aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/dvb/bt8xx.txt64
-rw-r--r--Documentation/dvb/cards.txt37
-rw-r--r--Documentation/dvb/contributors.txt17
-rw-r--r--Documentation/dvb/get_dvb_firmware19
-rw-r--r--Documentation/fb/fbcon.txt152
-rw-r--r--Documentation/feature-removal-schedule.txt29
-rw-r--r--Documentation/filesystems/ext2.txt2
-rw-r--r--Documentation/i2c/busses/i2c-viapro6
-rw-r--r--Documentation/i2c/writing-clients4
-rw-r--r--Documentation/md.txt119
-rw-r--r--Documentation/networking/README.ipw2100132
-rw-r--r--Documentation/networking/README.ipw2200196
-rw-r--r--Documentation/networking/dccp.txt56
-rw-r--r--Documentation/networking/ip-sysctl.txt5
-rw-r--r--Documentation/s390/Debugging390.txt2
-rw-r--r--Documentation/sched-arch.txt89
-rw-r--r--Documentation/video4linux/API.html2
-rw-r--r--Documentation/video4linux/CARDLIST.bttv279
-rw-r--r--Documentation/video4linux/CARDLIST.cx8869
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx10
-rw-r--r--Documentation/video4linux/CARDLIST.saa713429
-rw-r--r--Documentation/video4linux/CARDLIST.tuner4
-rw-r--r--Documentation/video4linux/README.cx888
-rw-r--r--Documentation/video4linux/README.saa71342
-rw-r--r--Documentation/video4linux/bttv/Cards18
-rw-r--r--Documentation/video4linux/bttv/README6
-rw-r--r--Documentation/video4linux/bttv/Sound-FAQ12
-rw-r--r--Documentation/video4linux/bttv/Tuners4
-rw-r--r--Documentation/video4linux/lifeview.txt58
-rw-r--r--MAINTAINERS20
-rw-r--r--Makefile4
-rw-r--r--arch/alpha/kernel/process.c10
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/configs/omap_h2_1610_defconfig97
-rw-r--r--arch/arm/kernel/process.c20
-rw-r--r--arch/arm/kernel/smp.c5
-rw-r--r--arch/arm/lib/bitops.h4
-rw-r--r--arch/arm/lib/csumpartial.S4
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig10
-rw-r--r--arch/arm/mach-ixp4xx/Makefile1
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-pci.c77
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-power.c92
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c134
-rw-r--r--arch/arm/mach-omap1/Kconfig32
-rw-r--r--arch/arm/mach-omap1/Makefile5
-rw-r--r--arch/arm/mach-omap1/board-generic.c33
-rw-r--r--arch/arm/mach-omap1/board-h2.c15
-rw-r--r--arch/arm/mach-omap1/board-h3.c19
-rw-r--r--arch/arm/mach-omap1/board-innovator.c42
-rw-r--r--arch/arm/mach-omap1/board-netstar.c15
-rw-r--r--arch/arm/mach-omap1/board-osk.c17
-rw-r--r--arch/arm/mach-omap1/board-palmte.c87
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c23
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c9
-rw-r--r--arch/arm/mach-omap1/clock.c792
-rw-r--r--arch/arm/mach-omap1/clock.h768
-rw-r--r--arch/arm/mach-omap1/devices.c221
-rw-r--r--arch/arm/mach-omap1/id.c9
-rw-r--r--arch/arm/mach-omap1/io.c13
-rw-r--r--arch/arm/mach-omap1/irq.c23
-rw-r--r--arch/arm/mach-omap1/leds-h2p2-debug.c44
-rw-r--r--arch/arm/mach-omap1/leds.c1
-rw-r--r--arch/arm/mach-omap1/mux.c289
-rw-r--r--arch/arm/mach-omap1/serial.c9
-rw-r--r--arch/arm/mach-omap1/time.c4
-rw-r--r--arch/arm/mach-omap2/Kconfig22
-rw-r--r--arch/arm/mach-omap2/Makefile13
-rw-r--r--arch/arm/mach-omap2/Makefile.boot3
-rw-r--r--arch/arm/mach-omap2/board-generic.c80
-rw-r--r--arch/arm/mach-omap2/board-h4.c197
-rw-r--r--arch/arm/mach-omap2/clock.c1129
-rw-r--r--arch/arm/mach-omap2/clock.h2103
-rw-r--r--arch/arm/mach-omap2/devices.c89
-rw-r--r--arch/arm/mach-omap2/id.c124
-rw-r--r--arch/arm/mach-omap2/io.c53
-rw-r--r--arch/arm/mach-omap2/irq.c149
-rw-r--r--arch/arm/mach-omap2/mux.c65
-rw-r--r--arch/arm/mach-omap2/prcm.h419
-rw-r--r--arch/arm/mach-omap2/serial.c180
-rw-r--r--arch/arm/mach-omap2/sram-fn.S333
-rw-r--r--arch/arm/mach-omap2/timer-gp.c126
-rw-r--r--arch/arm/mach-pxa/Kconfig7
-rw-r--r--arch/arm/mach-pxa/Makefile5
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c2
-rw-r--r--arch/arm/mach-pxa/sharpsl.h87
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c992
-rw-r--r--arch/arm/mach-pxa/ssp.c128
-rw-r--r--arch/arm/mach-realview/Makefile2
-rw-r--r--arch/arm/mach-realview/core.c2
-rw-r--r--arch/arm/mach-realview/hotplug.c138
-rw-r--r--arch/arm/mach-realview/localtimer.c130
-rw-r--r--arch/arm/mach-realview/platsmp.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c51
-rw-r--r--arch/arm/mach-s3c2410/mach-rx3715.c13
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c23
-rw-r--r--arch/arm/mm/Kconfig6
-rw-r--r--arch/arm/plat-omap/Makefile2
-rw-r--r--arch/arm/plat-omap/clock.c1315
-rw-r--r--arch/arm/plat-omap/clock.h120
-rw-r--r--arch/arm/plat-omap/common.c50
-rw-r--r--arch/arm/plat-omap/devices.c381
-rw-r--r--arch/arm/plat-omap/dma.c910
-rw-r--r--arch/arm/plat-omap/gpio.c40
-rw-r--r--arch/arm/plat-omap/mcbsp.c22
-rw-r--r--arch/arm/plat-omap/mux.c65
-rw-r--r--arch/arm/plat-omap/ocpi.c1
-rw-r--r--arch/arm/plat-omap/pm.c103
-rw-r--r--arch/arm/plat-omap/sleep.S139
-rw-r--r--arch/arm/plat-omap/sram.c143
-rw-r--r--arch/arm/plat-omap/sram.h21
-rw-r--r--arch/arm/plat-omap/usb.c11
-rw-r--r--arch/arm26/kernel/process.c12
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c1
-rw-r--r--arch/cris/arch-v10/kernel/fasttimer.c1
-rw-r--r--arch/cris/arch-v32/drivers/nandflash.c1
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c1
-rw-r--r--arch/cris/arch-v32/kernel/smp.c1
-rw-r--r--arch/cris/kernel/process.c2
-rw-r--r--arch/frv/kernel/process.c6
-rw-r--r--arch/h8300/kernel/process.c28
-rw-r--r--arch/i386/kernel/apm.c20
-rw-r--r--arch/i386/kernel/process.c68
-rw-r--r--arch/i386/kernel/setup.c2
-rw-r--r--arch/i386/kernel/smpboot.c1
-rw-r--r--arch/i386/pci/fixup.c3
-rw-r--r--arch/ia64/ia32/ia32_ioctl.c4
-rw-r--r--arch/ia64/kernel/efi.c2
-rw-r--r--arch/ia64/kernel/kprobes.c22
-rw-r--r--arch/ia64/kernel/mca.c120
-rw-r--r--arch/ia64/kernel/mca_drv.c20
-rw-r--r--arch/ia64/kernel/process.c40
-rw-r--r--arch/ia64/kernel/setup.c1
-rw-r--r--arch/ia64/kernel/signal.c11
-rw-r--r--arch/ia64/kernel/smpboot.c1
-rw-r--r--arch/ia64/kernel/traps.c44
-rw-r--r--arch/ia64/mm/discontig.c19
-rw-r--r--arch/ia64/mm/tlb.c85
-rw-r--r--arch/ia64/pci/pci.c106
-rw-r--r--arch/ia64/sn/kernel/io_init.c2
-rw-r--r--arch/ia64/sn/kernel/xpc.h2
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c102
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c8
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c4
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_reg.c2
-rw-r--r--arch/ia64/sn/pci/tioce_provider.c6
-rw-r--r--arch/m32r/kernel/process.c2
-rw-r--r--arch/m32r/kernel/smpboot.c1
-rw-r--r--arch/m68k/kernel/process.c2
-rw-r--r--arch/mips/au1000/common/setup.c11
-rw-r--r--arch/mips/configs/ddb5476_defconfig1
-rw-r--r--arch/mips/configs/jmr3927_defconfig1
-rw-r--r--arch/mips/configs/ocelot_3_defconfig1
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig1
-rw-r--r--arch/mips/configs/rbhma4500_defconfig1
-rw-r--r--arch/mips/kernel/ioctl32.c4
-rw-r--r--arch/mips/kernel/process.c2
-rw-r--r--arch/mips/kernel/smp.c4
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c1
-rw-r--r--arch/parisc/kernel/asm-offsets.c1
-rw-r--r--arch/parisc/kernel/process.c4
-rw-r--r--arch/parisc/kernel/smp.c1
-rw-r--r--arch/powerpc/Kconfig15
-rw-r--r--arch/powerpc/kernel/Makefile19
-rw-r--r--arch/powerpc/kernel/asm-offsets.c46
-rw-r--r--arch/powerpc/kernel/cpu_setup_power4.S (renamed from arch/ppc64/kernel/cpu_setup_power4.S)8
-rw-r--r--arch/powerpc/kernel/cputable.c19
-rw-r--r--arch/powerpc/kernel/firmware.c (renamed from arch/ppc64/kernel/firmware.c)2
-rw-r--r--arch/powerpc/kernel/fpu.S24
-rw-r--r--arch/powerpc/kernel/head_32.S1
-rw-r--r--arch/powerpc/kernel/head_64.S91
-rw-r--r--arch/powerpc/kernel/ioctl32.c (renamed from arch/ppc64/kernel/ioctl32.c)4
-rw-r--r--arch/powerpc/kernel/irq.c (renamed from arch/ppc64/kernel/irq.c)265
-rw-r--r--arch/powerpc/kernel/lparcfg.c (renamed from arch/ppc64/kernel/lparcfg.c)32
-rw-r--r--arch/powerpc/kernel/misc_32.S23
-rw-r--r--arch/powerpc/kernel/misc_64.S8
-rw-r--r--arch/powerpc/kernel/paca.c (renamed from arch/ppc64/kernel/pacaData.c)10
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c5
-rw-r--r--arch/powerpc/kernel/proc_ppc64.c (renamed from arch/ppc64/kernel/proc_ppc64.c)14
-rw-r--r--arch/powerpc/kernel/prom.c35
-rw-r--r--arch/powerpc/kernel/prom_init.c187
-rw-r--r--arch/powerpc/kernel/rtas-proc.c3
-rw-r--r--arch/powerpc/kernel/rtas.c5
-rw-r--r--arch/powerpc/kernel/rtas_pci.c (renamed from arch/ppc64/kernel/rtas_pci.c)47
-rw-r--r--arch/powerpc/kernel/setup-common.c41
-rw-r--r--arch/powerpc/kernel/setup.h6
-rw-r--r--arch/powerpc/kernel/setup_32.c18
-rw-r--r--arch/powerpc/kernel/setup_64.c123
-rw-r--r--arch/powerpc/kernel/signal_32.c13
-rw-r--r--arch/powerpc/kernel/smp.c10
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c1
-rw-r--r--arch/powerpc/kernel/sysfs.c (renamed from arch/ppc64/kernel/sysfs.c)3
-rw-r--r--arch/powerpc/kernel/time.c41
-rw-r--r--arch/powerpc/kernel/traps.c7
-rw-r--r--arch/powerpc/kernel/udbg.c (renamed from arch/ppc64/kernel/udbg.c)0
-rw-r--r--arch/powerpc/kernel/udbg_16550.c (renamed from arch/ppc64/kernel/udbg_16550.c)0
-rw-r--r--arch/powerpc/kernel/udbg_scc.c (renamed from arch/ppc64/kernel/udbg_scc.c)0
-rw-r--r--arch/powerpc/kernel/vdso.c746
-rw-r--r--arch/powerpc/kernel/vdso32/Makefile (renamed from arch/ppc64/kernel/vdso32/Makefile)6
-rw-r--r--arch/powerpc/kernel/vdso32/cacheflush.S (renamed from arch/ppc64/kernel/vdso32/cacheflush.S)0
-rw-r--r--arch/powerpc/kernel/vdso32/datapage.S (renamed from arch/ppc64/kernel/vdso32/datapage.S)16
-rw-r--r--arch/powerpc/kernel/vdso32/gettimeofday.S315
-rw-r--r--arch/powerpc/kernel/vdso32/note.S (renamed from arch/ppc64/kernel/vdso32/note.S)0
-rw-r--r--arch/powerpc/kernel/vdso32/sigtramp.S (renamed from arch/ppc64/kernel/vdso32/sigtramp.S)0
-rw-r--r--arch/powerpc/kernel/vdso32/vdso32.lds.S (renamed from arch/ppc64/kernel/vdso32/vdso32.lds.S)5
-rw-r--r--arch/powerpc/kernel/vdso32/vdso32_wrapper.S (renamed from arch/ppc64/kernel/vdso32/vdso32_wrapper.S)2
-rw-r--r--arch/powerpc/kernel/vdso64/Makefile (renamed from arch/ppc64/kernel/vdso64/Makefile)0
-rw-r--r--arch/powerpc/kernel/vdso64/cacheflush.S (renamed from arch/ppc64/kernel/vdso64/cacheflush.S)0
-rw-r--r--arch/powerpc/kernel/vdso64/datapage.S (renamed from arch/ppc64/kernel/vdso64/datapage.S)16
-rw-r--r--arch/powerpc/kernel/vdso64/gettimeofday.S242
-rw-r--r--arch/powerpc/kernel/vdso64/note.S (renamed from arch/ppc64/kernel/vdso64/note.S)0
-rw-r--r--arch/powerpc/kernel/vdso64/sigtramp.S (renamed from arch/ppc64/kernel/vdso64/sigtramp.S)0
-rw-r--r--arch/powerpc/kernel/vdso64/vdso64.lds.S (renamed from arch/ppc64/kernel/vdso64/vdso64.lds.S)5
-rw-r--r--arch/powerpc/kernel/vdso64/vdso64_wrapper.S (renamed from arch/ppc64/kernel/vdso64/vdso64_wrapper.S)2
-rw-r--r--arch/powerpc/kernel/vio.c27
-rw-r--r--arch/powerpc/lib/bitops.c2
-rw-r--r--arch/powerpc/mm/hash_utils_64.c38
-rw-r--r--arch/powerpc/mm/init_32.c3
-rw-r--r--arch/powerpc/mm/init_64.c20
-rw-r--r--arch/powerpc/mm/mem.c8
-rw-r--r--arch/powerpc/mm/numa.c369
-rw-r--r--arch/powerpc/mm/pgtable_64.c7
-rw-r--r--arch/powerpc/mm/stab.c21
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c4
-rw-r--r--arch/powerpc/platforms/chrp/setup.c4
-rw-r--r--arch/powerpc/platforms/iseries/irq.c24
-rw-r--r--arch/powerpc/platforms/iseries/misc.S1
-rw-r--r--arch/powerpc/platforms/iseries/setup.c41
-rw-r--r--arch/powerpc/platforms/maple/pci.c3
-rw-r--r--arch/powerpc/platforms/powermac/pci.c3
-rw-r--r--arch/powerpc/platforms/powermac/pic.c3
-rw-r--r--arch/powerpc/platforms/powermac/smp.c51
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c (renamed from arch/ppc64/kernel/eeh.c)659
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c155
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c3
-rw-r--r--arch/powerpc/platforms/pseries/pci.c3
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c2
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c9
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c (renamed from arch/ppc64/kernel/scanlog.c)0
-rw-r--r--arch/powerpc/platforms/pseries/setup.c28
-rw-r--r--arch/powerpc/platforms/pseries/smp.c5
-rw-r--r--arch/powerpc/platforms/pseries/xics.c7
-rw-r--r--arch/powerpc/sysdev/u3_iommu.c2
-rw-r--r--arch/powerpc/xmon/Makefile2
-rw-r--r--arch/powerpc/xmon/nonstdio.c134
-rw-r--r--arch/powerpc/xmon/nonstdio.h28
-rw-r--r--arch/powerpc/xmon/setjmp.S176
-rw-r--r--arch/powerpc/xmon/start_32.c235
-rw-r--r--arch/powerpc/xmon/start_64.c167
-rw-r--r--arch/powerpc/xmon/start_8xx.c255
-rw-r--r--arch/powerpc/xmon/subr_prf.c54
-rw-r--r--arch/powerpc/xmon/xmon.c75
-rw-r--r--arch/ppc/boot/include/of1275.h3
-rw-r--r--arch/ppc/boot/of1275/Makefile2
-rw-r--r--arch/ppc/boot/of1275/call_prom.c74
-rw-r--r--arch/ppc/boot/of1275/claim.c97
-rw-r--r--arch/ppc/boot/of1275/finddevice.c19
-rw-r--r--arch/ppc/boot/openfirmware/Makefile3
-rw-r--r--arch/ppc/configs/mpc834x_sys_defconfig431
-rw-r--r--arch/ppc/kernel/Makefile5
-rw-r--r--arch/ppc/kernel/asm-offsets.c28
-rw-r--r--arch/ppc/kernel/head_booke.h2
-rw-r--r--arch/ppc/kernel/idle.c25
-rw-r--r--arch/ppc/kernel/irq.c165
-rw-r--r--arch/ppc/kernel/misc.S4
-rw-r--r--arch/ppc/kernel/pci.c14
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c7
-rw-r--r--arch/ppc/kernel/setup.c1
-rw-r--r--arch/ppc/kernel/smp.c1
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c23
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.h1
-rw-r--r--arch/ppc/platforms/pmac_pic.c3
-rw-r--r--arch/ppc/platforms/prep_setup.c9
-rw-r--r--arch/ppc/syslib/Makefile2
-rw-r--r--arch/ppc/syslib/cpm2_pic.c2
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c12
-rw-r--r--arch/ppc/syslib/mpc83xx_sys.c24
-rw-r--r--arch/ppc/syslib/prom.c1
-rw-r--r--arch/ppc/syslib/prom_init.c1
-rw-r--r--arch/ppc64/Kconfig15
-rw-r--r--arch/ppc64/boot/addRamDisk.c207
-rw-r--r--arch/ppc64/kernel/Makefile22
-rw-r--r--arch/ppc64/kernel/asm-offsets.c1
-rw-r--r--arch/ppc64/kernel/head.S84
-rw-r--r--arch/ppc64/kernel/idle.c16
-rw-r--r--arch/ppc64/kernel/misc.S11
-rw-r--r--arch/ppc64/kernel/nvram.c5
-rw-r--r--arch/ppc64/kernel/pci.c10
-rw-r--r--arch/ppc64/kernel/pci_dn.c21
-rw-r--r--arch/ppc64/kernel/prom.c9
-rw-r--r--arch/ppc64/kernel/prom_init.c3
-rw-r--r--arch/ppc64/kernel/vdso.c5
-rw-r--r--arch/ppc64/kernel/vdso32/gettimeofday.S140
-rw-r--r--arch/ppc64/kernel/vdso64/gettimeofday.S91
-rw-r--r--arch/s390/kernel/debug.c12
-rw-r--r--arch/s390/kernel/process.c24
-rw-r--r--arch/s390/kernel/smp.c1
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/kernel/process.c14
-rw-r--r--arch/sh/kernel/smp.c5
-rw-r--r--arch/sh64/kernel/process.c16
-rw-r--r--arch/sparc/kernel/cpu.c4
-rw-r--r--arch/sparc/kernel/pcic.c2
-rw-r--r--arch/sparc/kernel/process.c35
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--arch/sparc64/kernel/cpu.c4
-rw-r--r--arch/sparc64/kernel/ioctl32.c6
-rw-r--r--arch/sparc64/kernel/process.c24
-rw-r--r--arch/sparc64/kernel/sbus.c2
-rw-r--r--arch/sparc64/kernel/smp.c16
-rw-r--r--arch/sparc64/mm/fault.c2
-rw-r--r--arch/um/drivers/net_kern.c38
-rw-r--r--arch/v850/kernel/process.c16
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c6
-rw-r--r--arch/x86_64/kernel/process.c69
-rw-r--r--arch/x86_64/kernel/smpboot.c1
-rw-r--r--arch/xtensa/kernel/process.c3
-rw-r--r--arch/xtensa/platform-iss/network.c33
-rw-r--r--drivers/acpi/glue.c1
-rw-r--r--drivers/acpi/processor_idle.c37
-rw-r--r--drivers/atm/horizon.c4
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/block/floppy.c9
-rw-r--r--drivers/block/pktcdvd.c3
-rw-r--r--drivers/char/agp/ali-agp.c1
-rw-r--r--drivers/char/agp/amd-k7-agp.c1
-rw-r--r--drivers/char/agp/amd64-agp.c1
-rw-r--r--drivers/char/agp/ati-agp.c1
-rw-r--r--drivers/char/agp/backend.c9
-rw-r--r--drivers/char/agp/efficeon-agp.c1
-rw-r--r--drivers/char/agp/generic.c9
-rw-r--r--drivers/char/agp/i460-agp.c18
-rw-r--r--drivers/char/agp/intel-agp.c6
-rw-r--r--drivers/char/agp/nvidia-agp.c1
-rw-r--r--drivers/char/agp/sis-agp.c1
-rw-r--r--drivers/char/agp/sworks-agp.c1
-rw-r--r--drivers/char/agp/uninorth-agp.c1
-rw-r--r--drivers/char/agp/via-agp.c1
-rw-r--r--drivers/char/drm/ati_pcigart.c4
-rw-r--r--drivers/char/epca.c1
-rw-r--r--drivers/char/ip2.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c6
-rw-r--r--drivers/char/mwave/tp3780i.c1
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/synclink.c1
-rw-r--r--drivers/char/synclinkmp.c1
-rw-r--r--drivers/char/sysrq.c4
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/viocons.c1
-rw-r--r--drivers/char/viotape.c1
-rw-r--r--drivers/char/watchdog/pcwd_pci.c1
-rw-r--r--drivers/char/watchdog/wdt_pci.c1
-rw-r--r--drivers/cpufreq/cpufreq.c24
-rw-r--r--drivers/firmware/dell_rbu.c1
-rw-r--r--drivers/hwmon/hdaps.c41
-rw-r--r--drivers/hwmon/w83627hf.c16
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c1
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c1
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c1
-rw-r--r--drivers/i2c/busses/i2c-amd756.c1
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c1
-rw-r--r--drivers/i2c/busses/i2c-hydra.c1
-rw-r--r--drivers/i2c/busses/i2c-i801.c1
-rw-r--r--drivers/i2c/busses/i2c-i810.c1
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c1
-rw-r--r--drivers/i2c/busses/i2c-piix4.c1
-rw-r--r--drivers/i2c/busses/i2c-prosavage.c1
-rw-r--r--drivers/i2c/busses/i2c-savage4.c1
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c1
-rw-r--r--drivers/i2c/busses/i2c-sis630.c1
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c1
-rw-r--r--drivers/i2c/busses/i2c-via.c1
-rw-r--r--drivers/i2c/busses/i2c-viapro.c28
-rw-r--r--drivers/i2c/busses/i2c-voodoo3.c1
-rw-r--r--drivers/i2c/chips/ds1337.c4
-rw-r--r--drivers/ide/Kconfig9
-rw-r--r--drivers/ide/ide-floppy.c6
-rw-r--r--drivers/ide/ide-iops.c6
-rw-r--r--drivers/ide/ide-taskfile.c2
-rw-r--r--drivers/ide/ide.c1
-rw-r--r--drivers/ide/legacy/ide-cs.c7
-rw-r--r--drivers/ide/pci/Makefile1
-rw-r--r--drivers/ide/pci/amd74xx.c3
-rw-r--r--drivers/ide/pci/cs5535.c305
-rw-r--r--drivers/ide/pci/cy82c693.c2
-rw-r--r--drivers/ide/pci/siimage.c9
-rw-r--r--drivers/ide/setup-pci.c12
-rw-r--r--drivers/infiniband/core/user_mad.c129
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c12
-rw-r--r--drivers/infiniband/core/verbs.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c16
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c113
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c22
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h15
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c177
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c72
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c26
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c7
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/isdn/divert/divert_init.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c1
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c1
-rw-r--r--drivers/isdn/hisax/st5481_init.c1
-rw-r--r--drivers/isdn/hysdn/hycapi.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c1
-rw-r--r--drivers/isdn/icn/icn.h1
-rw-r--r--drivers/isdn/isdnloop/isdnloop.h1
-rw-r--r--drivers/isdn/sc/includes.h1
-rw-r--r--drivers/md/bitmap.c34
-rw-r--r--drivers/md/md.c636
-rw-r--r--drivers/md/multipath.c31
-rw-r--r--drivers/md/raid1.c216
-rw-r--r--drivers/md/raid10.c63
-rw-r--r--drivers/md/raid5.c261
-rw-r--r--drivers/md/raid6main.c40
-rw-r--r--drivers/media/common/ir-common.c4
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c54
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c1
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig4
-rw-r--r--drivers/media/dvb/bt8xx/dst.c136
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c123
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h5
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c114
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h1
-rw-r--r--drivers/media/dvb/dvb-core/demux.h5
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c118
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c59
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h5
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c4
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c54
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c26
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h4
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c1205
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h61
-rw-r--r--drivers/media/dvb/frontends/or51132.c7
-rw-r--r--drivers/media/dvb/frontends/or51211.c8
-rw-r--r--drivers/media/dvb/frontends/stv0299.c100
-rw-r--r--drivers/media/dvb/frontends/stv0299.h3
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c21
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c6
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c3
-rw-r--r--drivers/media/dvb/ttpci/budget.c120
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c5
-rw-r--r--drivers/media/video/Kconfig63
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/arv.c1
-rw-r--r--drivers/media/video/bt832.c89
-rw-r--r--drivers/media/video/bt832.h4
-rw-r--r--drivers/media/video/bttv-cards.c5307
-rw-r--r--drivers/media/video/bttv-driver.c379
-rw-r--r--drivers/media/video/bttv-gpio.c2
-rw-r--r--drivers/media/video/bttv-i2c.c61
-rw-r--r--drivers/media/video/bttv-if.c4
-rw-r--r--drivers/media/video/bttv-risc.c110
-rw-r--r--drivers/media/video/bttv.h282
-rw-r--r--drivers/media/video/bttvp.h14
-rw-r--r--drivers/media/video/cs53l32a.c240
-rw-r--r--drivers/media/video/cx88/Kconfig91
-rw-r--r--drivers/media/video/cx88/Makefile6
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c677
-rw-r--r--drivers/media/video/cx88/cx88-cards.c474
-rw-r--r--drivers/media/video/cx88/cx88-core.c55
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c59
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c22
-rw-r--r--drivers/media/video/cx88/cx88-input.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c25
-rw-r--r--drivers/media/video/cx88/cx88-reg.h12
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1184
-rw-r--r--drivers/media/video/cx88/cx88-video.c38
-rw-r--r--drivers/media/video/cx88/cx88.h55
-rw-r--r--drivers/media/video/em28xx/Kconfig12
-rw-r--r--drivers/media/video/em28xx/Makefile6
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c292
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c817
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c586
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c184
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c1933
-rw-r--r--drivers/media/video/em28xx/em28xx.h513
-rw-r--r--drivers/media/video/ir-kbd-gpio.c99
-rw-r--r--drivers/media/video/ir-kbd-i2c.c166
-rw-r--r--drivers/media/video/msp3400.c962
-rw-r--r--drivers/media/video/mt20xx.c206
-rw-r--r--drivers/media/video/saa6588.c11
-rw-r--r--drivers/media/video/saa711x.c593
-rw-r--r--drivers/media/video/saa7134/Kconfig68
-rw-r--r--drivers/media/video/saa7134/Makefile9
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c187
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c1047
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c587
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c120
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c370
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c28
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c403
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c375
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h27
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c29
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c23
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c185
-rw-r--r--drivers/media/video/saa7134/saa7134.h62
-rw-r--r--drivers/media/video/tda7432.c17
-rw-r--r--drivers/media/video/tda8290.c681
-rw-r--r--drivers/media/video/tda9875.c57
-rw-r--r--drivers/media/video/tda9887.c163
-rw-r--r--drivers/media/video/tea5767.c8
-rw-r--r--drivers/media/video/tuner-core.c74
-rw-r--r--drivers/media/video/tuner-simple.c143
-rw-r--r--drivers/media/video/tvaudio.c23
-rw-r--r--drivers/media/video/tveeprom.c458
-rw-r--r--drivers/media/video/tvmixer.c54
-rw-r--r--drivers/media/video/tvp5150.c829
-rw-r--r--drivers/media/video/tvp5150_reg.h173
-rw-r--r--drivers/media/video/v4l1-compat.c6
-rw-r--r--drivers/media/video/video-buf.c18
-rw-r--r--drivers/media/video/wm8775.c254
-rw-r--r--drivers/media/video/zr36016.c1
-rw-r--r--drivers/media/video/zr36050.c1
-rw-r--r--drivers/media/video/zr36060.c1
-rw-r--r--drivers/message/fusion/mptbase.c7
-rw-r--r--drivers/message/fusion/mptbase.h3
-rw-r--r--drivers/message/fusion/mptctl.c1
-rw-r--r--drivers/message/fusion/mptctl.h1
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c1
-rw-r--r--drivers/misc/ibmasm/ibmasm.h1
-rw-r--r--drivers/mmc/wbsd.c7
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c1
-rw-r--r--drivers/mtd/devices/pmc551.c1
-rw-r--r--drivers/mtd/maps/ebony.c1
-rw-r--r--drivers/mtd/maps/ocotea.c1
-rw-r--r--drivers/mtd/maps/walnut.c1
-rw-r--r--drivers/mtd/nand/au1550nd.c1
-rw-r--r--drivers/mtd/nand/autcpu12.c1
-rw-r--r--drivers/mtd/onenand/onenand_base.c2
-rw-r--r--drivers/mtd/rfd_ftl.c1
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/b44.c178
-rw-r--r--drivers/net/b44.h75
-rw-r--r--drivers/net/bnx2.c16
-rw-r--r--drivers/net/bonding/bond_main.c32
-rw-r--r--drivers/net/bonding/bonding.h7
-rw-r--r--drivers/net/cassini.c1
-rw-r--r--drivers/net/cris/eth_v10.c149
-rw-r--r--drivers/net/dgrs.c16
-rw-r--r--drivers/net/dm9000.c1
-rw-r--r--drivers/net/e100.c6
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c1
-rw-r--r--drivers/net/fs_enet/fs_enet.h1
-rw-r--r--drivers/net/fs_enet/mac-fcc.c1
-rw-r--r--drivers/net/fs_enet/mac-fec.c1
-rw-r--r--drivers/net/fs_enet/mac-scc.c1
-rw-r--r--drivers/net/gianfar.c1
-rw-r--r--drivers/net/gianfar.h1
-rw-r--r--drivers/net/gianfar_ethtool.c1
-rw-r--r--drivers/net/gianfar_mii.c1
-rw-r--r--drivers/net/hp100.c1
-rw-r--r--drivers/net/ibmveth.c1
-rw-r--r--drivers/net/iseries_veth.c1
-rw-r--r--drivers/net/mac8390.c1
-rw-r--r--drivers/net/mv643xx_eth.h1
-rw-r--r--drivers/net/ns83820.c13
-rw-r--r--drivers/net/s2io.c44
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h3
-rw-r--r--drivers/net/sk_mca.c1
-rw-r--r--drivers/net/sk_mca.h2
-rw-r--r--drivers/net/skge.c267
-rw-r--r--drivers/net/skge.h2
-rw-r--r--drivers/net/spider_net.c1
-rw-r--r--drivers/net/starfire.c1
-rw-r--r--drivers/net/via-velocity.c1
-rw-r--r--drivers/net/wireless/airo.c36
-rw-r--r--drivers/net/wireless/airo_cs.c6
-rw-r--r--drivers/net/wireless/atmel.c2
-rw-r--r--drivers/net/wireless/atmel_cs.c6
-rw-r--r--drivers/net/wireless/hostap/hostap.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c1
-rw-r--r--drivers/net/wireless/ipw2100.c2858
-rw-r--r--drivers/net/wireless/ipw2100.h170
-rw-r--r--drivers/net/wireless/ipw2200.c6610
-rw-r--r--drivers/net/wireless/ipw2200.h575
-rw-r--r--drivers/net/wireless/orinoco.h1
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c13
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h1
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h1
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c11
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c1
-rw-r--r--drivers/net/wireless/wavelan_cs.c3
-rw-r--r--drivers/net/wireless/wl3501_cs.c3
-rw-r--r--drivers/pci/access.c2
-rw-r--r--drivers/pci/hotplug/pciehp.h135
-rw-r--r--drivers/pci/hotplug/pciehp_core.c108
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c1979
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c113
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c840
-rw-r--r--drivers/pci/hotplug/pciehprm.h52
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c1727
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c464
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.h56
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c81
-rw-r--r--drivers/pci/hotplug/rpaphp.h2
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c76
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c2
-rw-r--r--drivers/pci/msi.c20
-rw-r--r--drivers/pci/pci-acpi.c11
-rw-r--r--drivers/pci/pci-driver.c11
-rw-r--r--drivers/pci/pci.c46
-rw-r--r--drivers/pci/quirks.c19
-rw-r--r--drivers/pcmcia/Kconfig2
-rw-r--r--drivers/pcmcia/Makefile6
-rw-r--r--drivers/pcmcia/au1000_db1x00.c1
-rw-r--r--drivers/pcmcia/au1000_generic.h2
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c2
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c2
-rw-r--r--drivers/pcmcia/i82365.c1
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c24
-rw-r--r--drivers/s390/char/keyboard.h4
-rw-r--r--drivers/s390/cio/qdio.h8
-rw-r--r--drivers/s390/crypto/z90main.c1
-rw-r--r--drivers/s390/net/claw.c1
-rw-r--r--drivers/s390/net/fsm.h6
-rw-r--r--drivers/s390/s390mach.h2
-rw-r--r--drivers/sbus/char/cpwatchdog.c2
-rw-r--r--drivers/sbus/char/display7seg.c4
-rw-r--r--drivers/sbus/char/rtc.c22
-rw-r--r--drivers/scsi/3w-xxxx.h1
-rw-r--r--drivers/scsi/a2091.c1
-rw-r--r--drivers/scsi/ahci.c4
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1
-rw-r--r--drivers/scsi/amiga7xx.c1
-rw-r--r--drivers/scsi/ata_piix.c3
-rw-r--r--drivers/scsi/bvme6000.c1
-rw-r--r--drivers/scsi/gvp11.c1
-rw-r--r--drivers/scsi/ibmmca.c6
-rw-r--r--drivers/scsi/ide-scsi.c5
-rw-r--r--drivers/scsi/ips.h1
-rw-r--r--drivers/scsi/libata-core.c11
-rw-r--r--drivers/scsi/libata-scsi.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c1
-rw-r--r--drivers/scsi/megaraid/mega_common.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c1
-rw-r--r--drivers/scsi/mvme147.c1
-rw-r--r--drivers/scsi/mvme16x.c1
-rw-r--r--drivers/scsi/nsp32.h1
-rw-r--r--drivers/scsi/pci2000.h3
-rw-r--r--drivers/scsi/pdc_adma.c3
-rw-r--r--drivers/scsi/sata_mv.c4
-rw-r--r--drivers/scsi/sata_nv.c3
-rw-r--r--drivers/scsi/sata_promise.c4
-rw-r--r--drivers/scsi/sata_qstor.c3
-rw-r--r--drivers/scsi/sata_sil.c3
-rw-r--r--drivers/scsi/sata_sil24.c4
-rw-r--r--drivers/scsi/sata_sis.c3
-rw-r--r--drivers/scsi/sata_svw.c3
-rw-r--r--drivers/scsi/sata_sx4.c4
-rw-r--r--drivers/scsi/sata_uli.c3
-rw-r--r--drivers/scsi/sata_via.c3
-rw-r--r--drivers/scsi/sata_vsc.c3
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/sg.c4
-rw-r--r--drivers/scsi/sgiwd93.c1
-rw-r--r--drivers/scsi/wd33c93.c1
-rw-r--r--drivers/telephony/ixj.h1
-rw-r--r--drivers/usb/gadget/dummy_hcd.c1
-rw-r--r--drivers/usb/gadget/goku_udc.c1
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.h1
-rw-r--r--drivers/usb/gadget/net2280.c1
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c1
-rw-r--r--drivers/usb/gadget/rndis.c1
-rw-r--r--drivers/usb/host/ehci-pci.c1
-rw-r--r--drivers/usb/host/hc_crisv10.c1
-rw-r--r--drivers/usb/host/ohci-pci.c1
-rw-r--r--drivers/usb/host/uhci-hcd.c1
-rw-r--r--drivers/usb/media/pwc/pwc-if.c1
-rw-r--r--drivers/usb/media/pwc/pwc.h2
-rw-r--r--drivers/usb/media/w9968cf.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.h1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c1
-rw-r--r--drivers/video/Kconfig32
-rw-r--r--drivers/video/backlight/backlight.c1
-rw-r--r--drivers/video/backlight/corgi_bl.c6
-rw-r--r--drivers/video/backlight/lcd.c1
-rw-r--r--drivers/video/cfbimgblt.c4
-rw-r--r--drivers/video/console/Kconfig10
-rw-r--r--drivers/video/console/Makefile4
-rw-r--r--drivers/video/console/bitblit.c46
-rw-r--r--drivers/video/console/fbcon.c375
-rw-r--r--drivers/video/console/fbcon.h62
-rw-r--r--drivers/video/console/fbcon_ccw.c428
-rw-r--r--drivers/video/console/fbcon_cw.c412
-rw-r--r--drivers/video/console/fbcon_rotate.c117
-rw-r--r--drivers/video/console/fbcon_rotate.h105
-rw-r--r--drivers/video/console/fbcon_ud.c454
-rw-r--r--drivers/video/console/tileblit.c13
-rw-r--r--drivers/video/fbmem.c299
-rw-r--r--drivers/video/fbsysfs.c67
-rw-r--r--drivers/video/intelfb/intelfbdrv.c1
-rw-r--r--drivers/video/intelfb/intelfbhw.c1
-rw-r--r--drivers/video/modedb.c4
-rw-r--r--drivers/video/savage/savagefb_driver.c10
-rw-r--r--drivers/video/vga16fb.c169
-rw-r--r--drivers/video/vgastate.c5
-rw-r--r--fs/9p/vfs_file.c1
-rw-r--r--fs/Kconfig53
-rw-r--r--fs/adfs/adfs.h1
-rw-r--r--fs/binfmt_misc.c2
-rw-r--r--fs/cifs/CHANGES2
-rw-r--r--fs/cifs/cifs_unicode.c5
-rw-r--r--fs/cifs/cifsfs.c11
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c2
-rw-r--r--fs/cifs/cn_cifs.h37
-rw-r--r--fs/cifs/connect.c1
-rw-r--r--fs/cifs/inode.c2
-rw-r--r--fs/compat_ioctl.c153
-rw-r--r--fs/exec.c6
-rw-r--r--fs/ext2/CHANGES157
-rw-r--r--fs/ext2/balloc.c73
-rw-r--r--fs/ext2/ialloc.c40
-rw-r--r--fs/ext2/super.c16
-rw-r--r--fs/ext3/balloc.c73
-rw-r--r--fs/ext3/ialloc.c41
-rw-r--r--fs/ext3/super.c17
-rw-r--r--fs/fat/inode.c11
-rw-r--r--fs/hfs/hfs_fs.h1
-rw-r--r--fs/hfs/inode.c1
-rw-r--r--fs/hfsplus/bnode.c1
-rw-r--r--fs/hfsplus/dir.c1
-rw-r--r--fs/hfsplus/extents.c1
-rw-r--r--fs/hfsplus/hfsplus_fs.h1
-rw-r--r--fs/hfsplus/inode.c1
-rw-r--r--fs/hfsplus/super.c1
-rw-r--r--fs/hfsplus/wrapper.c1
-rw-r--r--fs/hostfs/hostfs_kern.c1
-rw-r--r--fs/hpfs/file.c7
-rw-r--r--fs/hugetlbfs/inode.c2
-rw-r--r--fs/inotify.c2
-rw-r--r--fs/jfs/namei.c3
-rw-r--r--fs/namei.c66
-rw-r--r--fs/namespace.c2
-rw-r--r--fs/ncpfs/ioctl.c34
-rw-r--r--fs/open.c14
-rw-r--r--fs/reiserfs/file.c4
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/xfs.h7
-rw-r--r--fs/xfs/xfs_dmapi.h1
-rw-r--r--include/asm-alpha/ide.h4
-rw-r--r--include/asm-arm/arch-ixp4xx/hardware.h1
-rw-r--r--include/asm-arm/arch-ixp4xx/irqs.h7
-rw-r--r--include/asm-arm/arch-ixp4xx/nslu2.h96
-rw-r--r--include/asm-arm/arch-omap/board-h4.h6
-rw-r--r--include/asm-arm/arch-omap/board-innovator.h4
-rw-r--r--include/asm-arm/arch-omap/clock.h91
-rw-r--r--include/asm-arm/arch-omap/common.h2
-rw-r--r--include/asm-arm/arch-omap/cpu.h82
-rw-r--r--include/asm-arm/arch-omap/dma.h261
-rw-r--r--include/asm-arm/arch-omap/entry-macro.S14
-rw-r--r--include/asm-arm/arch-omap/fpga.h4
-rw-r--r--include/asm-arm/arch-omap/gpio.h2
-rw-r--r--include/asm-arm/arch-omap/hardware.h8
-rw-r--r--include/asm-arm/arch-omap/io.h32
-rw-r--r--include/asm-arm/arch-omap/irqs.h13
-rw-r--r--include/asm-arm/arch-omap/memory.h4
-rw-r--r--include/asm-arm/arch-omap/menelaus.h22
-rw-r--r--include/asm-arm/arch-omap/mux.h327
-rw-r--r--include/asm-arm/arch-omap/omap1510.h6
-rw-r--r--include/asm-arm/arch-omap/omap24xx.h17
-rw-r--r--include/asm-arm/arch-omap/omapfb.h281
-rw-r--r--include/asm-arm/arch-omap/pm.h40
-rw-r--r--include/asm-arm/arch-omap/prcm.h429
-rw-r--r--include/asm-arm/arch-omap/sram.h38
-rw-r--r--include/asm-arm/arch-omap/system.h35
-rw-r--r--include/asm-arm/arch-omap/timex.h8
-rw-r--r--include/asm-arm/arch-omap/uncompress.h6
-rw-r--r--include/asm-arm/arch-pxa/sharpsl.h8
-rw-r--r--include/asm-arm/arch-pxa/ssp.h8
-rw-r--r--include/asm-arm/arch-realview/entry-macro.S11
-rw-r--r--include/asm-arm/arch-realview/irqs.h3
-rw-r--r--include/asm-arm/arch-realview/platform.h5
-rw-r--r--include/asm-arm/assembler.h9
-rw-r--r--include/asm-arm/mach/flash.h3
-rw-r--r--include/asm-i386/ide.h6
-rw-r--r--include/asm-i386/msi.h9
-rw-r--r--include/asm-i386/smp.h6
-rw-r--r--include/asm-ia64/kdebug.h30
-rw-r--r--include/asm-ia64/mmu_context.h81
-rw-r--r--include/asm-ia64/msi.h3
-rw-r--r--include/asm-ia64/tlbflush.h1
-rw-r--r--include/asm-powerpc/abs_addr.h (renamed from include/asm-ppc64/abs_addr.h)6
-rw-r--r--include/asm-powerpc/asm-compat.h55
-rw-r--r--include/asm-powerpc/atomic.h188
-rw-r--r--include/asm-powerpc/auxvec.h2
-rw-r--r--include/asm-powerpc/bitops.h41
-rw-r--r--include/asm-powerpc/bug.h19
-rw-r--r--include/asm-powerpc/cache.h40
-rw-r--r--include/asm-powerpc/cacheflush.h (renamed from include/asm-ppc64/cacheflush.h)52
-rw-r--r--include/asm-powerpc/compat.h (renamed from include/asm-ppc64/compat.h)8
-rw-r--r--include/asm-powerpc/cputable.h6
-rw-r--r--include/asm-powerpc/current.h27
-rw-r--r--include/asm-powerpc/eeh_event.h52
-rw-r--r--include/asm-powerpc/elf.h10
-rw-r--r--include/asm-powerpc/firmware.h6
-rw-r--r--include/asm-powerpc/futex.h5
-rw-r--r--include/asm-powerpc/hvcall.h (renamed from include/asm-ppc64/hvcall.h)14
-rw-r--r--include/asm-powerpc/hw_irq.h1
-rw-r--r--include/asm-powerpc/irq.h6
-rw-r--r--include/asm-powerpc/lppaca.h (renamed from include/asm-ppc64/lppaca.h)9
-rw-r--r--include/asm-powerpc/paca.h (renamed from include/asm-ppc64/paca.h)15
-rw-r--r--include/asm-powerpc/pmc.h1
-rw-r--r--include/asm-powerpc/ppc-pci.h52
-rw-r--r--include/asm-powerpc/ppc_asm.h39
-rw-r--r--include/asm-powerpc/processor.h72
-rw-r--r--include/asm-powerpc/reg.h7
-rw-r--r--include/asm-powerpc/reg_8xx.h (renamed from include/asm-ppc/cache.h)50
-rw-r--r--include/asm-powerpc/signal.h (renamed from include/asm-ppc/signal.h)41
-rw-r--r--include/asm-powerpc/sparsemem.h8
-rw-r--r--include/asm-powerpc/system.h2
-rw-r--r--include/asm-powerpc/tce.h (renamed from include/asm-ppc64/tce.h)6
-rw-r--r--include/asm-powerpc/topology.h12
-rw-r--r--include/asm-powerpc/uaccess.h40
-rw-r--r--include/asm-powerpc/udbg.h (renamed from include/asm-ppc64/udbg.h)14
-rw-r--r--include/asm-powerpc/vdso.h (renamed from include/asm-ppc64/vdso.h)0
-rw-r--r--include/asm-powerpc/vdso_datapage.h108
-rw-r--r--include/asm-powerpc/xmon.h1
-rw-r--r--include/asm-ppc/cacheflush.h49
-rw-r--r--include/asm-ppc/current.h11
-rw-r--r--include/asm-ppc/mpc83xx.h1
-rw-r--r--include/asm-ppc/page.h8
-rw-r--r--include/asm-ppc64/cache.h36
-rw-r--r--include/asm-ppc64/current.h16
-rw-r--r--include/asm-ppc64/eeh.h46
-rw-r--r--include/asm-ppc64/mmu.h6
-rw-r--r--include/asm-ppc64/mmzone.h65
-rw-r--r--include/asm-ppc64/page.h7
-rw-r--r--include/asm-ppc64/pci-bridge.h1
-rw-r--r--include/asm-ppc64/pgalloc.h4
-rw-r--r--include/asm-ppc64/prom.h2
-rw-r--r--include/asm-ppc64/signal.h132
-rw-r--r--include/asm-ppc64/system.h2
-rw-r--r--include/asm-ppc64/systemcfg.h64
-rw-r--r--include/asm-s390/debug.h16
-rw-r--r--include/asm-s390/ebcdic.h2
-rw-r--r--include/asm-s390/io.h8
-rw-r--r--include/asm-s390/lowcore.h2
-rw-r--r--include/asm-s390/mmu_context.h2
-rw-r--r--include/asm-s390/pgtable.h68
-rw-r--r--include/asm-s390/sigp.h6
-rw-r--r--include/asm-s390/smp.h2
-rw-r--r--include/asm-sh/ide.h4
-rw-r--r--include/asm-sh64/ide.h4
-rw-r--r--include/asm-x86_64/msi.h4
-rw-r--r--include/asm-x86_64/smp.h6
-rw-r--r--include/linux/compat_ioctl.h15
-rw-r--r--include/linux/connector.h2
-rw-r--r--include/linux/cpu.h5
-rw-r--r--include/linux/eeprom.h136
-rw-r--r--include/linux/fb.h23
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/fs_enet_pd.h1
-rw-r--r--include/linux/genetlink.h51
-rw-r--r--include/linux/i2c-id.h18
-rw-r--r--include/linux/ide.h8
-rw-r--r--include/linux/if_ether.h4
-rw-r--r--include/linux/if_wanpipe_common.h2
-rw-r--r--include/linux/istallion.h2
-rw-r--r--include/linux/libata.h6
-rw-r--r--include/linux/mtd/cfi.h1
-rw-r--r--include/linux/mtd/mtd.h1
-rw-r--r--include/linux/namei.h2
-rw-r--r--include/linux/netdevice.h7
-rw-r--r--include/linux/netfilter/nf_conntrack_common.h159
-rw-r--r--include/linux/netfilter/nf_conntrack_ftp.h44
-rw-r--r--include/linux/netfilter/nf_conntrack_sctp.h27
-rw-r--r--include/linux/netfilter/nf_conntrack_tcp.h56
-rw-r--r--include/linux/netfilter/nf_conntrack_tuple_common.h13
-rw-r--r--include/linux/netfilter/nfnetlink.h2
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h152
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_ftp.h39
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_icmp.h9
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_sctp.h21
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tcp.h47
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tuple.h10
-rw-r--r--include/linux/netfilter_ipv6.h1
-rw-r--r--include/linux/netlink.h24
-rw-r--r--include/linux/pci-acpi.h5
-rw-r--r--include/linux/pci.h13
-rw-r--r--include/linux/pci_ids.h3
-rw-r--r--include/linux/phonedev.h1
-rw-r--r--include/linux/raid/bitmap.h11
-rw-r--r--include/linux/raid/md.h5
-rw-r--r--include/linux/raid/md_k.h40
-rw-r--r--include/linux/raid/raid1.h4
-rw-r--r--include/linux/raid/raid5.h2
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/skbuff.h46
-rw-r--r--include/linux/stallion.h2
-rw-r--r--include/linux/sysctl.h38
-rw-r--r--include/linux/tcp.h16
-rw-r--r--include/linux/videodev.h82
-rw-r--r--include/linux/videodev2.h207
-rw-r--r--include/media/audiochip.h17
-rw-r--r--include/media/id.h35
-rw-r--r--include/media/ir-common.h6
-rw-r--r--include/media/ir-kbd-i2c.h22
-rw-r--r--include/media/saa7146_vv.h2
-rw-r--r--include/media/tuner.h22
-rw-r--r--include/media/video-buf.h4
-rw-r--r--include/net/genetlink.h154
-rw-r--r--include/net/ieee80211.h2
-rw-r--r--include/net/ieee80211_crypt.h1
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_icmp.h11
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_ipv4.h43
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_icmpv6.h27
-rw-r--r--include/net/netfilter/nf_conntrack.h354
-rw-r--r--include/net/netfilter/nf_conntrack_compat.h108
-rw-r--r--include/net/netfilter/nf_conntrack_core.h76
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h51
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h93
-rw-r--r--include/net/netfilter/nf_conntrack_protocol.h105
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h190
-rw-r--r--include/net/netlink.h883
-rw-r--r--include/net/sock.h6
-rw-r--r--include/net/tcp.h74
-rw-r--r--include/rdma/ib_user_verbs.h9
-rw-r--r--include/rdma/ib_verbs.h2
-rw-r--r--init/main.c4
-rw-r--r--kernel/cpu.c33
-rw-r--r--kernel/power/main.c2
-rw-r--r--kernel/power/power.h6
-rw-r--r--kernel/power/snapshot.c83
-rw-r--r--kernel/power/swsusp.c210
-rw-r--r--kernel/ptrace.c2
-rw-r--r--kernel/sched.c160
-rw-r--r--kernel/signal.c2
-rw-r--r--kernel/softlockup.c3
-rw-r--r--kernel/sys.c2
-rw-r--r--mm/page_alloc.c2
-rw-r--r--net/core/datagram.c21
-rw-r--r--net/core/dev.c12
-rw-r--r--net/core/netpoll.c18
-rw-r--r--net/core/rtnetlink.c83
-rw-r--r--net/core/skbuff.c15
-rw-r--r--net/ieee80211/ieee80211_crypt.c152
-rw-r--r--net/ieee80211/ieee80211_rx.c2
-rw-r--r--net/ieee80211/ieee80211_wx.c14
-rw-r--r--net/ipv4/icmp.c6
-rw-r--r--net/ipv4/igmp.c19
-rw-r--r--net/ipv4/inet_diag.c9
-rw-r--r--net/ipv4/ip_gre.c15
-rw-r--r--net/ipv4/netfilter/Kconfig41
-rw-r--r--net/ipv4/netfilter/Makefile6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c85
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c26
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c11
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c28
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c12
-rw-r--r--net/ipv4/netfilter/ipt_CONNMARK.c22
-rw-r--r--net/ipv4/netfilter/ipt_NOTRACK.c4
-rw-r--r--net/ipv4/netfilter/ipt_connbytes.c39
-rw-r--r--net/ipv4/netfilter/ipt_connmark.c10
-rw-r--r--net/ipv4/netfilter/ipt_conntrack.c96
-rw-r--r--net/ipv4/netfilter/ipt_helper.c54
-rw-r--r--net/ipv4/netfilter/ipt_state.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c571
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c301
-rw-r--r--net/ipv4/sysctl_net_ipv4.c8
-rw-r--r--net/ipv4/tcp.c3
-rw-r--r--net/ipv4/tcp_bic.c12
-rw-r--r--net/ipv4/tcp_cong.c40
-rw-r--r--net/ipv4/tcp_highspeed.c11
-rw-r--r--net/ipv4/tcp_htcp.c13
-rw-r--r--net/ipv4/tcp_hybla.c6
-rw-r--r--net/ipv4/tcp_input.c288
-rw-r--r--net/ipv4/tcp_ipv4.c28
-rw-r--r--net/ipv4/tcp_minisocks.c7
-rw-r--r--net/ipv4/tcp_output.c61
-rw-r--r--net/ipv4/tcp_scalable.c14
-rw-r--r--net/ipv4/tcp_timer.c4
-rw-r--r--net/ipv4/tcp_vegas.c42
-rw-r--r--net/ipv4/udp.c7
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/icmp.c21
-rw-r--r--net/ipv6/ip6_input.c5
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/ip6_tunnel.c1
-rw-r--r--net/ipv6/netfilter/Kconfig14
-rw-r--r--net/ipv6/netfilter/Makefile6
-rw-r--r--net/ipv6/netfilter/ip6t_MARK.c6
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c556
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c272
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c885
-rw-r--r--net/ipv6/raw.c46
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/tcp_ipv6.c20
-rw-r--r--net/ipv6/udp.c25
-rw-r--r--net/netfilter/Kconfig74
-rw-r--r--net/netfilter/Makefile8
-rw-r--r--net/netfilter/nf_conntrack_core.c1538
-rw-r--r--net/netfilter/nf_conntrack_ftp.c698
-rw-r--r--net/netfilter/nf_conntrack_l3proto_generic.c98
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c85
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c670
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c1162
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c216
-rw-r--r--net/netfilter/nf_conntrack_standalone.c869
-rw-r--r--net/netfilter/nfnetlink.c21
-rw-r--r--net/netlink/Makefile2
-rw-r--r--net/netlink/af_netlink.c97
-rw-r--r--net/netlink/attr.c328
-rw-r--r--net/netlink/genetlink.c579
-rw-r--r--net/rxrpc/transport.c15
-rw-r--r--net/sunrpc/clnt.c32
-rw-r--r--net/sunrpc/rpc_pipe.c6
-rw-r--r--net/sunrpc/socklib.c5
-rw-r--r--net/sunrpc/svcsock.c9
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--net/xfrm/xfrm_user.c69
-rw-r--r--scripts/kconfig/Makefile27
-rw-r--r--scripts/kconfig/conf.c37
-rw-r--r--scripts/kconfig/confdata.c112
-rw-r--r--scripts/kconfig/expr.h1
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped1749
-rw-r--r--scripts/kconfig/lkc.h14
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rw-r--r--scripts/kconfig/menu.c15
-rw-r--r--scripts/kconfig/symbol.c80
-rw-r--r--scripts/kconfig/zconf.gperf43
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped231
-rw-r--r--scripts/kconfig/zconf.l96
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped1177
-rw-r--r--scripts/kconfig/zconf.tab.h_shipped125
-rw-r--r--scripts/kconfig/zconf.y315
-rw-r--r--security/selinux/hooks.c3
-rw-r--r--security/selinux/selinuxfs.c45
-rw-r--r--security/selinux/ss/mls.c5
-rw-r--r--sound/drivers/vx/vx_hwdep.c1
-rw-r--r--sound/oss/Kconfig73
-rw-r--r--sound/oss/msnd.c1
-rw-r--r--sound/oss/os.h2
-rw-r--r--sound/oss/rme96xx.c1
-rw-r--r--sound/oss/sh_dac_audio.c1
-rw-r--r--sound/pci/ad1889.c1
-rw-r--r--sound/pci/ali5451/ali5451.c1
-rw-r--r--sound/pci/als4000.c1
-rw-r--r--sound/pci/atiixp.c1
-rw-r--r--sound/pci/atiixp_modem.c1
-rw-r--r--sound/pci/au88x0/au88x0.c1
-rw-r--r--sound/pci/azt3328.c1
-rw-r--r--sound/pci/bt87x.c5
-rw-r--r--sound/pci/ca0106/ca0106_main.c1
-rw-r--r--sound/pci/cmipci.c1
-rw-r--r--sound/pci/cs4281.c1
-rw-r--r--sound/pci/cs46xx/cs46xx.c1
-rw-r--r--sound/pci/emu10k1/emu10k1.c1
-rw-r--r--sound/pci/emu10k1/emu10k1x.c1
-rw-r--r--sound/pci/ens1370.c1
-rw-r--r--sound/pci/es1938.c1
-rw-r--r--sound/pci/es1968.c1
-rw-r--r--sound/pci/fm801.c1
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/ice1712/ice1712.c1
-rw-r--r--sound/pci/ice1712/ice1724.c1
-rw-r--r--sound/pci/intel8x0.c1
-rw-r--r--sound/pci/intel8x0m.c1
-rw-r--r--sound/pci/korg1212/korg1212.c1
-rw-r--r--sound/pci/maestro3.c1
-rw-r--r--sound/pci/mixart/mixart.c1
-rw-r--r--sound/pci/nm256/nm256.c1
-rw-r--r--sound/pci/rme32.c1
-rw-r--r--sound/pci/rme96.c1
-rw-r--r--sound/pci/rme9652/hdsp.c1
-rw-r--r--sound/pci/rme9652/hdspm.c1
-rw-r--r--sound/pci/rme9652/rme9652.c1
-rw-r--r--sound/pci/sonicvibes.c1
-rw-r--r--sound/pci/trident/trident.c1
-rw-r--r--sound/pci/via82xx.c1
-rw-r--r--sound/pci/via82xx_modem.c1
-rw-r--r--sound/pci/vx222/vx222.c1
-rw-r--r--sound/pci/ymfpci/ymfpci.c1
-rw-r--r--sound/ppc/pmac.h1
1116 files changed, 65131 insertions, 27331 deletions
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index cb63b7a93c82..df6c05453cb5 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,5 +1,5 @@
1How to get the Nebula, PCTV and Twinhan DST cards working 1How to get the Nebula, PCTV, FusionHDTV Lite and Twinhan DST cards working
2========================================================= 2==========================================================================
3 3
4This class of cards has a bt878a as the PCI interface, and 4This class of cards has a bt878a as the PCI interface, and
5require the bttv driver. 5require the bttv driver.
@@ -26,27 +26,31 @@ Furthermore you need to enable
26 26
27In general you need to load the bttv driver, which will handle the gpio and 27In general you need to load the bttv driver, which will handle the gpio and
28i2c communication for us, plus the common dvb-bt8xx device driver. 28i2c communication for us, plus the common dvb-bt8xx device driver.
29The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and 29The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110), TwinHan (dst),
30TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver. 30FusionHDTV DVB-T Lite (mt352) and FusionHDTV5 Lite (lgdt330x) are loaded
31automatically by the dvb-bt8xx device driver.
31 32
323a) Nebula / Pinnacle PCTV 333a) Nebula / Pinnacle PCTV / FusionHDTV Lite
33-------------------------- 34---------------------------------------------
34 35
35 $ modprobe bttv (normally bttv is being loaded automatically by kmod) 36 $ modprobe bttv (normally bttv is being loaded automatically by kmod)
36 $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading) 37 $ modprobe dvb-bt8xx
38
39(or just place dvb-bt8xx in /etc/modules for automatic loading)
37 40
38 41
393b) TwinHan and Clones 423b) TwinHan and Clones
40-------------------------- 43--------------------------
41 44
42 $ modprobe bttv i2c_hw=1 card=0x71 45 $ modprobe bttv card=0x71
43 $ modprobe dvb-bt8xx 46 $ modprobe dvb-bt8xx
44 $ modprobe dst 47 $ modprobe dst
45 48
46The value 0x71 will override the PCI type detection for dvb-bt8xx, 49The value 0x71 will override the PCI type detection for dvb-bt8xx,
47which is necessary for TwinHan cards. 50which is necessary for TwinHan cards. Omission of this parameter might result
51in a system lockup.
48 52
49If you're having an older card (blue color circuit) and card=0x71 locks 53If you're having an older card (blue color PCB) and card=0x71 locks up
50your machine, try using 0x68, too. If that does not work, ask on the 54your machine, try using 0x68, too. If that does not work, ask on the
51mailing list. 55mailing list.
52 56
@@ -64,11 +68,47 @@ verbose=0 means complete disabling of messages
64dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card. 68dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
650x20 means it has a Conditional Access slot. 690x20 means it has a Conditional Access slot.
66 70
67The autodected values are determined bythe cards 'response 71The autodetected values are determined by the cards 'response string'
68string' which you can see in your logs e.g. 72which you can see in your logs e.g.
69 73
70dst_get_device_id: Recognise [DSTMCI] 74dst_get_device_id: Recognise [DSTMCI]
71 75
76If you need to sent in bug reports on the dst, please do send in a complete
77log with the verbose=4 module parameter. For general usage, the default setting
78of verbose=1 is ideal.
79
80
814) Multiple cards
82--------------------------
83
84If you happen to be running multiple cards, it would be advisable to load
85the bttv module with the card id. This would help to solve any module loading
86problems that you might face.
87
88For example, if you have a Twinhan and Clones card along with a FusionHDTV5 Lite
89
90 $ modprobe bttv card=0x71 card=0x87
91
92Here the order of the card id is important and should be the same as that of the
93physical order of the cards. Here card=0x71 represents the Twinhan and clones
94and card=0x87 represents Fusion HDTV5 Lite. These arguments can also be
95specified in decimal, rather than hex:
96
97 $ modprobe bttv card=113 card=135
98
99Some examples of card-id's
100
101Pinnacle Sat 0x5e (94)
102Nebula Digi TV 0x68 (104)
103PC HDTV 0x70 (112)
104Twinhan 0x71 (113)
105FusionHDTV DVB-T Lite 0x80 (128)
106FusionHDTV5 Lite 0x87 (135)
107
108For a full list of card-id's, see the V4L Documentation within the kernel
109source: linux/Documentation/video4linux/CARDLIST.bttv
110
111If you have problems with this please do ask on the mailing list.
72 112
73-- 113--
74Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham 114Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
diff --git a/Documentation/dvb/cards.txt b/Documentation/dvb/cards.txt
index efdc4ee9d40c..19329cf7b097 100644
--- a/Documentation/dvb/cards.txt
+++ b/Documentation/dvb/cards.txt
@@ -41,6 +41,12 @@ o Frontends drivers:
41 - dib3000mb : DiBcom 3000-MB demodulator 41 - dib3000mb : DiBcom 3000-MB demodulator
42 DVB-S/C/T: 42 DVB-S/C/T:
43 - dst : TwinHan DST Frontend 43 - dst : TwinHan DST Frontend
44 ATSC:
45 - nxt200x : Nxtwave NXT2002 & NXT2004
46 - or51211 : or51211 based (pcHDTV HD2000 card)
47 - or51132 : or51132 based (pcHDTV HD3000 card)
48 - bcm3510 : Broadcom BCM3510
49 - lgdt330x : LG Electronics DT3302 & DT3303
44 50
45 51
46o Cards based on the Phillips saa7146 multimedia PCI bridge chip: 52o Cards based on the Phillips saa7146 multimedia PCI bridge chip:
@@ -62,6 +68,10 @@ o Cards based on the Conexant Bt8xx PCI bridge:
62 - Nebula Electronics DigiTV 68 - Nebula Electronics DigiTV
63 - TwinHan DST 69 - TwinHan DST
64 - Avermedia DVB-T 70 - Avermedia DVB-T
71 - ChainTech digitop DST-1000 DVB-S
72 - pcHDTV HD-2000 TV
73 - DViCO FusionHDTV DVB-T Lite
74 - DViCO FusionHDTV5 Lite
65 75
66o Technotrend / Hauppauge DVB USB devices: 76o Technotrend / Hauppauge DVB USB devices:
67 - Nova USB 77 - Nova USB
@@ -83,3 +93,30 @@ o DiBcom DVB-T USB based devices:
83 - DiBcom USB2.0 DVB-T reference device (non-public) 93 - DiBcom USB2.0 DVB-T reference device (non-public)
84 94
85o Experimental support for the analog module of the Siemens DVB-C PCI card 95o Experimental support for the analog module of the Siemens DVB-C PCI card
96
97o Cards based on the Conexant cx2388x PCI bridge:
98 - ADS Tech Instant TV DVB-T PCI
99 - ATI HDTV Wonder
100 - digitalnow DNTV Live! DVB-T
101 - DViCO FusionHDTV DVB-T1
102 - DViCO FusionHDTV DVB-T Plus
103 - DViCO FusionHDTV3 Gold-Q
104 - DViCO FusionHDTV3 Gold-T
105 - DViCO FusionHDTV5 Gold
106 - Hauppauge Nova-T DVB-T
107 - KWorld/VStream XPert DVB-T
108 - pcHDTV HD3000 HDTV
109 - TerraTec Cinergy 1400 DVB-T
110 - WinFast DTV1000-T
111
112o Cards based on the Phillips saa7134 PCI bridge:
113 - Medion 7134
114 - Pinnacle PCTV 300i DVB-T + PAL
115 - LifeView FlyDVB-T DUO
116 - Typhoon DVB-T Duo Digital/Analog Cardbus
117 - Philips TOUGH DVB-T reference design
118 - Philips EUROPA V3 reference design
119 - Compro Videomate DVB-T300
120 - Compro Videomate DVB-T200
121 - AVerMedia AVerTVHD MCE A180
122
diff --git a/Documentation/dvb/contributors.txt b/Documentation/dvb/contributors.txt
index c9d5ce370701..2cbd2d0f6fdf 100644
--- a/Documentation/dvb/contributors.txt
+++ b/Documentation/dvb/contributors.txt
@@ -75,5 +75,22 @@ Ernst Peinlich <e.peinlich@inode.at>
75Peter Beutner <p.beutner@gmx.net> 75Peter Beutner <p.beutner@gmx.net>
76 for the IR code for the ttusb-dec driver 76 for the IR code for the ttusb-dec driver
77 77
78Wilson Michaels <wilsonmichaels@earthlink.net>
79 for the lgdt330x frontend driver, and various bugfixes
80
81Michael Krufky <mkrufky@m1k.net>
82 for maintaining v4l/dvb inter-tree dependencies
83
84Taylor Jacob <rtjacob@earthlink.net>
85 for the nxt2002 frontend driver
86
87Jean-Francois Thibert <jeanfrancois@sagetv.com>
88 for the nxt2004 frontend driver
89
90Kirk Lapray <kirk.lapray@gmail.com>
91 for the or51211 and or51132 frontend drivers, and
92 for merging the nxt2002 and nxt2004 modules into a
93 single nxt200x frontend driver.
94
78(If you think you should be in this list, but you are not, drop a 95(If you think you should be in this list, but you are not, drop a
79 line to the DVB mailing list) 96 line to the DVB mailing list)
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index a750f0101d9d..be6eb4c75991 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -22,7 +22,7 @@ use File::Temp qw/ tempdir /;
22use IO::Handle; 22use IO::Handle;
23 23
24@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", 24@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
25 "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", 25 "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
26 "or51211", "or51132_qam", "or51132_vsb"); 26 "or51211", "or51132_qam", "or51132_vsb");
27 27
28# Check args 28# Check args
@@ -252,6 +252,23 @@ sub nxt2002 {
252 $outfile; 252 $outfile;
253} 253}
254 254
255sub nxt2004 {
256 my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip";
257 my $url = "http://www.aver.com/support/Drivers/$sourcefile";
258 my $hash = "111cb885b1e009188346d72acfed024c";
259 my $outfile = "dvb-fe-nxt2004.fw";
260 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
261
262 checkstandard();
263
264 wgetfile($sourcefile, $url);
265 unzip($sourcefile, $tmpdir);
266 verify("$tmpdir/3xHybrid.sys", $hash);
267 extract("$tmpdir/3xHybrid.sys", 465304, 9584, $outfile);
268
269 $outfile;
270}
271
255sub or51211 { 272sub or51211 {
256 my $fwfile = "dvb-fe-or51211.fw"; 273 my $fwfile = "dvb-fe-or51211.fw";
257 my $url = "http://linuxtv.org/downloads/firmware/$fwfile"; 274 my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
diff --git a/Documentation/fb/fbcon.txt b/Documentation/fb/fbcon.txt
new file mode 100644
index 000000000000..08dce0f631bf
--- /dev/null
+++ b/Documentation/fb/fbcon.txt
@@ -0,0 +1,152 @@
1The Framebuffer Console
2=======================
3
4 The framebuffer console (fbcon), as its name implies, is a text
5console running on top of the framebuffer device. It has the functionality of
6any standard text console driver, such as the VGA console, with the added
7features that can be attributed to the graphical nature of the framebuffer.
8
9 In the x86 architecture, the framebuffer console is optional, and
10some even treat it as a toy. For other architectures, it is the only available
11display device, text or graphical.
12
13 What are the features of fbcon? The framebuffer console supports
14high resolutions, varying font types, display rotation, primitive multihead,
15etc. Theoretically, multi-colored fonts, blending, aliasing, and any feature
16made available by the underlying graphics card are also possible.
17
18A. Configuration
19
20 The framebuffer console can be enabled by using your favorite kernel
21configuration tool. It is under Device Drivers->Graphics Support->Support for
22framebuffer devices->Framebuffer Console Support. Select 'y' to compile
23support statically, or 'm' for module support. The module will be fbcon.
24
25 In order for fbcon to activate, at least one framebuffer driver is
26required, so choose from any of the numerous drivers available. For x86
27systems, they almost universally have VGA cards, so vga16fb and vesafb will
28always be available. However, using a chipset-specific driver will give you
29more speed and features, such as the ability to change the video mode
30dynamically.
31
32 To display the penguin logo, choose any logo available in Logo
33Configuration->Boot up logo.
34
35 Also, you will need to select at least one compiled-in fonts, but if
36you don't do anything, the kernel configuration tool will select one for you,
37usually an 8x16 font.
38
39GOTCHA: A common bug report is enabling the framebuffer without enabling the
40framebuffer console. Depending on the driver, you may get a blanked or
41garbled display, but the system still boots to completion. If you are
42fortunate to have a driver that does not alter the graphics chip, then you
43will still get a VGA console.
44
45B. Loading
46
47Possible scenarios:
48
491. Driver and fbcon are compiled statically
50
51 Usually, fbcon will automatically take over your console. The notable
52 exception is vesafb. It needs to be explicitly activated with the
53 vga= boot option parameter.
54
552. Driver is compiled statically, fbcon is compiled as a module
56
57 Depending on the driver, you either get a standard console, or a
58 garbled display, as mentioned above. To get a framebuffer console,
59 do a 'modprobe fbcon'.
60
613. Driver is compiled as a module, fbcon is compiled statically
62
63 You get your standard console. Once the driver is loaded with
64 'modprobe xxxfb', fbcon automatically takes over the console with
65 the possible exception of using the fbcon=map:n option. See below.
66
674. Driver and fbcon are compiled as a module.
68
69 You can load them in any order. Once both are loaded, fbcon will take
70 over the console.
71
72C. Boot options
73
74 The framebuffer console has several, largely unknown, boot options
75 that can change its behavior.
76
771. fbcon=font:<name>
78
79 Select the initial font to use. The value 'name' can be any of the
80 compiled-in fonts: VGA8x16, 7x14, 10x18, VGA8x8, MINI4x6, RomanLarge,
81 SUN8x16, SUN12x22, ProFont6x11, Acorn8x8, PEARL8x8.
82
83 Note, not all drivers can handle font with widths not divisible by 8,
84 such as vga16fb.
85
862. fbcon=scrollback:<value>[k]
87
88 The scrollback buffer is memory that is used to preserve display
89 contents that has already scrolled past your view. This is accessed
90 by using the Shift-PageUp key combination. The value 'value' is any
91 integer. It defaults to 32KB. The 'k' suffix is optional, and will
92 multiply the 'value' by 1024.
93
943. fbcon=map:<0123>
95
96 This is an interesting option. It tells which driver gets mapped to
97 which console. The value '0123' is a sequence that gets repeated until
98 the total length is 64 which is the number of consoles available. In
99 the above example, it is expanded to 012301230123... and the mapping
100 will be:
101
102 tty | 1 2 3 4 5 6 7 8 9 ...
103 fb | 0 1 2 3 0 1 2 3 0 ...
104
105 ('cat /proc/fb' should tell you what the fb numbers are)
106
107 One side effect that may be useful is using a map value that exceeds
108 the number of loaded fb drivers. For example, if only one driver is
109 available, fb0, adding fbcon=map:1 tells fbcon not to take over the
110 console.
111
112 Later on, when you want to map the console the to the framebuffer
113 device, you can use the con2fbmap utility.
114
1154. fbcon=vc:<n1>-<n2>
116
117 This option tells fbcon to take over only a range of consoles as
118 specified by the values 'n1' and 'n2'. The rest of the consoles
119 outside the given range will still be controlled by the standard
120 console driver.
121
122 NOTE: For x86 machines, the standard console is the VGA console which
123 is typically located on the same video card. Thus, the consoles that
124 are controlled by the VGA console will be garbled.
125
1264. fbcon=rotate:<n>
127
128 This option changes the orientation angle of the console display. The
129 value 'n' accepts the following:
130
131 0 - normal orientation (0 degree)
132 1 - clockwise orientation (90 degrees)
133 2 - upside down orientation (180 degrees)
134 3 - counterclockwise orientation (270 degrees)
135
136 The angle can be changed anytime afterwards by 'echoing' the same
137 numbers to any one of the 2 attributes found in
138 /sys/class/graphics/fb{x}
139
140 con_rotate - rotate the display of the active console
141 con_rotate_all - rotate the display of all consoles
142
143 Console rotation will only become available if Console Rotation
144 Support is compiled in your kernel.
145
146 NOTE: This is purely console rotation. Any other applications that
147 use the framebuffer will remain at their 'normal'orientation.
148 Actually, the underlying fb driver is totally ignorant of console
149 rotation.
150
151---
152Antonino Daplas <adaplas@pol.net>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index decdf9917e0d..429db4bf98ec 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -25,6 +25,13 @@ Who: Adrian Bunk <bunk@stusta.de>
25 25
26--------------------------- 26---------------------------
27 27
28What: drivers depending on OBSOLETE_OSS_DRIVER
29When: January 2006
30Why: OSS drivers with ALSA replacements
31Who: Adrian Bunk <bunk@stusta.de>
32
33---------------------------
34
28What: RCU API moves to EXPORT_SYMBOL_GPL 35What: RCU API moves to EXPORT_SYMBOL_GPL
29When: April 2006 36When: April 2006
30Files: include/linux/rcupdate.h, kernel/rcupdate.c 37Files: include/linux/rcupdate.h, kernel/rcupdate.c
@@ -60,6 +67,21 @@ Who: Jody McIntyre <scjody@steamballoon.com>
60 67
61--------------------------- 68---------------------------
62 69
70What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
71When: July 2006
72Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
73 series. The old API have lots of drawbacks and don't provide enough
74 means to work with all video and audio standards. The newer API is
75 already available on the main drivers and should be used instead.
76 Newer drivers should use v4l_compat_translate_ioctl function to handle
77 old calls, replacing to newer ones.
78 Decoder iocts are using internally to allow video drivers to
79 communicate with video decoders. This should also be improved to allow
80 V4L2 calls being translated into compatible internal ioctls.
81Who: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
82
83---------------------------
84
63What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid 85What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
64When: November 2005 86When: November 2005
65Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c 87Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
@@ -111,3 +133,10 @@ Why: This interface has been obsoleted by the new layer3-independent
111 to link against API-compatible library on top of libnfnetlink_queue 133 to link against API-compatible library on top of libnfnetlink_queue
112 instead of the current 'libipq'. 134 instead of the current 'libipq'.
113Who: Harald Welte <laforge@netfilter.org> 135Who: Harald Welte <laforge@netfilter.org>
136
137---------------------------
138
139What: EXPORT_SYMBOL(lookup_hash)
140When: January 2006
141Why: Too low-level interface. Use lookup_one_len or lookup_create instead.
142Who: Christoph Hellwig <hch@lst.de>
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
index d16334ec48ba..a8edb376b041 100644
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -17,8 +17,6 @@ set using tune2fs(8). Kernel-determined defaults are indicated by (*).
17bsddf (*) Makes `df' act like BSD. 17bsddf (*) Makes `df' act like BSD.
18minixdf Makes `df' act like Minix. 18minixdf Makes `df' act like Minix.
19 19
20check Check block and inode bitmaps at mount time
21 (requires CONFIG_EXT2_CHECK).
22check=none, nocheck (*) Don't do extra checking of bitmaps on mount 20check=none, nocheck (*) Don't do extra checking of bitmaps on mount
23 (check=normal and check=strict options removed) 21 (check=normal and check=strict options removed)
24 22
diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro
index 9363b8bd6109..16775663b9f5 100644
--- a/Documentation/i2c/busses/i2c-viapro
+++ b/Documentation/i2c/busses/i2c-viapro
@@ -7,12 +7,10 @@ Supported adapters:
7 * VIA Technologies, Inc. VT82C686A/B 7 * VIA Technologies, Inc. VT82C686A/B
8 Datasheet: Sometimes available at the VIA website 8 Datasheet: Sometimes available at the VIA website
9 9
10 * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237 10 * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237R
11 Datasheet: available on request from Via 11 Datasheet: available on request from VIA
12 12
13Authors: 13Authors:
14 Frodo Looijaard <frodol@dds.nl>,
15 Philip Edelbrock <phil@netroedge.com>,
16 Kyösti Mälkki <kmalkki@cc.hut.fi>, 14 Kyösti Mälkki <kmalkki@cc.hut.fi>,
17 Mark D. Studebaker <mdsxyz123@yahoo.com>, 15 Mark D. Studebaker <mdsxyz123@yahoo.com>,
18 Jean Delvare <khali@linux-fr.org> 16 Jean Delvare <khali@linux-fr.org>
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index cff7b652588a..d19993cc0604 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -412,7 +412,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
412 release_region(address,FOO_EXTENT); 412 release_region(address,FOO_EXTENT);
413 /* SENSORS ONLY END */ 413 /* SENSORS ONLY END */
414 ERROR1: 414 ERROR1:
415 kfree(new_client); 415 kfree(data);
416 ERROR0: 416 ERROR0:
417 return err; 417 return err;
418 } 418 }
@@ -443,7 +443,7 @@ much simpler than the attachment code, fortunately!
443 release_region(client->addr,LM78_EXTENT); 443 release_region(client->addr,LM78_EXTENT);
444 /* HYBRID SENSORS CHIP ONLY END */ 444 /* HYBRID SENSORS CHIP ONLY END */
445 445
446 kfree(data); 446 kfree(i2c_get_clientdata(client));
447 return 0; 447 return 0;
448 } 448 }
449 449
diff --git a/Documentation/md.txt b/Documentation/md.txt
index e2b536992a27..23e6cce40f9c 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -116,3 +116,122 @@ and it's role in the array.
116 116
117Once started with RUN_ARRAY, uninitialized spares can be added with 117Once started with RUN_ARRAY, uninitialized spares can be added with
118HOT_ADD_DISK. 118HOT_ADD_DISK.
119
120
121
122MD devices in sysfs
123-------------------
124md devices appear in sysfs (/sys) as regular block devices,
125e.g.
126 /sys/block/md0
127
128Each 'md' device will contain a subdirectory called 'md' which
129contains further md-specific information about the device.
130
131All md devices contain:
132 level
133 a text file indicating the 'raid level'. This may be a standard
134 numerical level prefixed by "RAID-" - e.g. "RAID-5", or some
135 other name such as "linear" or "multipath".
136 If no raid level has been set yet (array is still being
137 assembled), this file will be empty.
138
139 raid_disks
140 a text file with a simple number indicating the number of devices
141 in a fully functional array. If this is not yet known, the file
142 will be empty. If an array is being resized (not currently
143 possible) this will contain the larger of the old and new sizes.
144
145As component devices are added to an md array, they appear in the 'md'
146directory as new directories named
147 dev-XXX
148where XXX is a name that the kernel knows for the device, e.g. hdb1.
149Each directory contains:
150
151 block
152 a symlink to the block device in /sys/block, e.g.
153 /sys/block/md0/md/dev-hdb1/block -> ../../../../block/hdb/hdb1
154
155 super
156 A file containing an image of the superblock read from, or
157 written to, that device.
158
159 state
160 A file recording the current state of the device in the array
161 which can be a comma separated list of
162 faulty - device has been kicked from active use due to
163 a detected fault
164 in_sync - device is a fully in-sync member of the array
165 spare - device is working, but not a full member.
166 This includes spares that are in the process
167 of being recoverred to
168 This list make grow in future.
169
170
171An active md device will also contain and entry for each active device
172in the array. These are named
173
174 rdNN
175
176where 'NN' is the possition in the array, starting from 0.
177So for a 3 drive array there will be rd0, rd1, rd2.
178These are symbolic links to the appropriate 'dev-XXX' entry.
179Thus, for example,
180 cat /sys/block/md*/md/rd*/state
181will show 'in_sync' on every line.
182
183
184
185Active md devices for levels that support data redundancy (1,4,5,6)
186also have
187
188 sync_action
189 a text file that can be used to monitor and control the rebuild
190 process. It contains one word which can be one of:
191 resync - redundancy is being recalculated after unclean
192 shutdown or creation
193 recover - a hot spare is being built to replace a
194 failed/missing device
195 idle - nothing is happening
196 check - A full check of redundancy was requested and is
197 happening. This reads all block and checks
198 them. A repair may also happen for some raid
199 levels.
200 repair - A full check and repair is happening. This is
201 similar to 'resync', but was requested by the
202 user, and the write-intent bitmap is NOT used to
203 optimise the process.
204
205 This file is writable, and each of the strings that could be
206 read are meaningful for writing.
207
208 'idle' will stop an active resync/recovery etc. There is no
209 guarantee that another resync/recovery may not be automatically
210 started again, though some event will be needed to trigger
211 this.
212 'resync' or 'recovery' can be used to restart the
213 corresponding operation if it was stopped with 'idle'.
214 'check' and 'repair' will start the appropriate process
215 providing the current state is 'idle'.
216
217 mismatch_count
218 When performing 'check' and 'repair', and possibly when
219 performing 'resync', md will count the number of errors that are
220 found. The count in 'mismatch_cnt' is the number of sectors
221 that were re-written, or (for 'check') would have been
222 re-written. As most raid levels work in units of pages rather
223 than sectors, this my be larger than the number of actual errors
224 by a factor of the number of sectors in a page.
225
226Each active md device may also have attributes specific to the
227personality module that manages it.
228These are specific to the implementation of the module and could
229change substantially if the implementation changes.
230
231These currently include
232
233 stripe_cache_size (currently raid5 only)
234 number of entries in the stripe cache. This is writable, but
235 there are upper and lower limits (32768, 16). Default is 128.
236 strip_cache_active (currently raid5 only)
237 number of active entries in the stripe cache
diff --git a/Documentation/networking/README.ipw2100 b/Documentation/networking/README.ipw2100
index 2046948b020d..3ab40379d1cf 100644
--- a/Documentation/networking/README.ipw2100
+++ b/Documentation/networking/README.ipw2100
@@ -1,27 +1,82 @@
1 1
2=========================== 2Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
3Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux 3
4Intel(R) PRO/Wireless 2100 Network Connection
5
6Copyright (C) 2003-2005, Intel Corporation
7
4README.ipw2100 8README.ipw2100
5 9
6March 14, 2005 10Version: 1.1.3
11Date : October 17, 2005
7 12
8===========================
9Index 13Index
10--------------------------- 14-----------------------------------------------
110. Introduction 150. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
121. Release 1.1.0 Current Features 161. Introduction
132. Command Line Parameters 172. Release 1.1.3 Current Features
143. Sysfs Helper Files 183. Command Line Parameters
154. Radio Kill Switch 194. Sysfs Helper Files
165. Dynamic Firmware 205. Radio Kill Switch
176. Power Management 216. Dynamic Firmware
187. Support 227. Power Management
198. License 238. Support
20 249. License
21 25
22=========================== 26
230. Introduction 270. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
24------------ ----- ----- ---- --- -- - 28-----------------------------------------------
29
30Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
31
32Intel wireless LAN adapters are engineered, manufactured, tested, and
33quality checked to ensure that they meet all necessary local and
34governmental regulatory agency requirements for the regions that they
35are designated and/or marked to ship into. Since wireless LANs are
36generally unlicensed devices that share spectrum with radars,
37satellites, and other licensed and unlicensed devices, it is sometimes
38necessary to dynamically detect, avoid, and limit usage to avoid
39interference with these devices. In many instances Intel is required to
40provide test data to prove regional and local compliance to regional and
41governmental regulations before certification or approval to use the
42product is granted. Intel's wireless LAN's EEPROM, firmware, and
43software driver are designed to carefully control parameters that affect
44radio operation and to ensure electromagnetic compliance (EMC). These
45parameters include, without limitation, RF power, spectrum usage,
46channel scanning, and human exposure.
47
48For these reasons Intel cannot permit any manipulation by third parties
49of the software provided in binary format with the wireless WLAN
50adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
51patches, utilities, or code with the Intel wireless LAN adapters that
52have been manipulated by an unauthorized party (i.e., patches,
53utilities, or code (including open source code modifications) which have
54not been validated by Intel), (i) you will be solely responsible for
55ensuring the regulatory compliance of the products, (ii) Intel will bear
56no liability, under any theory of liability for any issues associated
57with the modified products, including without limitation, claims under
58the warranty and/or issues arising from regulatory non-compliance, and
59(iii) Intel will not provide or be required to assist in providing
60support to any third parties for such modified products.
61
62Note: Many regulatory agencies consider Wireless LAN adapters to be
63modules, and accordingly, condition system-level regulatory approval
64upon receipt and review of test data documenting that the antennas and
65system configuration do not cause the EMC and radio operation to be
66non-compliant.
67
68The drivers available for download from SourceForge are provided as a
69part of a development project. Conformance to local regulatory
70requirements is the responsibility of the individual developer. As
71such, if you are interested in deploying or shipping a driver as part of
72solution intended to be used for purposes other than development, please
73obtain a tested driver from Intel Customer Support at:
74
75http://support.intel.com/support/notebook/sb/CS-006408.htm
76
77
781. Introduction
79-----------------------------------------------
25 80
26This document provides a brief overview of the features supported by the 81This document provides a brief overview of the features supported by the
27IPW2100 driver project. The main project website, where the latest 82IPW2100 driver project. The main project website, where the latest
@@ -34,9 +89,8 @@ potential fixes and patches, as well as links to the development mailing list
34for the driver project. 89for the driver project.
35 90
36 91
37=========================== 922. Release 1.1.3 Current Supported Features
381. Release 1.1.0 Current Supported Features 93-----------------------------------------------
39---------------------------
40- Managed (BSS) and Ad-Hoc (IBSS) 94- Managed (BSS) and Ad-Hoc (IBSS)
41- WEP (shared key and open) 95- WEP (shared key and open)
42- Wireless Tools support 96- Wireless Tools support
@@ -51,9 +105,8 @@ on the amount of validation and interoperability testing that has been
51performed on a given feature. 105performed on a given feature.
52 106
53 107
54=========================== 1083. Command Line Parameters
552. Command Line Parameters 109-----------------------------------------------
56---------------------------
57 110
58If the driver is built as a module, the following optional parameters are used 111If the driver is built as a module, the following optional parameters are used
59by entering them on the command line with the modprobe command using this 112by entering them on the command line with the modprobe command using this
@@ -75,9 +128,9 @@ associate boolean associate=0 /* Do NOT auto associate */
75disable boolean disable=1 /* Do not power the HW */ 128disable boolean disable=1 /* Do not power the HW */
76 129
77 130
78=========================== 1314. Sysfs Helper Files
793. Sysfs Helper Files
80--------------------------- 132---------------------------
133-----------------------------------------------
81 134
82There are several ways to control the behavior of the driver. Many of the 135There are several ways to control the behavior of the driver. Many of the
83general capabilities are exposed through the Wireless Tools (iwconfig). There 136general capabilities are exposed through the Wireless Tools (iwconfig). There
@@ -120,9 +173,8 @@ For the device level files, see /sys/bus/pci/drivers/ipw2100:
120 based RF kill from ON -> OFF -> ON, the radio will NOT come back on 173 based RF kill from ON -> OFF -> ON, the radio will NOT come back on
121 174
122 175
123=========================== 1765. Radio Kill Switch
1244. Radio Kill Switch 177-----------------------------------------------
125---------------------------
126Most laptops provide the ability for the user to physically disable the radio. 178Most laptops provide the ability for the user to physically disable the radio.
127Some vendors have implemented this as a physical switch that requires no 179Some vendors have implemented this as a physical switch that requires no
128software to turn the radio off and on. On other laptops, however, the switch 180software to turn the radio off and on. On other laptops, however, the switch
@@ -134,9 +186,8 @@ See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
134on your system. 186on your system.
135 187
136 188
137=========================== 1896. Dynamic Firmware
1385. Dynamic Firmware 190-----------------------------------------------
139---------------------------
140As the firmware is licensed under a restricted use license, it can not be 191As the firmware is licensed under a restricted use license, it can not be
141included within the kernel sources. To enable the IPW2100 you will need a 192included within the kernel sources. To enable the IPW2100 you will need a
142firmware image to load into the wireless NIC's processors. 193firmware image to load into the wireless NIC's processors.
@@ -146,9 +197,8 @@ You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
146See INSTALL for instructions on installing the firmware. 197See INSTALL for instructions on installing the firmware.
147 198
148 199
149=========================== 2007. Power Management
1506. Power Management 201-----------------------------------------------
151---------------------------
152The IPW2100 supports the configuration of the Power Save Protocol 202The IPW2100 supports the configuration of the Power Save Protocol
153through a private wireless extension interface. The IPW2100 supports 203through a private wireless extension interface. The IPW2100 supports
154the following different modes: 204the following different modes:
@@ -200,9 +250,8 @@ xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
200level if `iwconfig eth1 power on` is invoked. 250level if `iwconfig eth1 power on` is invoked.
201 251
202 252
203=========================== 2538. Support
2047. Support 254-----------------------------------------------
205---------------------------
206 255
207For general development information and support, 256For general development information and support,
208go to: 257go to:
@@ -218,9 +267,8 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
218 267
219 http://supportmail.intel.com 268 http://supportmail.intel.com
220 269
221=========================== 2709. License
2228. License 271-----------------------------------------------
223---------------------------
224 272
225 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 273 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
226 274
diff --git a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200
index 6916080c5f03..c6492d3839fa 100644
--- a/Documentation/networking/README.ipw2200
+++ b/Documentation/networking/README.ipw2200
@@ -1,33 +1,89 @@
1 1
2Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of: 2Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
3 3
4Intel(R) PRO/Wireless 2200BG Network Connection 4Intel(R) PRO/Wireless 2200BG Network Connection
5Intel(R) PRO/Wireless 2915ABG Network Connection 5Intel(R) PRO/Wireless 2915ABG Network Connection
6 6
7Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R) 7Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
8PRO/Wireless 2200BG Driver for Linux is a unified driver that works on 8PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
9both hardware adapters listed above. In this document the Intel(R) 9both hardware adapters listed above. In this document the Intel(R)
10PRO/Wireless 2915ABG Driver for Linux will be used to reference the 10PRO/Wireless 2915ABG Driver for Linux will be used to reference the
11unified driver. 11unified driver.
12 12
13Copyright (C) 2004-2005, Intel Corporation 13Copyright (C) 2004-2005, Intel Corporation
14 14
15README.ipw2200 15README.ipw2200
16 16
17Version: 1.0.0 17Version: 1.0.8
18Date : January 31, 2005 18Date : October 20, 2005
19 19
20 20
21Index 21Index
22----------------------------------------------- 22-----------------------------------------------
230. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
231. Introduction 241. Introduction
241.1. Overview of features 251.1. Overview of features
251.2. Module parameters 261.2. Module parameters
261.3. Wireless Extension Private Methods 271.3. Wireless Extension Private Methods
271.4. Sysfs Helper Files 281.4. Sysfs Helper Files
282. About the Version Numbers 292. Ad-Hoc Networking
293. Support 303. Interacting with Wireless Tools
304. License 313.1. iwconfig mode
324. About the Version Numbers
335. Firmware installation
346. Support
357. License
36
37
380. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
39-----------------------------------------------
40
41Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
42
43Intel wireless LAN adapters are engineered, manufactured, tested, and
44quality checked to ensure that they meet all necessary local and
45governmental regulatory agency requirements for the regions that they
46are designated and/or marked to ship into. Since wireless LANs are
47generally unlicensed devices that share spectrum with radars,
48satellites, and other licensed and unlicensed devices, it is sometimes
49necessary to dynamically detect, avoid, and limit usage to avoid
50interference with these devices. In many instances Intel is required to
51provide test data to prove regional and local compliance to regional and
52governmental regulations before certification or approval to use the
53product is granted. Intel's wireless LAN's EEPROM, firmware, and
54software driver are designed to carefully control parameters that affect
55radio operation and to ensure electromagnetic compliance (EMC). These
56parameters include, without limitation, RF power, spectrum usage,
57channel scanning, and human exposure.
58
59For these reasons Intel cannot permit any manipulation by third parties
60of the software provided in binary format with the wireless WLAN
61adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
62patches, utilities, or code with the Intel wireless LAN adapters that
63have been manipulated by an unauthorized party (i.e., patches,
64utilities, or code (including open source code modifications) which have
65not been validated by Intel), (i) you will be solely responsible for
66ensuring the regulatory compliance of the products, (ii) Intel will bear
67no liability, under any theory of liability for any issues associated
68with the modified products, including without limitation, claims under
69the warranty and/or issues arising from regulatory non-compliance, and
70(iii) Intel will not provide or be required to assist in providing
71support to any third parties for such modified products.
72
73Note: Many regulatory agencies consider Wireless LAN adapters to be
74modules, and accordingly, condition system-level regulatory approval
75upon receipt and review of test data documenting that the antennas and
76system configuration do not cause the EMC and radio operation to be
77non-compliant.
78
79The drivers available for download from SourceForge are provided as a
80part of a development project. Conformance to local regulatory
81requirements is the responsibility of the individual developer. As
82such, if you are interested in deploying or shipping a driver as part of
83solution intended to be used for purposes other than development, please
84obtain a tested driver from Intel Customer Support at:
85
86http://support.intel.com/support/notebook/sb/CS-006408.htm
31 87
32 88
331. Introduction 891. Introduction
@@ -45,7 +101,7 @@ file.
45 101
461.1. Overview of Features 1021.1. Overview of Features
47----------------------------------------------- 103-----------------------------------------------
48The current release (1.0.0) supports the following features: 104The current release (1.0.8) supports the following features:
49 105
50+ BSS mode (Infrastructure, Managed) 106+ BSS mode (Infrastructure, Managed)
51+ IBSS mode (Ad-Hoc) 107+ IBSS mode (Ad-Hoc)
@@ -56,17 +112,27 @@ The current release (1.0.0) supports the following features:
56+ Full A rate support (2915 only) 112+ Full A rate support (2915 only)
57+ Transmit power control 113+ Transmit power control
58+ S state support (ACPI suspend/resume) 114+ S state support (ACPI suspend/resume)
115
116The following features are currently enabled, but not officially
117supported:
118
119+ WPA
59+ long/short preamble support 120+ long/short preamble support
121+ Monitor mode (aka RFMon)
122
123The distinction between officially supported and enabled is a reflection
124on the amount of validation and interoperability testing that has been
125performed on a given feature.
60 126
61 127
62 128
631.2. Command Line Parameters 1291.2. Command Line Parameters
64----------------------------------------------- 130-----------------------------------------------
65 131
66Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless 132Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
672915ABG Driver for Linux allows certain configuration options to be 1332915ABG Driver for Linux allows configuration options to be provided
68provided as module parameters. The most common way to specify a module 134as module parameters. The most common way to specify a module parameter
69parameter is via the command line. 135is via the command line.
70 136
71The general form is: 137The general form is:
72 138
@@ -96,14 +162,18 @@ Where the supported parameter are:
96 162
97 debug 163 debug
98 If using a debug build, this is used to control the amount of debug 164 If using a debug build, this is used to control the amount of debug
99 info is logged. See the 'dval' and 'load' script for more info on 165 info is logged. See the 'dvals' and 'load' script for more info on
100 how to use this (the dval and load scripts are provided as part 166 how to use this (the dvals and load scripts are provided as part
101 of the ipw2200 development snapshot releases available from the 167 of the ipw2200 development snapshot releases available from the
102 SourceForge project at http://ipw2200.sf.net) 168 SourceForge project at http://ipw2200.sf.net)
169
170 led
171 Can be used to turn on experimental LED code.
172 0 = Off, 1 = On. Default is 0.
103 173
104 mode 174 mode
105 Can be used to set the default mode of the adapter. 175 Can be used to set the default mode of the adapter.
106 0 = Managed, 1 = Ad-Hoc 176 0 = Managed, 1 = Ad-Hoc, 2 = Monitor
107 177
108 178
1091.3. Wireless Extension Private Methods 1791.3. Wireless Extension Private Methods
@@ -164,8 +234,8 @@ The supported private methods are:
164----------------------------------------------- 234-----------------------------------------------
165 235
166The Linux kernel provides a pseudo file system that can be used to 236The Linux kernel provides a pseudo file system that can be used to
167access various components of the operating system. The Intel(R) 237access various components of the operating system. The Intel(R)
168PRO/Wireless 2915ABG Driver for Linux exposes several configuration 238PRO/Wireless 2915ABG Driver for Linux exposes several configuration
169parameters through this mechanism. 239parameters through this mechanism.
170 240
171An entry in the sysfs can support reading and/or writing. You can 241An entry in the sysfs can support reading and/or writing. You can
@@ -184,13 +254,13 @@ You can set the debug level via:
184 254
185Where $VALUE would be a number in the case of this sysfs entry. The 255Where $VALUE would be a number in the case of this sysfs entry. The
186input to sysfs files does not have to be a number. For example, the 256input to sysfs files does not have to be a number. For example, the
187firmware loader used by hotplug utilizes sysfs entries for transferring 257firmware loader used by hotplug utilizes sysfs entries for transfering
188the firmware image from user space into the driver. 258the firmware image from user space into the driver.
189 259
190The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries 260The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries
191at two levels -- driver level, which apply to all instances of the 261at two levels -- driver level, which apply to all instances of the driver
192driver (in the event that there are more than one device installed) and 262(in the event that there are more than one device installed) and device
193device level, which applies only to the single specific instance. 263level, which applies only to the single specific instance.
194 264
195 265
1961.4.1 Driver Level Sysfs Helper Files 2661.4.1 Driver Level Sysfs Helper Files
@@ -203,6 +273,7 @@ For the driver level files, look in /sys/bus/pci/drivers/ipw2200/
203 This controls the same global as the 'debug' module parameter 273 This controls the same global as the 'debug' module parameter
204 274
205 275
276
2061.4.2 Device Level Sysfs Helper Files 2771.4.2 Device Level Sysfs Helper Files
207----------------------------------------------- 278-----------------------------------------------
208 279
@@ -213,7 +284,7 @@ For the device level files, look in
213For example: 284For example:
214 /sys/bus/pci/drivers/ipw2200/0000:02:01.0 285 /sys/bus/pci/drivers/ipw2200/0000:02:01.0
215 286
216For the device level files, see /sys/bus/pci/[drivers/ipw2200: 287For the device level files, see /sys/bus/pci/drivers/ipw2200:
217 288
218 rf_kill 289 rf_kill
219 read - 290 read -
@@ -231,8 +302,59 @@ For the device level files, see /sys/bus/pci/[drivers/ipw2200:
231 ucode 302 ucode
232 read-only access to the ucode version number 303 read-only access to the ucode version number
233 304
305 led
306 read -
307 0 = LED code disabled
308 1 = LED code enabled
309 write -
310 0 = Disable LED code
311 1 = Enable LED code
312
313 NOTE: The LED code has been reported to hang some systems when
314 running ifconfig and is therefore disabled by default.
315
316
3172. Ad-Hoc Networking
318-----------------------------------------------
319
320When using a device in an Ad-Hoc network, it is useful to understand the
321sequence and requirements for the driver to be able to create, join, or
322merge networks.
323
324The following attempts to provide enough information so that you can
325have a consistent experience while using the driver as a member of an
326Ad-Hoc network.
327
3282.1. Joining an Ad-Hoc Network
329-----------------------------------------------
330
331The easiest way to get onto an Ad-Hoc network is to join one that
332already exists.
234 333
2352. About the Version Numbers 3342.2. Creating an Ad-Hoc Network
335-----------------------------------------------
336
337An Ad-Hoc networks is created using the syntax of the Wireless tool.
338
339For Example:
340iwconfig eth1 mode ad-hoc essid testing channel 2
341
3422.3. Merging Ad-Hoc Networks
343-----------------------------------------------
344
345
3463. Interaction with Wireless Tools
347-----------------------------------------------
348
3493.1 iwconfig mode
350-----------------------------------------------
351
352When configuring the mode of the adapter, all run-time configured parameters
353are reset to the value used when the module was loaded. This includes
354channels, rates, ESSID, etc.
355
356
3574. About the Version Numbers
236----------------------------------------------- 358-----------------------------------------------
237 359
238Due to the nature of open source development projects, there are 360Due to the nature of open source development projects, there are
@@ -259,12 +381,23 @@ available as quickly as possible, unknown anomalies should be expected.
259The major version number will be incremented when significant changes 381The major version number will be incremented when significant changes
260are made to the driver. Currently, there are no major changes planned. 382are made to the driver. Currently, there are no major changes planned.
261 383
3845. Firmware installation
385----------------------------------------------
386
387The driver requires a firmware image, download it and extract the
388files under /lib/firmware (or wherever your hotplug's firmware.agent
389will look for firmware files)
390
391The firmware can be downloaded from the following URL:
262 392
2633. Support 393 http://ipw2200.sf.net/
394
395
3966. Support
264----------------------------------------------- 397-----------------------------------------------
265 398
266For installation support of the 1.0.0 version, you can contact 399For direct support of the 1.0.0 version, you can contact
267http://supportmail.intel.com, or you can use the open source project 400http://supportmail.intel.com, or you can use the open source project
268support. 401support.
269 402
270For general information and support, go to: 403For general information and support, go to:
@@ -272,7 +405,7 @@ For general information and support, go to:
272 http://ipw2200.sf.net/ 405 http://ipw2200.sf.net/
273 406
274 407
2754. License 4087. License
276----------------------------------------------- 409-----------------------------------------------
277 410
278 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 411 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
@@ -297,4 +430,3 @@ For general information and support, go to:
297 James P. Ketrenos <ipw2100-admin@linux.intel.com> 430 James P. Ketrenos <ipw2100-admin@linux.intel.com>
298 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 431 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
299 432
300
diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt
new file mode 100644
index 000000000000..c45daabd3bfe
--- /dev/null
+++ b/Documentation/networking/dccp.txt
@@ -0,0 +1,56 @@
1DCCP protocol
2============
3
4Last updated: 10 November 2005
5
6Contents
7========
8
9- Introduction
10- Missing features
11- Socket options
12- Notes
13
14Introduction
15============
16
17Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
18based protocol designed to solve issues present in UDP and TCP particularly
19for real time and multimedia traffic.
20
21It has a base protocol and pluggable congestion control IDs (CCIDs).
22
23It is at draft RFC status and the homepage for DCCP as a protocol is at:
24 http://www.icir.org/kohler/dcp/
25
26Missing features
27================
28
29The DCCP implementation does not currently have all the features that are in
30the draft RFC.
31
32In particular the following are missing:
33- CCID2 support
34- feature negotiation
35
36When testing against other implementations it appears that elapsed time
37options are not coded compliant to the specification.
38
39Socket options
40==============
41
42DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
43calculations.
44
45DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the
46specification. If you don't set it you will get EPROTO.
47
48Notes
49=====
50
51SELinux does not yet have support for DCCP. You will need to turn it off or
52else you will get EACCES.
53
54DCCP does not travel through NAT successfully at present. This is because
55the checksum covers the psuedo-header as per TCP and UDP. It should be
56relatively trivial to add Linux NAT support for DCCP.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 65895bb51414..ebc09a159f62 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -78,6 +78,11 @@ inet_peer_gc_maxtime - INTEGER
78 78
79TCP variables: 79TCP variables:
80 80
81tcp_abc - INTEGER
82 Controls Appropriate Byte Count defined in RFC3465. If set to
83 0 then does congestion avoid once per ack. 1 is conservative
84 value, and 2 is more agressive.
85
81tcp_syn_retries - INTEGER 86tcp_syn_retries - INTEGER
82 Number of times initial SYNs for an active TCP connection attempt 87 Number of times initial SYNs for an active TCP connection attempt
83 will be retransmitted. Should not be higher than 255. Default value 88 will be retransmitted. Should not be higher than 255. Default value
diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt
index adbfe620c061..844c03fe7921 100644
--- a/Documentation/s390/Debugging390.txt
+++ b/Documentation/s390/Debugging390.txt
@@ -871,7 +871,7 @@ by playing with the --adjust-vma parameter to objdump.
871 871
872 872
873 873
874extern inline void spin_lock(spinlock_t *lp) 874static inline void spin_lock(spinlock_t *lp)
875{ 875{
876 a0: 18 34 lr %r3,%r4 876 a0: 18 34 lr %r3,%r4
877 a2: a7 3a 03 bc ahi %r3,956 877 a2: a7 3a 03 bc ahi %r3,956
diff --git a/Documentation/sched-arch.txt b/Documentation/sched-arch.txt
new file mode 100644
index 000000000000..941615a9769b
--- /dev/null
+++ b/Documentation/sched-arch.txt
@@ -0,0 +1,89 @@
1 CPU Scheduler implementation hints for architecture specific code
2
3 Nick Piggin, 2005
4
5Context switch
6==============
71. Runqueue locking
8By default, the switch_to arch function is called with the runqueue
9locked. This is usually not a problem unless switch_to may need to
10take the runqueue lock. This is usually due to a wake up operation in
11the context switch. See include/asm-ia64/system.h for an example.
12
13To request the scheduler call switch_to with the runqueue unlocked,
14you must `#define __ARCH_WANT_UNLOCKED_CTXSW` in a header file
15(typically the one where switch_to is defined).
16
17Unlocked context switches introduce only a very minor performance
18penalty to the core scheduler implementation in the CONFIG_SMP case.
19
202. Interrupt status
21By default, the switch_to arch function is called with interrupts
22disabled. Interrupts may be enabled over the call if it is likely to
23introduce a significant interrupt latency by adding the line
24`#define __ARCH_WANT_INTERRUPTS_ON_CTXSW` in the same place as for
25unlocked context switches. This define also implies
26`__ARCH_WANT_UNLOCKED_CTXSW`. See include/asm-arm/system.h for an
27example.
28
29
30CPU idle
31========
32Your cpu_idle routines need to obey the following rules:
33
341. Preempt should now disabled over idle routines. Should only
35 be enabled to call schedule() then disabled again.
36
372. need_resched/TIF_NEED_RESCHED is only ever set, and will never
38 be cleared until the running task has called schedule(). Idle
39 threads need only ever query need_resched, and may never set or
40 clear it.
41
423. When cpu_idle finds (need_resched() == 'true'), it should call
43 schedule(). It should not call schedule() otherwise.
44
454. The only time interrupts need to be disabled when checking
46 need_resched is if we are about to sleep the processor until
47 the next interrupt (this doesn't provide any protection of
48 need_resched, it prevents losing an interrupt).
49
50 4a. Common problem with this type of sleep appears to be:
51 local_irq_disable();
52 if (!need_resched()) {
53 local_irq_enable();
54 *** resched interrupt arrives here ***
55 __asm__("sleep until next interrupt");
56 }
57
585. TIF_POLLING_NRFLAG can be set by idle routines that do not
59 need an interrupt to wake them up when need_resched goes high.
60 In other words, they must be periodically polling need_resched,
61 although it may be reasonable to do some background work or enter
62 a low CPU priority.
63
64 5a. If TIF_POLLING_NRFLAG is set, and we do decide to enter
65 an interrupt sleep, it needs to be cleared then a memory
66 barrier issued (followed by a test of need_resched with
67 interrupts disabled, as explained in 3).
68
69arch/i386/kernel/process.c has examples of both polling and
70sleeping idle functions.
71
72
73Possible arch/ problems
74=======================
75
76Possible arch problems I found (and either tried to fix or didn't):
77
78h8300 - Is such sleeping racy vs interrupts? (See #4a).
79 The H8/300 manual I found indicates yes, however disabling IRQs
80 over the sleep mean only NMIs can wake it up, so can't fix easily
81 without doing spin waiting.
82
83ia64 - is safe_halt call racy vs interrupts? (does it sleep?) (See #4a)
84
85sh64 - Is sleeping racy vs interrupts? (See #4a)
86
87sparc - IRQs on at this point(?), change local_irq_save to _disable.
88 - TODO: needs secondary CPUs to disable preempt (See #1)
89
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html
index 441407b12a9f..afbe9ae7ee96 100644
--- a/Documentation/video4linux/API.html
+++ b/Documentation/video4linux/API.html
@@ -8,7 +8,7 @@ V4L original API</a>
8</td><td> 8</td><td>
9Obsoleted by V4L2 API 9Obsoleted by V4L2 API
10</td></tr><tr><td> 10</td></tr><tr><td>
11<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html> 11<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API>
12V4L2 API</a> 12V4L2 API</a>
13</td><td> 13</td><td>
14Should be used for new projects 14Should be used for new projects
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index ec785f9f15a3..2404099996ac 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -1,137 +1,142 @@
1card=0 - *** UNKNOWN/GENERIC *** 1 0 -> *** UNKNOWN/GENERIC ***
2card=1 - MIRO PCTV 2 1 -> MIRO PCTV
3card=2 - Hauppauge (bt848) 3 2 -> Hauppauge (bt848)
4card=3 - STB, Gateway P/N 6000699 (bt848) 4 3 -> STB, Gateway P/N 6000699 (bt848)
5card=4 - Intel Create and Share PCI/ Smart Video Recorder III 5 4 -> Intel Create and Share PCI/ Smart Video Recorder III
6card=5 - Diamond DTV2000 6 5 -> Diamond DTV2000
7card=6 - AVerMedia TVPhone 7 6 -> AVerMedia TVPhone
8card=7 - MATRIX-Vision MV-Delta 8 7 -> MATRIX-Vision MV-Delta
9card=8 - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 9 8 -> Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
10card=9 - IMS/IXmicro TurboTV 10 9 -> IMS/IXmicro TurboTV
11card=10 - Hauppauge (bt878) 11 10 -> Hauppauge (bt878) [0070:13eb,0070:3900,2636:10b4]
12card=11 - MIRO PCTV pro 12 11 -> MIRO PCTV pro
13card=12 - ADS Technologies Channel Surfer TV (bt848) 13 12 -> ADS Technologies Channel Surfer TV (bt848)
14card=13 - AVerMedia TVCapture 98 14 13 -> AVerMedia TVCapture 98 [1461:0002,1461:0004,1461:0300]
15card=14 - Aimslab Video Highway Xtreme (VHX) 15 14 -> Aimslab Video Highway Xtreme (VHX)
16card=15 - Zoltrix TV-Max 16 15 -> Zoltrix TV-Max [a1a0:a0fc]
17card=16 - Prolink Pixelview PlayTV (bt878) 17 16 -> Prolink Pixelview PlayTV (bt878)
18card=17 - Leadtek WinView 601 18 17 -> Leadtek WinView 601
19card=18 - AVEC Intercapture 19 18 -> AVEC Intercapture
20card=19 - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) 20 19 -> Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
21card=20 - CEI Raffles Card 21 20 -> CEI Raffles Card
22card=21 - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 22 21 -> Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
23card=22 - Askey CPH050/ Phoebe Tv Master + FM 23 22 -> Askey CPH050/ Phoebe Tv Master + FM [14ff:3002]
24card=23 - Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 24 23 -> Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 [14c7:0101]
25card=24 - Askey CPH05X/06X (bt878) [many vendors] 25 24 -> Askey CPH05X/06X (bt878) [many vendors] [144f:3002,144f:3005,144f:5000,14ff:3000]
26card=25 - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar 26 25 -> Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar
27card=26 - Hauppauge WinCam newer (bt878) 27 26 -> Hauppauge WinCam newer (bt878)
28card=27 - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 28 27 -> Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
29card=28 - Terratec TerraTV+ Version 1.1 (bt878) 29 28 -> Terratec TerraTV+ Version 1.1 (bt878) [153b:1127,1852:1852]
30card=29 - Imagenation PXC200 30 29 -> Imagenation PXC200 [1295:200a]
31card=30 - Lifeview FlyVideo 98 LR50 31 30 -> Lifeview FlyVideo 98 LR50 [1f7f:1850]
32card=31 - Formac iProTV, Formac ProTV I (bt848) 32 31 -> Formac iProTV, Formac ProTV I (bt848)
33card=32 - Intel Create and Share PCI/ Smart Video Recorder III 33 32 -> Intel Create and Share PCI/ Smart Video Recorder III
34card=33 - Terratec TerraTValue Version Bt878 34 33 -> Terratec TerraTValue Version Bt878 [153b:1117,153b:1118,153b:1119,153b:111a,153b:1134,153b:5018]
35card=34 - Leadtek WinFast 2000/ WinFast 2000 XP 35 34 -> Leadtek WinFast 2000/ WinFast 2000 XP [107d:6606,107d:6609,6606:217d,f6ff:fff6]
36card=35 - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II 36 35 -> Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II [1851:1850,1851:a050]
37card=36 - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner 37 36 -> Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner [1852:1852]
38card=37 - Prolink PixelView PlayTV pro 38 37 -> Prolink PixelView PlayTV pro
39card=38 - Askey CPH06X TView99 39 38 -> Askey CPH06X TView99 [144f:3000,144f:a005,a04f:a0fc]
40card=39 - Pinnacle PCTV Studio/Rave 40 39 -> Pinnacle PCTV Studio/Rave [11bd:0012,bd11:1200,bd11:ff00,11bd:ff12]
41card=40 - STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 41 40 -> STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 [10b4:2636,10b4:2645,121a:3060]
42card=41 - AVerMedia TVPhone 98 42 41 -> AVerMedia TVPhone 98 [1461:0001,1461:0003]
43card=42 - ProVideo PV951 43 42 -> ProVideo PV951 [aa0c:146c]
44card=43 - Little OnAir TV 44 43 -> Little OnAir TV
45card=44 - Sigma TVII-FM 45 44 -> Sigma TVII-FM
46card=45 - MATRIX-Vision MV-Delta 2 46 45 -> MATRIX-Vision MV-Delta 2
47card=46 - Zoltrix Genie TV/FM 47 46 -> Zoltrix Genie TV/FM [15b0:4000,15b0:400a,15b0:400d,15b0:4010,15b0:4016]
48card=47 - Terratec TV/Radio+ 48 47 -> Terratec TV/Radio+ [153b:1123]
49card=48 - Askey CPH03x/ Dynalink Magic TView 49 48 -> Askey CPH03x/ Dynalink Magic TView
50card=49 - IODATA GV-BCTV3/PCI 50 49 -> IODATA GV-BCTV3/PCI [10fc:4020]
51card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP 51 50 -> Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
52card=51 - Eagle Wireless Capricorn2 (bt878A) 52 51 -> Eagle Wireless Capricorn2 (bt878A)
53card=52 - Pinnacle PCTV Studio Pro 53 52 -> Pinnacle PCTV Studio Pro
54card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS 54 53 -> Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
55card=54 - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] 55 54 -> Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
56card=55 - Askey CPH031/ BESTBUY Easy TV 56 55 -> Askey CPH031/ BESTBUY Easy TV
57card=56 - Lifeview FlyVideo 98FM LR50 57 56 -> Lifeview FlyVideo 98FM LR50 [a051:41a0]
58card=57 - GrandTec 'Grand Video Capture' (Bt848) 58 57 -> GrandTec 'Grand Video Capture' (Bt848) [4344:4142]
59card=58 - Askey CPH060/ Phoebe TV Master Only (No FM) 59 58 -> Askey CPH060/ Phoebe TV Master Only (No FM)
60card=59 - Askey CPH03x TV Capturer 60 59 -> Askey CPH03x TV Capturer
61card=60 - Modular Technology MM100PCTV 61 60 -> Modular Technology MM100PCTV
62card=61 - AG Electronics GMV1 62 61 -> AG Electronics GMV1 [15cb:0101]
63card=62 - Askey CPH061/ BESTBUY Easy TV (bt878) 63 62 -> Askey CPH061/ BESTBUY Easy TV (bt878)
64card=63 - ATI TV-Wonder 64 63 -> ATI TV-Wonder [1002:0001]
65card=64 - ATI TV-Wonder VE 65 64 -> ATI TV-Wonder VE [1002:0003]
66card=65 - Lifeview FlyVideo 2000S LR90 66 65 -> Lifeview FlyVideo 2000S LR90
67card=66 - Terratec TValueRadio 67 66 -> Terratec TValueRadio [153b:1135,153b:ff3b]
68card=67 - IODATA GV-BCTV4/PCI 68 67 -> IODATA GV-BCTV4/PCI [10fc:4050]
69card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA) 69 68 -> 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA) [121a:3000,10b4:2637]
70card=69 - Active Imaging AIMMS 70 69 -> Active Imaging AIMMS
71card=70 - Prolink Pixelview PV-BT878P+ (Rev.4C,8E) 71 70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E)
72card=71 - Lifeview FlyVideo 98EZ (capture only) LR51 72 71 -> Lifeview FlyVideo 98EZ (capture only) LR51 [1851:1851]
73card=72 - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) 73 72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011]
74card=73 - Sensoray 311 74 73 -> Sensoray 311 [6000:0311]
75card=74 - RemoteVision MX (RV605) 75 74 -> RemoteVision MX (RV605)
76card=75 - Powercolor MTV878/ MTV878R/ MTV878F 76 75 -> Powercolor MTV878/ MTV878R/ MTV878F
77card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) 77 76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079]
78card=77 - GrandTec Multi Capture Card (Bt878) 78 77 -> GrandTec Multi Capture Card (Bt878)
79card=78 - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF 79 78 -> Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF [0a01:17de]
80card=79 - DSP Design TCVIDEO 80 79 -> DSP Design TCVIDEO
81card=80 - Hauppauge WinTV PVR 81 80 -> Hauppauge WinTV PVR [0070:4500]
82card=81 - IODATA GV-BCTV5/PCI 82 81 -> IODATA GV-BCTV5/PCI [10fc:4070,10fc:d018]
83card=82 - Osprey 100/150 (878) 83 82 -> Osprey 100/150 (878) [0070:ff00]
84card=83 - Osprey 100/150 (848) 84 83 -> Osprey 100/150 (848)
85card=84 - Osprey 101 (848) 85 84 -> Osprey 101 (848)
86card=85 - Osprey 101/151 86 85 -> Osprey 101/151
87card=86 - Osprey 101/151 w/ svid 87 86 -> Osprey 101/151 w/ svid
88card=87 - Osprey 200/201/250/251 88 87 -> Osprey 200/201/250/251
89card=88 - Osprey 200/250 89 88 -> Osprey 200/250 [0070:ff01]
90card=89 - Osprey 210/220 90 89 -> Osprey 210/220
91card=90 - Osprey 500 91 90 -> Osprey 500 [0070:ff02]
92card=91 - Osprey 540 92 91 -> Osprey 540 [0070:ff04]
93card=92 - Osprey 2000 93 92 -> Osprey 2000 [0070:ff03]
94card=93 - IDS Eagle 94 93 -> IDS Eagle
95card=94 - Pinnacle PCTV Sat 95 94 -> Pinnacle PCTV Sat [11bd:001c]
96card=95 - Formac ProTV II (bt878) 96 95 -> Formac ProTV II (bt878)
97card=96 - MachTV 97 96 -> MachTV
98card=97 - Euresys Picolo 98 97 -> Euresys Picolo
99card=98 - ProVideo PV150 99 98 -> ProVideo PV150 [aa00:1460,aa01:1461,aa02:1462,aa03:1463,aa04:1464,aa05:1465,aa06:1466,aa07:1467]
100card=99 - AD-TVK503 100 99 -> AD-TVK503
101card=100 - Hercules Smart TV Stereo 101100 -> Hercules Smart TV Stereo
102card=101 - Pace TV & Radio Card 102101 -> Pace TV & Radio Card
103card=102 - IVC-200 103102 -> IVC-200 [0000:a155,0001:a155,0002:a155,0003:a155,0100:a155,0101:a155,0102:a155,0103:a155]
104card=103 - Grand X-Guard / Trust 814PCI 104103 -> Grand X-Guard / Trust 814PCI [0304:0102]
105card=104 - Nebula Electronics DigiTV 105104 -> Nebula Electronics DigiTV [0071:0101]
106card=105 - ProVideo PV143 106105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433]
107card=106 - PHYTEC VD-009-X1 MiniDIN (bt878) 107106 -> PHYTEC VD-009-X1 MiniDIN (bt878)
108card=107 - PHYTEC VD-009-X1 Combi (bt878) 108107 -> PHYTEC VD-009-X1 Combi (bt878)
109card=108 - PHYTEC VD-009 MiniDIN (bt878) 109108 -> PHYTEC VD-009 MiniDIN (bt878)
110card=109 - PHYTEC VD-009 Combi (bt878) 110109 -> PHYTEC VD-009 Combi (bt878)
111card=110 - IVC-100 111110 -> IVC-100 [ff00:a132]
112card=111 - IVC-120G 112111 -> IVC-120G [ff00:a182,ff01:a182,ff02:a182,ff03:a182,ff04:a182,ff05:a182,ff06:a182,ff07:a182,ff08:a182,ff09:a182,ff0a:a182,ff0b:a182,ff0c:a182,ff0d:a182,ff0e:a182,ff0f:a182]
113card=112 - pcHDTV HD-2000 TV 113112 -> pcHDTV HD-2000 TV [7063:2000]
114card=113 - Twinhan DST + clones 114113 -> Twinhan DST + clones [11bd:0026,1822:0001,270f:fc00]
115card=114 - Winfast VC100 115114 -> Winfast VC100 [107d:6607]
116card=115 - Teppro TEV-560/InterVision IV-560 116115 -> Teppro TEV-560/InterVision IV-560
117card=116 - SIMUS GVC1100 117116 -> SIMUS GVC1100 [aa6a:82b2]
118card=117 - NGS NGSTV+ 118117 -> NGS NGSTV+
119card=118 - LMLBT4 119118 -> LMLBT4
120card=119 - Tekram M205 PRO 120119 -> Tekram M205 PRO
121card=120 - Conceptronic CONTVFMi 121120 -> Conceptronic CONTVFMi
122card=121 - Euresys Picolo Tetra 122121 -> Euresys Picolo Tetra [1805:0105,1805:0106,1805:0107,1805:0108]
123card=122 - Spirit TV Tuner 123122 -> Spirit TV Tuner
124card=123 - AVerMedia AVerTV DVB-T 771 124123 -> AVerMedia AVerTV DVB-T 771 [1461:0771]
125card=124 - AverMedia AverTV DVB-T 761 125124 -> AverMedia AverTV DVB-T 761 [1461:0761]
126card=125 - MATRIX Vision Sigma-SQ 126125 -> MATRIX Vision Sigma-SQ
127card=126 - MATRIX Vision Sigma-SLC 127126 -> MATRIX Vision Sigma-SLC
128card=127 - APAC Viewcomp 878(AMAX) 128127 -> APAC Viewcomp 878(AMAX)
129card=128 - DViCO FusionHDTV DVB-T Lite 129128 -> DViCO FusionHDTV DVB-T Lite [18ac:db10]
130card=129 - V-Gear MyVCD 130129 -> V-Gear MyVCD
131card=130 - Super TV Tuner 131130 -> Super TV Tuner
132card=131 - Tibet Systems 'Progress DVR' CS16 132131 -> Tibet Systems 'Progress DVR' CS16
133card=132 - Kodicom 4400R (master) 133132 -> Kodicom 4400R (master)
134card=133 - Kodicom 4400R (slave) 134133 -> Kodicom 4400R (slave)
135card=134 - Adlink RTV24 135134 -> Adlink RTV24
136card=135 - DViCO FusionHDTV 5 Lite 136135 -> DViCO FusionHDTV 5 Lite [18ac:d500]
137card=136 - Acorp Y878F 137136 -> Acorp Y878F [9511:1540]
138137 -> Conceptronic CTVFMi v2
139138 -> Prolink Pixelview PV-BT878P+ (Rev.2E)
140139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
141140 -> Osprey 440 [0070:ff07]
142141 -> Asound Skyeye PCTV
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 03deb0726aa4..a1017d1a85d4 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -1,32 +1,37 @@
1card=0 - UNKNOWN/GENERIC 1 0 -> UNKNOWN/GENERIC
2card=1 - Hauppauge WinTV 34xxx models 2 1 -> Hauppauge WinTV 34xxx models [0070:3400,0070:3401]
3card=2 - GDI Black Gold 3 2 -> GDI Black Gold [14c7:0106,14c7:0107]
4card=3 - PixelView 4 3 -> PixelView [1554:4811]
5card=4 - ATI TV Wonder Pro 5 4 -> ATI TV Wonder Pro [1002:00f8]
6card=5 - Leadtek Winfast 2000XP Expert 6 5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613]
7card=6 - AverTV Studio 303 (M126) 7 6 -> AverTV Studio 303 (M126) [1461:000b]
8card=7 - MSI TV-@nywhere Master 8 7 -> MSI TV-@nywhere Master [1462:8606]
9card=8 - Leadtek Winfast DV2000 9 8 -> Leadtek Winfast DV2000 [107d:6620]
10card=9 - Leadtek PVR 2000 10 9 -> Leadtek PVR 2000 [107d:663b,107d:663C]
11card=10 - IODATA GV-VCP3/PCI 11 10 -> IODATA GV-VCP3/PCI [10fc:d003]
12card=11 - Prolink PlayTV PVR 12 11 -> Prolink PlayTV PVR
13card=12 - ASUS PVR-416 13 12 -> ASUS PVR-416 [1043:4823]
14card=13 - MSI TV-@nywhere 14 13 -> MSI TV-@nywhere
15card=14 - KWorld/VStream XPert DVB-T 15 14 -> KWorld/VStream XPert DVB-T [17de:08a6]
16card=15 - DViCO FusionHDTV DVB-T1 16 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00]
17card=16 - KWorld LTV883RF 17 16 -> KWorld LTV883RF
18card=17 - DViCO FusionHDTV 3 Gold-Q 18 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810]
19card=18 - Hauppauge Nova-T DVB-T 19 18 -> Hauppauge Nova-T DVB-T [0070:9002]
20card=19 - Conexant DVB-T reference design 20 19 -> Conexant DVB-T reference design [14f1:0187]
21card=20 - Provideo PV259 21 20 -> Provideo PV259 [1540:2580]
22card=21 - DViCO FusionHDTV DVB-T Plus 22 21 -> DViCO FusionHDTV DVB-T Plus [18ac:db10]
23card=22 - digitalnow DNTV Live! DVB-T 23 22 -> pcHDTV HD3000 HDTV [7063:3000]
24card=23 - pcHDTV HD3000 HDTV 24 23 -> digitalnow DNTV Live! DVB-T [17de:a8a6]
25card=24 - Hauppauge WinTV 28xxx (Roslyn) models 25 24 -> Hauppauge WinTV 28xxx (Roslyn) models [0070:2801]
26card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC) 26 25 -> Digital-Logic MICROSPACE Entertainment Center (MEC) [14f1:0342]
27card=26 - IODATA GV/BCTV7E 27 26 -> IODATA GV/BCTV7E [10fc:d035]
28card=27 - PixelView PlayTV Ultra Pro (Stereo) 28 27 -> PixelView PlayTV Ultra Pro (Stereo)
29card=28 - DViCO FusionHDTV 3 Gold-T 29 28 -> DViCO FusionHDTV 3 Gold-T [18ac:d820]
30card=29 - ADS Tech Instant TV DVB-T PCI 30 29 -> ADS Tech Instant TV DVB-T PCI [1421:0334]
31card=30 - TerraTec Cinergy 1400 DVB-T 31 30 -> TerraTec Cinergy 1400 DVB-T [153b:1166]
32card=31 - DViCO FusionHDTV 5 Gold 32 31 -> DViCO FusionHDTV 5 Gold [18ac:d500]
33 32 -> AverMedia UltraTV Media Center PCI 550 [1461:8011]
34 33 -> Kworld V-Stream Xpert DVD
35 34 -> ATI HDTV Wonder [1002:a101]
36 35 -> WinFast DTV1000-T [107d:665f]
37 36 -> AVerTV 303 (M126) [1461:000a]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
new file mode 100644
index 000000000000..a0c7cad20971
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -0,0 +1,10 @@
1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
2 1 -> Unknown EM2820/2840 video grabber (em2820/em2840)
3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200]
6 5 -> MSI VOX USB 2.0 (em2820/em2840) [eb1a:2820]
7 6 -> Terratec Cinergy 200 USB (em2800)
8 7 -> Leadtek Winfast USB II (em2800)
9 8 -> Kworld USB2800 (em2800)
10 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index dc57225f39be..57c9d631db56 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -6,10 +6,10 @@
6 5 -> SKNet Monster TV [1131:4e85] 6 5 -> SKNet Monster TV [1131:4e85]
7 6 -> Tevion MD 9717 7 6 -> Tevion MD 9717
8 7 -> KNC One TV-Station RDS / Typhoon TV Tuner RDS [1131:fe01,1894:fe01] 8 7 -> KNC One TV-Station RDS / Typhoon TV Tuner RDS [1131:fe01,1894:fe01]
9 8 -> Terratec Cinergy 400 TV [153B:1142] 9 8 -> Terratec Cinergy 400 TV [153b:1142]
10 9 -> Medion 5044 10 9 -> Medion 5044
11 10 -> Kworld/KuroutoShikou SAA7130-TVPCI 11 10 -> Kworld/KuroutoShikou SAA7130-TVPCI
12 11 -> Terratec Cinergy 600 TV [153B:1143] 12 11 -> Terratec Cinergy 600 TV [153b:1143]
13 12 -> Medion 7134 [16be:0003] 13 12 -> Medion 7134 [16be:0003]
14 13 -> Typhoon TV+Radio 90031 14 13 -> Typhoon TV+Radio 90031
15 14 -> ELSA EX-VISION 300TV [1048:226b] 15 14 -> ELSA EX-VISION 300TV [1048:226b]
@@ -36,8 +36,8 @@
36 35 -> AverMedia AverTV Studio 305 [1461:2115] 36 35 -> AverMedia AverTV Studio 305 [1461:2115]
37 36 -> UPMOST PURPLE TV [12ab:0800] 37 36 -> UPMOST PURPLE TV [12ab:0800]
38 37 -> Items MuchTV Plus / IT-005 38 37 -> Items MuchTV Plus / IT-005
39 38 -> Terratec Cinergy 200 TV [153B:1152] 39 38 -> Terratec Cinergy 200 TV [153b:1152]
40 39 -> LifeView FlyTV Platinum Mini [5168:0212] 40 39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212]
41 40 -> Compro VideoMate TV PVR/FM [185b:c100] 41 40 -> Compro VideoMate TV PVR/FM [185b:c100]
42 41 -> Compro VideoMate TV Gold+ [185b:c100] 42 41 -> Compro VideoMate TV Gold+ [185b:c100]
43 42 -> Sabrent SBT-TVFM (saa7130) 43 42 -> Sabrent SBT-TVFM (saa7130)
@@ -46,7 +46,7 @@
46 45 -> Avermedia AVerTV Studio 307 [1461:9715] 46 45 -> Avermedia AVerTV Studio 307 [1461:9715]
47 46 -> AVerMedia Cardbus TV/Radio (E500) [1461:d6ee] 47 46 -> AVerMedia Cardbus TV/Radio (E500) [1461:d6ee]
48 47 -> Terratec Cinergy 400 mobile [153b:1162] 48 47 -> Terratec Cinergy 400 mobile [153b:1162]
49 48 -> Terratec Cinergy 600 TV MK3 [153B:1158] 49 48 -> Terratec Cinergy 600 TV MK3 [153b:1158]
50 49 -> Compro VideoMate Gold+ Pal [185b:c200] 50 49 -> Compro VideoMate Gold+ Pal [185b:c200]
51 50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d] 51 50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d]
52 51 -> ProVideo PV952 [1540:9524] 52 51 -> ProVideo PV952 [1540:9524]
@@ -56,12 +56,27 @@
56 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306] 56 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306]
57 56 -> Avermedia AVerTV 307 [1461:a70a] 57 56 -> Avermedia AVerTV 307 [1461:a70a]
58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370] 59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370,1421:1370]
60 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 60 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
61 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502] 61 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
62 61 -> Philips TOUGH DVB-T reference design [1131:2004] 62 61 -> Philips TOUGH DVB-T reference design [1131:2004]
63 62 -> Compro VideoMate TV Gold+II 63 62 -> Compro VideoMate TV Gold+II
64 63 -> Kworld Xpert TV PVR7134 64 63 -> Kworld Xpert TV PVR7134
65 64 -> FlyTV mini Asus Digimatrix [1043:0210,1043:0210] 65 64 -> FlyTV mini Asus Digimatrix [1043:0210]
66 65 -> V-Stream Studio TV Terminator 66 65 -> V-Stream Studio TV Terminator
67 66 -> Yuan TUN-900 (saa7135) 67 66 -> Yuan TUN-900 (saa7135)
68 67 -> Beholder BeholdTV 409 FM [0000:4091]
69 68 -> GoTView 7135 PCI [5456:7135]
70 69 -> Philips EUROPA V3 reference design [1131:2004]
71 70 -> Compro Videomate DVB-T300 [185b:c900]
72 71 -> Compro Videomate DVB-T200 [185b:c901]
73 72 -> RTD Embedded Technologies VFG7350 [1435:7350]
74 73 -> RTD Embedded Technologies VFG7330 [1435:7330]
75 74 -> LifeView FlyTV Platinum Mini2 [14c0:1212]
76 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044]
77 76 -> SKNet MonsterTV Mobile [1131:4ee9]
78 77 -> Pinnacle PCTV 110i (saa7133) [11bd:002e]
79 78 -> ASUSTeK P7131 Dual [1043:4862]
80 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
81 80 -> ASUS Digimatrix TV [1043:0210]
82 81 -> Philips Tiger reference design [1131:2018]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index f5876be658a6..ec840ca6f455 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -53,7 +53,7 @@ tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
53tuner=52 - Thomson DDT 7610 (ATSC/NTSC) 53tuner=52 - Thomson DDT 7610 (ATSC/NTSC)
54tuner=53 - Philips FQ1286 54tuner=53 - Philips FQ1286
55tuner=54 - tda8290+75 55tuner=54 - tda8290+75
56tuner=55 - LG PAL (TAPE series) 56tuner=55 - TCL 2002MB
57tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4) 57tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
58tuner=57 - Philips FQ1236A MK4 58tuner=57 - Philips FQ1236A MK4
59tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF 59tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF
@@ -65,3 +65,5 @@ tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
65tuner=64 - LG TDVS-H062F/TUA6034 65tuner=64 - LG TDVS-H062F/TUA6034
66tuner=65 - Ymec TVF66T5-B/DFF 66tuner=65 - Ymec TVF66T5-B/DFF
67tuner=66 - LG NTSC (TALN mini series) 67tuner=66 - LG NTSC (TALN mini series)
68tuner=67 - Philips TD1316 Hybrid Tuner
69tuner=68 - Philips TUV1236D ATSC/NTSC dual in
diff --git a/Documentation/video4linux/README.cx88 b/Documentation/video4linux/README.cx88
index 897ab834839a..06a33a4f52fd 100644
--- a/Documentation/video4linux/README.cx88
+++ b/Documentation/video4linux/README.cx88
@@ -17,9 +17,9 @@ audio
17 - The chip specs for the on-chip TV sound decoder are next 17 - The chip specs for the on-chip TV sound decoder are next
18 to useless :-/ 18 to useless :-/
19 - Neverless the builtin TV sound decoder starts working now, 19 - Neverless the builtin TV sound decoder starts working now,
20 at least for PAL-BG. Other TV norms need other code ... 20 at least for PAL-BG. Other TV norms need other code ...
21 FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE 21 FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE
22 USING. 22 USING.
23 - Most tuner chips do provide mono sound, which may or may not 23 - Most tuner chips do provide mono sound, which may or may not
24 be useable depending on the board design. With the Hauppauge 24 be useable depending on the board design. With the Hauppauge
25 cards it works, so there is mono sound available as fallback. 25 cards it works, so there is mono sound available as fallback.
@@ -65,5 +65,5 @@ Have fun,
65 65
66 Gerd 66 Gerd
67 67
68-- 68--
69Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 69Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134
index 1f788e498eff..b911f0871874 100644
--- a/Documentation/video4linux/README.saa7134
+++ b/Documentation/video4linux/README.saa7134
@@ -78,5 +78,5 @@ Have fun,
78 78
79 Gerd 79 Gerd
80 80
81-- 81--
82Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 82Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
index 8f1941ede4da..d3389655ad96 100644
--- a/Documentation/video4linux/bttv/Cards
+++ b/Documentation/video4linux/bttv/Cards
@@ -149,11 +149,11 @@ Lifeview Flyvideo Series:
149 2) There is a print on the PCB: 149 2) There is a print on the PCB:
150 LR25 = Flyvideo (Zoran ZR36120, SAA7110A) 150 LR25 = Flyvideo (Zoran ZR36120, SAA7110A)
151 LR26 Rev.N = Flyvideo II (Bt848) 151 LR26 Rev.N = Flyvideo II (Bt848)
152 Rev.O = Flyvideo II (Bt878) 152 Rev.O = Flyvideo II (Bt878)
153 LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110) 153 LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110)
154 LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only) 154 LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only)
155 LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID) 155 LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
156 Rev.W = Flyvideo 98 (no eeprom) 156 Rev.W = Flyvideo 98 (no eeprom)
157 LR51 Rev.E = Flyvideo 98 EZ (capture only) 157 LR51 Rev.E = Flyvideo 98 EZ (capture only)
158 LR90 = Flyvideo 2000 (Bt878) 158 LR90 = Flyvideo 2000 (Bt878)
159 Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard) 159 Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
@@ -163,7 +163,7 @@ Lifeview Flyvideo Series:
163 LR136 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134) 163 LR136 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
164 LR137 = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394) 164 LR137 = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
165 LR138 Rev.C= Flyvideo 2000 (SAA7130) 165 LR138 Rev.C= Flyvideo 2000 (SAA7130)
166 or Flyvideo 3000 (SAA7134) w/Stereo TV 166 or Flyvideo 3000 (SAA7134) w/Stereo TV
167 These exist in variations w/FM and w/Remote sometimes denoted 167 These exist in variations w/FM and w/Remote sometimes denoted
168 by suffixes "FM" and "R". 168 by suffixes "FM" and "R".
169 3) You have a laptop (miniPCI card): 169 3) You have a laptop (miniPCI card):
@@ -197,7 +197,7 @@ Typhoon TV card series:
197 50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B) 197 50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B)
198 50681 "TV Tuner PCI Pal I" (variant of 50680) 198 50681 "TV Tuner PCI Pal I" (variant of 50680)
199 50682 "TView TV/FM Tuner Pal BG" = Flyvideo 98FM (LR50 Rev.Q) 199 50682 "TView TV/FM Tuner Pal BG" = Flyvideo 98FM (LR50 Rev.Q)
200 Note: The package has a picture of CPH05x (which would be a real TView) 200 Note: The package has a picture of CPH05x (which would be a real TView)
201 50683 "TV Tuner PCI SECAM" (variant of 50680) 201 50683 "TV Tuner PCI SECAM" (variant of 50680)
202 50684 "TV Tuner Pal BG" = Pixelview 878TV(Rev.3D) 202 50684 "TV Tuner Pal BG" = Pixelview 878TV(Rev.3D)
203 50686 "TV Tuner" = KNC1 TV Station 203 50686 "TV Tuner" = KNC1 TV Station
@@ -418,9 +418,9 @@ Lifetec/Medion/Tevion/Aldi
418-------------------------- 418--------------------------
419 LT9306/MD9306 = CPH061 419 LT9306/MD9306 = CPH061
420 LT9415/MD9415 = LR90 Rev.F or Rev.G 420 LT9415/MD9415 = LR90 Rev.F or Rev.G
421 MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H) 421 MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
422 MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner) 422 MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner)
423 MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner) 423 MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner)
424 424
425Modular Technologies (www.modulartech.com) UK 425Modular Technologies (www.modulartech.com) UK
426--------------------------------------------- 426---------------------------------------------
@@ -453,10 +453,10 @@ Technisat
453 Discos ADR PC-Karte ISA (no TV!) 453 Discos ADR PC-Karte ISA (no TV!)
454 Discos ADR PC-Karte PCI (probably no TV?) 454 Discos ADR PC-Karte PCI (probably no TV?)
455 Techni-PC-Sat (Sat. analog) 455 Techni-PC-Sat (Sat. analog)
456 Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A) 456 Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
457 Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio) 457 Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
458 Mediafocus II (saa7146, Sat. analog) 458 Mediafocus II (saa7146, Sat. analog)
459 SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A) 459 SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
460 SkyStar 1 DVB (AV7110) = Technotrend Premium 460 SkyStar 1 DVB (AV7110) = Technotrend Premium
461 SkyStar 2 DVB (B2C2) (=Sky2PC) 461 SkyStar 2 DVB (B2C2) (=Sky2PC)
462 462
diff --git a/Documentation/video4linux/bttv/README b/Documentation/video4linux/bttv/README
index a72f4c94fb0b..7ca2154c2bf5 100644
--- a/Documentation/video4linux/bttv/README
+++ b/Documentation/video4linux/bttv/README
@@ -42,9 +42,9 @@ bttv uses the PCI Subsystem ID to autodetect the card type. lspci lists
42the Subsystem ID in the second line, looks like this: 42the Subsystem ID in the second line, looks like this:
43 43
4400:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02) 4400:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
45 Subsystem: Hauppauge computer works Inc. WinTV/GO 45 Subsystem: Hauppauge computer works Inc. WinTV/GO
46 Flags: bus master, medium devsel, latency 32, IRQ 5 46 Flags: bus master, medium devsel, latency 32, IRQ 5
47 Memory at e2000000 (32-bit, prefetchable) [size=4K] 47 Memory at e2000000 (32-bit, prefetchable) [size=4K]
48 48
49only bt878-based cards can have a subsystem ID (which does not mean 49only bt878-based cards can have a subsystem ID (which does not mean
50that every card really has one). bt848 cards can't have a Subsystem 50that every card really has one). bt848 cards can't have a Subsystem
diff --git a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ
index b8c9c2605ce2..1e6328f91083 100644
--- a/Documentation/video4linux/bttv/Sound-FAQ
+++ b/Documentation/video4linux/bttv/Sound-FAQ
@@ -61,8 +61,8 @@ line for your board. The important fields are these two:
61struct tvcard 61struct tvcard
62{ 62{
63 [ ... ] 63 [ ... ]
64 u32 gpiomask; 64 u32 gpiomask;
65 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ 65 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
66}; 66};
67 67
68gpiomask specifies which pins are used to control the audio mux chip. 68gpiomask specifies which pins are used to control the audio mux chip.
@@ -126,11 +126,11 @@ muxsel - video mux, input->registervalue mapping
126pll - same as pll= insmod option 126pll - same as pll= insmod option
127tuner_type - same as tuner= insmod option 127tuner_type - same as tuner= insmod option
128*_modulename - hint whenever some card needs this or that audio 128*_modulename - hint whenever some card needs this or that audio
129 module loaded to work properly. 129 module loaded to work properly.
130has_radio - whenever this TV card has a radio tuner. 130has_radio - whenever this TV card has a radio tuner.
131no_msp34xx - "1" disables loading of msp3400.o module 131no_msp34xx - "1" disables loading of msp3400.o module
132no_tda9875 - "1" disables loading of tda9875.o module 132no_tda9875 - "1" disables loading of tda9875.o module
133needs_tvaudio - set to "1" to load tvaudio.o module 133needs_tvaudio - set to "1" to load tvaudio.o module
134 134
135If some config item is specified both from the tvcards array and as 135If some config item is specified both from the tvcards array and as
136insmod option, the insmod option takes precedence. 136insmod option, the insmod option takes precedence.
@@ -144,5 +144,5 @@ Good luck,
144 144
145PS: If you have a new working entry, mail it to me. 145PS: If you have a new working entry, mail it to me.
146 146
147-- 147--
148Gerd Knorr <kraxel@bytesex.org> 148Gerd Knorr <kraxel@bytesex.org>
diff --git a/Documentation/video4linux/bttv/Tuners b/Documentation/video4linux/bttv/Tuners
index d18fbc70c0e0..0a371d349542 100644
--- a/Documentation/video4linux/bttv/Tuners
+++ b/Documentation/video4linux/bttv/Tuners
@@ -21,7 +21,7 @@ SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
21 J= NTSC-Japan 21 J= NTSC-Japan
22 L= Secam LL 22 L= Secam LL
23 M= BG+I+DK 23 M= BG+I+DK
24 N= NTSC 24 N= NTSC
25 Q= BG+I+DK+LL 25 Q= BG+I+DK+LL
26 [89]: ? 26 [89]: ?
27 [125]: 27 [125]:
@@ -96,7 +96,7 @@ LG Innotek Tuner:
96 TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69) 96 TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
97 TADC-M201D: PAL D/K+B/G+I (L,143/425) (sound control at I2C address 0xc8) 97 TADC-M201D: PAL D/K+B/G+I (L,143/425) (sound control at I2C address 0xc8)
98 TADC-T003F: NTSC Taiwan (L,175/410?; 2-B, C-W+11, W+12-69) 98 TADC-T003F: NTSC Taiwan (L,175/410?; 2-B, C-W+11, W+12-69)
99 Suffix: 99 Suffix:
100 P= Standard phono female socket 100 P= Standard phono female socket
101 D= IEC female socket 101 D= IEC female socket
102 F= F-connector 102 F= F-connector
diff --git a/Documentation/video4linux/lifeview.txt b/Documentation/video4linux/lifeview.txt
index b07ea79c2b7e..05f9eb57aac9 100644
--- a/Documentation/video4linux/lifeview.txt
+++ b/Documentation/video4linux/lifeview.txt
@@ -10,33 +10,33 @@ bt878:
10------------------------------------------------------------------------------ 10------------------------------------------------------------------------------
11 11
12saa7134: 12saa7134:
13 /* LifeView FlyTV Platinum FM (LR214WF) */ 13 /* LifeView FlyTV Platinum FM (LR214WF) */
14 /* "Peter Missel <peter.missel@onlinehome.de> */ 14 /* "Peter Missel <peter.missel@onlinehome.de> */
15 .name = "LifeView FlyTV Platinum FM", 15 .name = "LifeView FlyTV Platinum FM",
16 /* GP27 MDT2005 PB4 pin 10 */ 16 /* GP27 MDT2005 PB4 pin 10 */
17 /* GP26 MDT2005 PB3 pin 9 */ 17 /* GP26 MDT2005 PB3 pin 9 */
18 /* GP25 MDT2005 PB2 pin 8 */ 18 /* GP25 MDT2005 PB2 pin 8 */
19 /* GP23 MDT2005 PB1 pin 7 */ 19 /* GP23 MDT2005 PB1 pin 7 */
20 /* GP22 MDT2005 PB0 pin 6 */ 20 /* GP22 MDT2005 PB0 pin 6 */
21 /* GP21 MDT2005 PB5 pin 11 */ 21 /* GP21 MDT2005 PB5 pin 11 */
22 /* GP20 MDT2005 PB6 pin 12 */ 22 /* GP20 MDT2005 PB6 pin 12 */
23 /* GP19 MDT2005 PB7 pin 13 */ 23 /* GP19 MDT2005 PB7 pin 13 */
24 /* nc MDT2005 PA3 pin 2 */ 24 /* nc MDT2005 PA3 pin 2 */
25 /* Remote MDT2005 PA2 pin 1 */ 25 /* Remote MDT2005 PA2 pin 1 */
26 /* GP18 MDT2005 PA1 pin 18 */ 26 /* GP18 MDT2005 PA1 pin 18 */
27 /* nc MDT2005 PA0 pin 17 strap low */ 27 /* nc MDT2005 PA0 pin 17 strap low */
28 28
29 /* GP17 Strap "GP7"=High */ 29 /* GP17 Strap "GP7"=High */
30 /* GP16 Strap "GP6"=High 30 /* GP16 Strap "GP6"=High
31 0=Radio 1=TV 31 0=Radio 1=TV
32 Drives SA630D ENCH1 and HEF4052 A1 pins 32 Drives SA630D ENCH1 and HEF4052 A1 pins
33 to do FM radio through SIF input */ 33 to do FM radio through SIF input */
34 /* GP15 nc */ 34 /* GP15 nc */
35 /* GP14 nc */ 35 /* GP14 nc */
36 /* GP13 nc */ 36 /* GP13 nc */
37 /* GP12 Strap "GP5" = High */ 37 /* GP12 Strap "GP5" = High */
38 /* GP11 Strap "GP4" = High */ 38 /* GP11 Strap "GP4" = High */
39 /* GP10 Strap "GP3" = High */ 39 /* GP10 Strap "GP3" = High */
40 /* GP09 Strap "GP2" = Low */ 40 /* GP09 Strap "GP2" = Low */
41 /* GP08 Strap "GP1" = Low */ 41 /* GP08 Strap "GP1" = Low */
42 /* GP07.00 nc */ 42 /* GP07.00 nc */
diff --git a/MAINTAINERS b/MAINTAINERS
index 995bfd8e6e7f..0b03a88e88be 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -707,7 +707,7 @@ DCCP PROTOCOL
707P: Arnaldo Carvalho de Melo 707P: Arnaldo Carvalho de Melo
708M: acme@mandriva.com 708M: acme@mandriva.com
709L: dccp@vger.kernel.org 709L: dccp@vger.kernel.org
710W: http://www.wlug.org.nz/DCCP 710W: http://linux-net.osdl.org/index.php/DCCP
711S: Maintained 711S: Maintained
712 712
713DECnet NETWORK LAYER 713DECnet NETWORK LAYER
@@ -1330,6 +1330,24 @@ M: john.ronciak@intel.com
1330W: http://sourceforge.net/projects/e1000/ 1330W: http://sourceforge.net/projects/e1000/
1331S: Supported 1331S: Supported
1332 1332
1333INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
1334P: Yi Zhu
1335M: yi.zhu@intel.com
1336P: James Ketrenos
1337M: jketreno@linux.intel.com
1338L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
1339W: http://ipw2100.sourceforge.net
1340S: Supported
1341
1342INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
1343P: Yi Zhu
1344M: yi.zhu@intel.com
1345P: James Ketrenos
1346M: jketreno@linux.intel.com
1347L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
1348W: http://ipw2200.sourceforge.net
1349S: Supported
1350
1333IOC3 DRIVER 1351IOC3 DRIVER
1334P: Ralf Baechle 1352P: Ralf Baechle
1335M: ralf@linux-mips.org 1353M: ralf@linux-mips.org
diff --git a/Makefile b/Makefile
index ea96da1572d5..6d1f727f4399 100644
--- a/Makefile
+++ b/Makefile
@@ -347,7 +347,7 @@ AFLAGS_KERNEL =
347# Needed to be compatible with the O= option 347# Needed to be compatible with the O= option
348LINUXINCLUDE := -Iinclude \ 348LINUXINCLUDE := -Iinclude \
349 $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ 349 $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
350 -imacros include/linux/autoconf.h 350 -include include/linux/autoconf.h
351 351
352CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) 352CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
353 353
@@ -407,7 +407,7 @@ outputmakefile:
407# of make so .config is not included in this case either (for *config). 407# of make so .config is not included in this case either (for *config).
408 408
409no-dot-config-targets := clean mrproper distclean \ 409no-dot-config-targets := clean mrproper distclean \
410 cscope TAGS tags help %docs check% 410 cscope TAGS tags help %docs check% kernelrelease
411 411
412config-targets := 0 412config-targets := 0
413mixed-targets := 0 413mixed-targets := 0
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index eb20c3afff58..a8682612abc0 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -43,21 +43,17 @@
43#include "proto.h" 43#include "proto.h"
44#include "pci_impl.h" 44#include "pci_impl.h"
45 45
46void default_idle(void)
47{
48 barrier();
49}
50
51void 46void
52cpu_idle(void) 47cpu_idle(void)
53{ 48{
49 set_thread_flag(TIF_POLLING_NRFLAG);
50
54 while (1) { 51 while (1) {
55 void (*idle)(void) = default_idle;
56 /* FIXME -- EV6 and LCA45 know how to power down 52 /* FIXME -- EV6 and LCA45 know how to power down
57 the CPU. */ 53 the CPU. */
58 54
59 while (!need_resched()) 55 while (!need_resched())
60 idle(); 56 cpu_relax();
61 schedule(); 57 schedule();
62 } 58 }
63} 59}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3bfef0934c9d..3df7cbd924a1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -239,6 +239,8 @@ source "arch/arm/plat-omap/Kconfig"
239 239
240source "arch/arm/mach-omap1/Kconfig" 240source "arch/arm/mach-omap1/Kconfig"
241 241
242source "arch/arm/mach-omap2/Kconfig"
243
242source "arch/arm/mach-s3c2410/Kconfig" 244source "arch/arm/mach-s3c2410/Kconfig"
243 245
244source "arch/arm/mach-lh7a40x/Kconfig" 246source "arch/arm/mach-lh7a40x/Kconfig"
@@ -358,7 +360,7 @@ config HOTPLUG_CPU
358 360
359config LOCAL_TIMERS 361config LOCAL_TIMERS
360 bool "Use local timer interrupts" 362 bool "Use local timer interrupts"
361 depends on SMP && n 363 depends on SMP && REALVIEW_MPCORE
362 default y 364 default y
363 help 365 help
364 Enable support for local timers on SMP platforms, rather then the 366 Enable support for local timers on SMP platforms, rather then the
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 114cda7f1b73..81bd2193fe6d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -93,6 +93,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
93 machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx 93 machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
94 machine-$(CONFIG_ARCH_IXP2000) := ixp2000 94 machine-$(CONFIG_ARCH_IXP2000) := ixp2000
95 machine-$(CONFIG_ARCH_OMAP1) := omap1 95 machine-$(CONFIG_ARCH_OMAP1) := omap1
96 machine-$(CONFIG_ARCH_OMAP2) := omap2
96 incdir-$(CONFIG_ARCH_OMAP) := omap 97 incdir-$(CONFIG_ARCH_OMAP) := omap
97 machine-$(CONFIG_ARCH_S3C2410) := s3c2410 98 machine-$(CONFIG_ARCH_S3C2410) := s3c2410
98 machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x 99 machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
index 4198677cd394..529f0f72e1e9 100644
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.13 3# Linux kernel version: 2.6.14
4# Mon Sep 5 18:07:12 2005 4# Wed Nov 9 18:53:40 2005
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -22,6 +22,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
22# General setup 22# General setup
23# 23#
24CONFIG_LOCALVERSION="" 24CONFIG_LOCALVERSION=""
25CONFIG_LOCALVERSION_AUTO=y
25CONFIG_SWAP=y 26CONFIG_SWAP=y
26CONFIG_SYSVIPC=y 27CONFIG_SYSVIPC=y
27# CONFIG_POSIX_MQUEUE is not set 28# CONFIG_POSIX_MQUEUE is not set
@@ -31,6 +32,7 @@ CONFIG_SYSCTL=y
31# CONFIG_HOTPLUG is not set 32# CONFIG_HOTPLUG is not set
32CONFIG_KOBJECT_UEVENT=y 33CONFIG_KOBJECT_UEVENT=y
33# CONFIG_IKCONFIG is not set 34# CONFIG_IKCONFIG is not set
35CONFIG_INITRAMFS_SOURCE=""
34# CONFIG_EMBEDDED is not set 36# CONFIG_EMBEDDED is not set
35CONFIG_KALLSYMS=y 37CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_EXTRA_PASS is not set 38# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -60,6 +62,23 @@ CONFIG_OBSOLETE_MODPARM=y
60# CONFIG_KMOD is not set 62# CONFIG_KMOD is not set
61 63
62# 64#
65# Block layer
66#
67
68#
69# IO Schedulers
70#
71CONFIG_IOSCHED_NOOP=y
72CONFIG_IOSCHED_AS=y
73CONFIG_IOSCHED_DEADLINE=y
74CONFIG_IOSCHED_CFQ=y
75CONFIG_DEFAULT_AS=y
76# CONFIG_DEFAULT_DEADLINE is not set
77# CONFIG_DEFAULT_CFQ is not set
78# CONFIG_DEFAULT_NOOP is not set
79CONFIG_DEFAULT_IOSCHED="anticipatory"
80
81#
63# System Type 82# System Type
64# 83#
65# CONFIG_ARCH_CLPS7500 is not set 84# CONFIG_ARCH_CLPS7500 is not set
@@ -81,6 +100,7 @@ CONFIG_OBSOLETE_MODPARM=y
81# CONFIG_ARCH_LH7A40X is not set 100# CONFIG_ARCH_LH7A40X is not set
82CONFIG_ARCH_OMAP=y 101CONFIG_ARCH_OMAP=y
83# CONFIG_ARCH_VERSATILE is not set 102# CONFIG_ARCH_VERSATILE is not set
103# CONFIG_ARCH_REALVIEW is not set
84# CONFIG_ARCH_IMX is not set 104# CONFIG_ARCH_IMX is not set
85# CONFIG_ARCH_H720X is not set 105# CONFIG_ARCH_H720X is not set
86# CONFIG_ARCH_AAEC2000 is not set 106# CONFIG_ARCH_AAEC2000 is not set
@@ -112,7 +132,7 @@ CONFIG_OMAP_SERIAL_WAKE=y
112# OMAP Core Type 132# OMAP Core Type
113# 133#
114# CONFIG_ARCH_OMAP730 is not set 134# CONFIG_ARCH_OMAP730 is not set
115# CONFIG_ARCH_OMAP1510 is not set 135# CONFIG_ARCH_OMAP15XX is not set
116CONFIG_ARCH_OMAP16XX=y 136CONFIG_ARCH_OMAP16XX=y
117 137
118# 138#
@@ -177,6 +197,8 @@ CONFIG_FLATMEM_MANUAL=y
177# CONFIG_SPARSEMEM_MANUAL is not set 197# CONFIG_SPARSEMEM_MANUAL is not set
178CONFIG_FLATMEM=y 198CONFIG_FLATMEM=y
179CONFIG_FLAT_NODE_MEM_MAP=y 199CONFIG_FLAT_NODE_MEM_MAP=y
200# CONFIG_SPARSEMEM_STATIC is not set
201CONFIG_SPLIT_PTLOCK_CPUS=4096
180# CONFIG_LEDS is not set 202# CONFIG_LEDS is not set
181CONFIG_ALIGNMENT_TRAP=y 203CONFIG_ALIGNMENT_TRAP=y
182 204
@@ -258,14 +280,19 @@ CONFIG_IP_PNP_BOOTP=y
258# CONFIG_INET_ESP is not set 280# CONFIG_INET_ESP is not set
259# CONFIG_INET_IPCOMP is not set 281# CONFIG_INET_IPCOMP is not set
260# CONFIG_INET_TUNNEL is not set 282# CONFIG_INET_TUNNEL is not set
261CONFIG_IP_TCPDIAG=y 283CONFIG_INET_DIAG=y
262# CONFIG_IP_TCPDIAG_IPV6 is not set 284CONFIG_INET_TCP_DIAG=y
263# CONFIG_TCP_CONG_ADVANCED is not set 285# CONFIG_TCP_CONG_ADVANCED is not set
264CONFIG_TCP_CONG_BIC=y 286CONFIG_TCP_CONG_BIC=y
265# CONFIG_IPV6 is not set 287# CONFIG_IPV6 is not set
266# CONFIG_NETFILTER is not set 288# CONFIG_NETFILTER is not set
267 289
268# 290#
291# DCCP Configuration (EXPERIMENTAL)
292#
293# CONFIG_IP_DCCP is not set
294
295#
269# SCTP Configuration (EXPERIMENTAL) 296# SCTP Configuration (EXPERIMENTAL)
270# 297#
271# CONFIG_IP_SCTP is not set 298# CONFIG_IP_SCTP is not set
@@ -281,6 +308,10 @@ CONFIG_TCP_CONG_BIC=y
281# CONFIG_NET_DIVERT is not set 308# CONFIG_NET_DIVERT is not set
282# CONFIG_ECONET is not set 309# CONFIG_ECONET is not set
283# CONFIG_WAN_ROUTER is not set 310# CONFIG_WAN_ROUTER is not set
311
312#
313# QoS and/or fair queueing
314#
284# CONFIG_NET_SCHED is not set 315# CONFIG_NET_SCHED is not set
285# CONFIG_NET_CLS_ROUTE is not set 316# CONFIG_NET_CLS_ROUTE is not set
286 317
@@ -291,6 +322,7 @@ CONFIG_TCP_CONG_BIC=y
291# CONFIG_HAMRADIO is not set 322# CONFIG_HAMRADIO is not set
292# CONFIG_IRDA is not set 323# CONFIG_IRDA is not set
293# CONFIG_BT is not set 324# CONFIG_BT is not set
325# CONFIG_IEEE80211 is not set
294 326
295# 327#
296# Device Drivers 328# Device Drivers
@@ -328,21 +360,13 @@ CONFIG_BLK_DEV_RAM=y
328CONFIG_BLK_DEV_RAM_COUNT=16 360CONFIG_BLK_DEV_RAM_COUNT=16
329CONFIG_BLK_DEV_RAM_SIZE=8192 361CONFIG_BLK_DEV_RAM_SIZE=8192
330CONFIG_BLK_DEV_INITRD=y 362CONFIG_BLK_DEV_INITRD=y
331CONFIG_INITRAMFS_SOURCE=""
332# CONFIG_CDROM_PKTCDVD is not set 363# CONFIG_CDROM_PKTCDVD is not set
333
334#
335# IO Schedulers
336#
337CONFIG_IOSCHED_NOOP=y
338CONFIG_IOSCHED_AS=y
339CONFIG_IOSCHED_DEADLINE=y
340CONFIG_IOSCHED_CFQ=y
341CONFIG_ATA_OVER_ETH=m 364CONFIG_ATA_OVER_ETH=m
342 365
343# 366#
344# SCSI device support 367# SCSI device support
345# 368#
369# CONFIG_RAID_ATTRS is not set
346CONFIG_SCSI=y 370CONFIG_SCSI=y
347CONFIG_SCSI_PROC_FS=y 371CONFIG_SCSI_PROC_FS=y
348 372
@@ -369,10 +393,12 @@ CONFIG_SCSI_PROC_FS=y
369# CONFIG_SCSI_SPI_ATTRS is not set 393# CONFIG_SCSI_SPI_ATTRS is not set
370# CONFIG_SCSI_FC_ATTRS is not set 394# CONFIG_SCSI_FC_ATTRS is not set
371# CONFIG_SCSI_ISCSI_ATTRS is not set 395# CONFIG_SCSI_ISCSI_ATTRS is not set
396# CONFIG_SCSI_SAS_ATTRS is not set
372 397
373# 398#
374# SCSI low-level drivers 399# SCSI low-level drivers
375# 400#
401# CONFIG_ISCSI_TCP is not set
376# CONFIG_SCSI_SATA is not set 402# CONFIG_SCSI_SATA is not set
377# CONFIG_SCSI_DEBUG is not set 403# CONFIG_SCSI_DEBUG is not set
378 404
@@ -404,6 +430,11 @@ CONFIG_NETDEVICES=y
404# CONFIG_TUN is not set 430# CONFIG_TUN is not set
405 431
406# 432#
433# PHY device support
434#
435# CONFIG_PHYLIB is not set
436
437#
407# Ethernet (10 or 100Mbit) 438# Ethernet (10 or 100Mbit)
408# 439#
409CONFIG_NET_ETHERNET=y 440CONFIG_NET_ETHERNET=y
@@ -439,6 +470,7 @@ CONFIG_PPP=y
439# CONFIG_PPP_SYNC_TTY is not set 470# CONFIG_PPP_SYNC_TTY is not set
440# CONFIG_PPP_DEFLATE is not set 471# CONFIG_PPP_DEFLATE is not set
441# CONFIG_PPP_BSDCOMP is not set 472# CONFIG_PPP_BSDCOMP is not set
473# CONFIG_PPP_MPPE is not set
442# CONFIG_PPPOE is not set 474# CONFIG_PPPOE is not set
443CONFIG_SLIP=y 475CONFIG_SLIP=y
444CONFIG_SLIP_COMPRESSED=y 476CONFIG_SLIP_COMPRESSED=y
@@ -541,18 +573,18 @@ CONFIG_WATCHDOG_NOWAYOUT=y
541# 573#
542# TPM devices 574# TPM devices
543# 575#
576# CONFIG_TELCLOCK is not set
544 577
545# 578#
546# I2C support 579# I2C support
547# 580#
548# CONFIG_I2C is not set 581# CONFIG_I2C is not set
549# CONFIG_I2C_SENSOR is not set
550CONFIG_ISP1301_OMAP=y
551 582
552# 583#
553# Hardware Monitoring support 584# Hardware Monitoring support
554# 585#
555CONFIG_HWMON=y 586CONFIG_HWMON=y
587# CONFIG_HWMON_VID is not set
556# CONFIG_HWMON_DEBUG_CHIP is not set 588# CONFIG_HWMON_DEBUG_CHIP is not set
557 589
558# 590#
@@ -560,6 +592,10 @@ CONFIG_HWMON=y
560# 592#
561 593
562# 594#
595# Multimedia Capabilities Port drivers
596#
597
598#
563# Multimedia devices 599# Multimedia devices
564# 600#
565# CONFIG_VIDEO_DEV is not set 601# CONFIG_VIDEO_DEV is not set
@@ -576,7 +612,6 @@ CONFIG_FB=y
576# CONFIG_FB_CFB_FILLRECT is not set 612# CONFIG_FB_CFB_FILLRECT is not set
577# CONFIG_FB_CFB_COPYAREA is not set 613# CONFIG_FB_CFB_COPYAREA is not set
578# CONFIG_FB_CFB_IMAGEBLIT is not set 614# CONFIG_FB_CFB_IMAGEBLIT is not set
579# CONFIG_FB_SOFT_CURSOR is not set
580# CONFIG_FB_MACMODES is not set 615# CONFIG_FB_MACMODES is not set
581CONFIG_FB_MODE_HELPERS=y 616CONFIG_FB_MODE_HELPERS=y
582# CONFIG_FB_TILEBLITTING is not set 617# CONFIG_FB_TILEBLITTING is not set
@@ -589,6 +624,7 @@ CONFIG_FB_MODE_HELPERS=y
589# CONFIG_VGA_CONSOLE is not set 624# CONFIG_VGA_CONSOLE is not set
590CONFIG_DUMMY_CONSOLE=y 625CONFIG_DUMMY_CONSOLE=y
591CONFIG_FRAMEBUFFER_CONSOLE=y 626CONFIG_FRAMEBUFFER_CONSOLE=y
627# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
592CONFIG_FONTS=y 628CONFIG_FONTS=y
593CONFIG_FONT_8x8=y 629CONFIG_FONT_8x8=y
594CONFIG_FONT_8x16=y 630CONFIG_FONT_8x16=y
@@ -600,6 +636,7 @@ CONFIG_FONT_8x16=y
600# CONFIG_FONT_SUN8x16 is not set 636# CONFIG_FONT_SUN8x16 is not set
601# CONFIG_FONT_SUN12x22 is not set 637# CONFIG_FONT_SUN12x22 is not set
602# CONFIG_FONT_10x18 is not set 638# CONFIG_FONT_10x18 is not set
639# CONFIG_FONT_RL is not set
603 640
604# 641#
605# Logo configuration 642# Logo configuration
@@ -624,10 +661,10 @@ CONFIG_SOUND=y
624# Open Sound System 661# Open Sound System
625# 662#
626CONFIG_SOUND_PRIME=y 663CONFIG_SOUND_PRIME=y
664# CONFIG_OBSOLETE_OSS_DRIVER is not set
627# CONFIG_SOUND_MSNDCLAS is not set 665# CONFIG_SOUND_MSNDCLAS is not set
628# CONFIG_SOUND_MSNDPIN is not set 666# CONFIG_SOUND_MSNDPIN is not set
629# CONFIG_SOUND_OSS is not set 667# CONFIG_SOUND_OSS is not set
630# CONFIG_SOUND_AD1980 is not set
631 668
632# 669#
633# USB support 670# USB support
@@ -637,22 +674,21 @@ CONFIG_USB_ARCH_HAS_OHCI=y
637# CONFIG_USB is not set 674# CONFIG_USB is not set
638 675
639# 676#
677# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
678#
679
680#
640# USB Gadget Support 681# USB Gadget Support
641# 682#
642CONFIG_USB_GADGET=y 683# CONFIG_USB_GADGET is not set
643# CONFIG_USB_GADGET_DEBUG_FILES is not set
644CONFIG_USB_GADGET_SELECTED=y
645# CONFIG_USB_GADGET_NET2280 is not set 684# CONFIG_USB_GADGET_NET2280 is not set
646# CONFIG_USB_GADGET_PXA2XX is not set 685# CONFIG_USB_GADGET_PXA2XX is not set
647# CONFIG_USB_GADGET_GOKU is not set 686# CONFIG_USB_GADGET_GOKU is not set
648# CONFIG_USB_GADGET_LH7A40X is not set 687# CONFIG_USB_GADGET_LH7A40X is not set
649CONFIG_USB_GADGET_OMAP=y 688# CONFIG_USB_GADGET_OMAP is not set
650CONFIG_USB_OMAP=y
651# CONFIG_USB_GADGET_DUMMY_HCD is not set 689# CONFIG_USB_GADGET_DUMMY_HCD is not set
652# CONFIG_USB_GADGET_DUALSPEED is not set
653# CONFIG_USB_ZERO is not set 690# CONFIG_USB_ZERO is not set
654CONFIG_USB_ETH=y 691# CONFIG_USB_ETH is not set
655CONFIG_USB_ETH_RNDIS=y
656# CONFIG_USB_GADGETFS is not set 692# CONFIG_USB_GADGETFS is not set
657# CONFIG_USB_FILE_STORAGE is not set 693# CONFIG_USB_FILE_STORAGE is not set
658# CONFIG_USB_G_SERIAL is not set 694# CONFIG_USB_G_SERIAL is not set
@@ -673,10 +709,6 @@ CONFIG_EXT2_FS=y
673# CONFIG_REISERFS_FS is not set 709# CONFIG_REISERFS_FS is not set
674# CONFIG_JFS_FS is not set 710# CONFIG_JFS_FS is not set
675# CONFIG_FS_POSIX_ACL is not set 711# CONFIG_FS_POSIX_ACL is not set
676
677#
678# XFS support
679#
680# CONFIG_XFS_FS is not set 712# CONFIG_XFS_FS is not set
681# CONFIG_MINIX_FS is not set 713# CONFIG_MINIX_FS is not set
682CONFIG_ROMFS_FS=y 714CONFIG_ROMFS_FS=y
@@ -685,6 +717,7 @@ CONFIG_INOTIFY=y
685CONFIG_DNOTIFY=y 717CONFIG_DNOTIFY=y
686# CONFIG_AUTOFS_FS is not set 718# CONFIG_AUTOFS_FS is not set
687# CONFIG_AUTOFS4_FS is not set 719# CONFIG_AUTOFS4_FS is not set
720# CONFIG_FUSE_FS is not set
688 721
689# 722#
690# CD-ROM/DVD Filesystems 723# CD-ROM/DVD Filesystems
@@ -706,10 +739,10 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
706# 739#
707CONFIG_PROC_FS=y 740CONFIG_PROC_FS=y
708CONFIG_SYSFS=y 741CONFIG_SYSFS=y
709# CONFIG_DEVPTS_FS_XATTR is not set
710# CONFIG_TMPFS is not set 742# CONFIG_TMPFS is not set
711# CONFIG_HUGETLB_PAGE is not set 743# CONFIG_HUGETLB_PAGE is not set
712CONFIG_RAMFS=y 744CONFIG_RAMFS=y
745# CONFIG_RELAYFS_FS is not set
713 746
714# 747#
715# Miscellaneous filesystems 748# Miscellaneous filesystems
@@ -750,6 +783,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
750# CONFIG_NCP_FS is not set 783# CONFIG_NCP_FS is not set
751# CONFIG_CODA_FS is not set 784# CONFIG_CODA_FS is not set
752# CONFIG_AFS_FS is not set 785# CONFIG_AFS_FS is not set
786# CONFIG_9P_FS is not set
753 787
754# 788#
755# Partition Types 789# Partition Types
@@ -859,6 +893,7 @@ CONFIG_CRYPTO_DES=y
859# Library routines 893# Library routines
860# 894#
861# CONFIG_CRC_CCITT is not set 895# CONFIG_CRC_CCITT is not set
896# CONFIG_CRC16 is not set
862CONFIG_CRC32=y 897CONFIG_CRC32=y
863# CONFIG_LIBCRC32C is not set 898# CONFIG_LIBCRC32C is not set
864CONFIG_ZLIB_INFLATE=y 899CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index ba298277becd..30494aab829a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -86,12 +86,16 @@ EXPORT_SYMBOL(pm_power_off);
86 */ 86 */
87void default_idle(void) 87void default_idle(void)
88{ 88{
89 local_irq_disable(); 89 if (hlt_counter)
90 if (!need_resched() && !hlt_counter) { 90 cpu_relax();
91 timer_dyn_reprogram(); 91 else {
92 arch_idle(); 92 local_irq_disable();
93 if (!need_resched()) {
94 timer_dyn_reprogram();
95 arch_idle();
96 }
97 local_irq_enable();
93 } 98 }
94 local_irq_enable();
95} 99}
96 100
97/* 101/*
@@ -116,13 +120,13 @@ void cpu_idle(void)
116 120
117 if (!idle) 121 if (!idle)
118 idle = default_idle; 122 idle = default_idle;
119 preempt_disable();
120 leds_event(led_idle_start); 123 leds_event(led_idle_start);
121 while (!need_resched()) 124 while (!need_resched())
122 idle(); 125 idle();
123 leds_event(led_idle_end); 126 leds_event(led_idle_end);
124 preempt_enable(); 127 preempt_enable_no_resched();
125 schedule(); 128 schedule();
129 preempt_disable();
126 } 130 }
127} 131}
128 132
@@ -355,7 +359,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
355 struct thread_info *thread = p->thread_info; 359 struct thread_info *thread = p->thread_info;
356 struct pt_regs *childregs; 360 struct pt_regs *childregs;
357 361
358 childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; 362 childregs = (void *)thread + THREAD_START_SP - sizeof(*regs);
359 *childregs = *regs; 363 *childregs = *regs;
360 childregs->ARM_r0 = 0; 364 childregs->ARM_r0 = 0;
361 childregs->ARM_sp = stack_start; 365 childregs->ARM_sp = stack_start;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 77e2e9ca89fa..e55ea952f7aa 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -256,7 +256,9 @@ void __cpuexit cpu_die(void)
256asmlinkage void __cpuinit secondary_start_kernel(void) 256asmlinkage void __cpuinit secondary_start_kernel(void)
257{ 257{
258 struct mm_struct *mm = &init_mm; 258 struct mm_struct *mm = &init_mm;
259 unsigned int cpu = smp_processor_id(); 259 unsigned int cpu;
260
261 cpu = smp_processor_id();
260 262
261 printk("CPU%u: Booted secondary processor\n", cpu); 263 printk("CPU%u: Booted secondary processor\n", cpu);
262 264
@@ -273,6 +275,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
273 local_flush_tlb_all(); 275 local_flush_tlb_all();
274 276
275 cpu_init(); 277 cpu_init();
278 preempt_disable();
276 279
277 /* 280 /*
278 * Give the platform a chance to do its own initialisation. 281 * Give the platform a chance to do its own initialisation.
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index f35d91fbe117..b8c14e936697 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -34,7 +34,7 @@
34 and r2, r0, #7 34 and r2, r0, #7
35 mov r3, #1 35 mov r3, #1
36 mov r3, r3, lsl r2 36 mov r3, r3, lsl r2
37 save_and_disable_irqs ip, r2 37 save_and_disable_irqs ip
38 ldrb r2, [r1, r0, lsr #3] 38 ldrb r2, [r1, r0, lsr #3]
39 \instr r2, r2, r3 39 \instr r2, r2, r3
40 strb r2, [r1, r0, lsr #3] 40 strb r2, [r1, r0, lsr #3]
@@ -54,7 +54,7 @@
54 add r1, r1, r0, lsr #3 54 add r1, r1, r0, lsr #3
55 and r3, r0, #7 55 and r3, r0, #7
56 mov r0, #1 56 mov r0, #1
57 save_and_disable_irqs ip, r2 57 save_and_disable_irqs ip
58 ldrb r2, [r1] 58 ldrb r2, [r1]
59 tst r2, r0, lsl r3 59 tst r2, r0, lsl r3
60 \instr r2, r2, r0, lsl r3 60 \instr r2, r2, r0, lsl r3
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S
index cb5e3708f118..fe797cf320bb 100644
--- a/arch/arm/lib/csumpartial.S
+++ b/arch/arm/lib/csumpartial.S
@@ -39,6 +39,7 @@ td3 .req lr
39 39
40 /* we must have at least one byte. */ 40 /* we must have at least one byte. */
41 tst buf, #1 @ odd address? 41 tst buf, #1 @ odd address?
42 movne sum, sum, ror #8
42 ldrneb td0, [buf], #1 43 ldrneb td0, [buf], #1
43 subne len, len, #1 44 subne len, len, #1
44 adcnes sum, sum, td0, put_byte_1 45 adcnes sum, sum, td0, put_byte_1
@@ -103,6 +104,9 @@ ENTRY(csum_partial)
103 cmp len, #8 @ Ensure that we have at least 104 cmp len, #8 @ Ensure that we have at least
104 blo .less8 @ 8 bytes to copy. 105 blo .less8 @ 8 bytes to copy.
105 106
107 tst buf, #1
108 movne sum, sum, ror #8
109
106 adds sum, sum, #0 @ C = 0 110 adds sum, sum, #0 @ C = 0
107 tst buf, #3 @ Test destination alignment 111 tst buf, #3 @ Test destination alignment
108 blne .not_aligned @ aligh destination, return here 112 blne .not_aligned @ aligh destination, return here
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 89762a26495c..385285851cb5 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -8,6 +8,16 @@ menu "Intel IXP4xx Implementation Options"
8 8
9comment "IXP4xx Platforms" 9comment "IXP4xx Platforms"
10 10
11# This entry is placed on top because otherwise it would have
12# been shown as a submenu.
13config MACH_NSLU2
14 bool
15 prompt "NSLU2" if !(MACH_IXDP465 || MACH_IXDPG425 || ARCH_IXDP425 || ARCH_ADI_COYOTE || ARCH_AVILA || ARCH_IXCDP1100 || ARCH_PRPMC1100 || MACH_GTWX5715)
16 help
17 Say 'Y' here if you want your kernel to support Linksys's
18 NSLU2 NAS device. For more information on this platform,
19 see http://www.nslu2-linux.org
20
11config ARCH_AVILA 21config ARCH_AVILA
12 bool "Avila" 22 bool "Avila"
13 help 23 help
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index ddecbda4a633..7a15629c18d0 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o
8obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o 8obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o
9obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o 9obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o
10obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o 10obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o
11obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o
11 12
diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c
new file mode 100644
index 000000000000..a575f2e0b2c8
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-pci.c
@@ -0,0 +1,77 @@
1/*
2 * arch/arm/mach-ixp4xx/nslu2-pci.c
3 *
4 * NSLU2 board-level PCI initialization
5 *
6 * based on ixdp425-pci.c:
7 * Copyright (C) 2002 Intel Corporation.
8 * Copyright (C) 2003-2004 MontaVista Software, Inc.
9 *
10 * Maintainer: http://www.nslu2-linux.org/
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/config.h>
19#include <linux/pci.h>
20#include <linux/init.h>
21
22#include <asm/mach/pci.h>
23#include <asm/mach-types.h>
24
25void __init nslu2_pci_preinit(void)
26{
27 set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW);
28 set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW);
29 set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW);
30
31 gpio_line_isr_clear(NSLU2_PCI_INTA_PIN);
32 gpio_line_isr_clear(NSLU2_PCI_INTB_PIN);
33 gpio_line_isr_clear(NSLU2_PCI_INTC_PIN);
34
35 /* INTD is not configured as GPIO is used
36 * for the power input button.
37 */
38
39 ixp4xx_pci_preinit();
40}
41
42static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
43{
44 static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
45 IRQ_NSLU2_PCI_INTA,
46 IRQ_NSLU2_PCI_INTB,
47 IRQ_NSLU2_PCI_INTC,
48 };
49
50 int irq = -1;
51
52 if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
53 pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
54 irq = pci_irq_table[(slot + pin - 2) % NSLU2_PCI_IRQ_LINES];
55 }
56
57 return irq;
58}
59
60struct hw_pci __initdata nslu2_pci = {
61 .nr_controllers = 1,
62 .preinit = nslu2_pci_preinit,
63 .swizzle = pci_std_swizzle,
64 .setup = ixp4xx_setup,
65 .scan = ixp4xx_scan_bus,
66 .map_irq = nslu2_map_irq,
67};
68
69int __init nslu2_pci_init(void) /* monkey see, monkey do */
70{
71 if (machine_is_nslu2())
72 pci_common_init(&nslu2_pci);
73
74 return 0;
75}
76
77subsys_initcall(nslu2_pci_init);
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c
new file mode 100644
index 000000000000..18fbc8c0fb30
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-power.c
@@ -0,0 +1,92 @@
1/*
2 * arch/arm/mach-ixp4xx/nslu2-power.c
3 *
4 * NSLU2 Power/Reset driver
5 *
6 * Copyright (C) 2005 Tower Technologies
7 *
8 * based on nslu2-io.c
9 * Copyright (C) 2004 Karen Spearel
10 *
11 * Author: Alessandro Zummo <a.zummo@towertech.it>
12 * Maintainers: http://www.nslu2-linux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/reboot.h>
22#include <linux/interrupt.h>
23
24#include <asm/mach-types.h>
25
26extern void ctrl_alt_del(void);
27
28static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs)
29{
30 /* Signal init to do the ctrlaltdel action, this will bypass init if
31 * it hasn't started and do a kernel_restart.
32 */
33 ctrl_alt_del();
34
35 return IRQ_HANDLED;
36}
37
38static irqreturn_t nslu2_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
39{
40 /* This is the paper-clip reset, it shuts the machine down directly.
41 */
42 machine_power_off();
43
44 return IRQ_HANDLED;
45}
46
47static int __init nslu2_power_init(void)
48{
49 if (!(machine_is_nslu2()))
50 return 0;
51
52 *IXP4XX_GPIO_GPISR = 0x20400000; /* read the 2 irqs to clr */
53
54 set_irq_type(NSLU2_RB_IRQ, IRQT_LOW);
55 set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
56
57 gpio_line_isr_clear(NSLU2_RB_GPIO);
58 gpio_line_isr_clear(NSLU2_PB_GPIO);
59
60 if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler,
61 SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) {
62
63 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
64 NSLU2_RB_IRQ);
65
66 return -EIO;
67 }
68
69 if (request_irq(NSLU2_PB_IRQ, &nslu2_power_handler,
70 SA_INTERRUPT, "NSLU2 power button", NULL) < 0) {
71
72 printk(KERN_DEBUG "Power Button IRQ %d not available\n",
73 NSLU2_PB_IRQ);
74
75 return -EIO;
76 }
77
78 return 0;
79}
80
81static void __exit nslu2_power_exit(void)
82{
83 free_irq(NSLU2_RB_IRQ, NULL);
84 free_irq(NSLU2_PB_IRQ, NULL);
85}
86
87module_init(nslu2_power_init);
88module_exit(nslu2_power_exit);
89
90MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
91MODULE_DESCRIPTION("NSLU2 Power/Reset driver");
92MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
new file mode 100644
index 000000000000..289e94cb65c2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -0,0 +1,134 @@
1/*
2 * arch/arm/mach-ixp4xx/nslu2-setup.c
3 *
4 * NSLU2 board-setup
5 *
6 * based ixdp425-setup.c:
7 * Copyright (C) 2003-2004 MontaVista Software, Inc.
8 *
9 * Author: Mark Rakes <mrakes at mac.com>
10 * Maintainers: http://www.nslu2-linux.org/
11 *
12 * Fixed missing init_time in MACHINE_START kas11 10/22/04
13 * Changed to conform to new style __init ixdp425 kas11 10/22/04
14 */
15
16#include <linux/kernel.h>
17#include <linux/serial.h>
18#include <linux/serial_8250.h>
19
20#include <asm/mach-types.h>
21#include <asm/mach/arch.h>
22#include <asm/mach/flash.h>
23
24static struct flash_platform_data nslu2_flash_data = {
25 .map_name = "cfi_probe",
26 .width = 2,
27};
28
29static struct resource nslu2_flash_resource = {
30 .start = NSLU2_FLASH_BASE,
31 .end = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE,
32 .flags = IORESOURCE_MEM,
33};
34
35static struct platform_device nslu2_flash = {
36 .name = "IXP4XX-Flash",
37 .id = 0,
38 .dev.platform_data = &nslu2_flash_data,
39 .num_resources = 1,
40 .resource = &nslu2_flash_resource,
41};
42
43static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
44 .sda_pin = NSLU2_SDA_PIN,
45 .scl_pin = NSLU2_SCL_PIN,
46};
47
48static struct platform_device nslu2_i2c_controller = {
49 .name = "IXP4XX-I2C",
50 .id = 0,
51 .dev.platform_data = &nslu2_i2c_gpio_pins,
52 .num_resources = 0,
53};
54
55static struct resource nslu2_uart_resources[] = {
56 {
57 .start = IXP4XX_UART1_BASE_PHYS,
58 .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
59 .flags = IORESOURCE_MEM,
60 },
61 {
62 .start = IXP4XX_UART2_BASE_PHYS,
63 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
64 .flags = IORESOURCE_MEM,
65 }
66};
67
68static struct plat_serial8250_port nslu2_uart_data[] = {
69 {
70 .mapbase = IXP4XX_UART1_BASE_PHYS,
71 .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
72 .irq = IRQ_IXP4XX_UART1,
73 .flags = UPF_BOOT_AUTOCONF,
74 .iotype = UPIO_MEM,
75 .regshift = 2,
76 .uartclk = IXP4XX_UART_XTAL,
77 },
78 {
79 .mapbase = IXP4XX_UART2_BASE_PHYS,
80 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
81 .irq = IRQ_IXP4XX_UART2,
82 .flags = UPF_BOOT_AUTOCONF,
83 .iotype = UPIO_MEM,
84 .regshift = 2,
85 .uartclk = IXP4XX_UART_XTAL,
86 },
87 { }
88};
89
90static struct platform_device nslu2_uart = {
91 .name = "serial8250",
92 .id = PLAT8250_DEV_PLATFORM,
93 .dev.platform_data = nslu2_uart_data,
94 .num_resources = 2,
95 .resource = nslu2_uart_resources,
96};
97
98static struct platform_device *nslu2_devices[] __initdata = {
99 &nslu2_i2c_controller,
100 &nslu2_flash,
101 &nslu2_uart,
102};
103
104static void nslu2_power_off(void)
105{
106 /* This causes the box to drop the power and go dead. */
107
108 /* enable the pwr cntl gpio */
109 gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);
110
111 /* do the deed */
112 gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
113}
114
115static void __init nslu2_init(void)
116{
117 ixp4xx_sys_init();
118
119 pm_power_off = nslu2_power_off;
120
121 platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
122}
123
124MACHINE_START(NSLU2, "Linksys NSLU2")
125 /* Maintainer: www.nslu2-linux.org */
126 .phys_ram = PHYS_OFFSET,
127 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
128 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
129 .boot_params = 0x00000100,
130 .map_io = ixp4xx_map_io,
131 .init_irq = ixp4xx_init_irq,
132 .timer = &ixp4xx_timer,
133 .init_machine = nslu2_init,
134MACHINE_END
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 27fc2e8e5fca..86a0f0d14345 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -6,10 +6,10 @@ config ARCH_OMAP730
6 bool "OMAP730 Based System" 6 bool "OMAP730 Based System"
7 select ARCH_OMAP_OTG 7 select ARCH_OMAP_OTG
8 8
9config ARCH_OMAP1510 9config ARCH_OMAP15XX
10 depends on ARCH_OMAP1 10 depends on ARCH_OMAP1
11 default y 11 default y
12 bool "OMAP1510 Based System" 12 bool "OMAP15xx Based System"
13 13
14config ARCH_OMAP16XX 14config ARCH_OMAP16XX
15 depends on ARCH_OMAP1 15 depends on ARCH_OMAP1
@@ -21,7 +21,7 @@ comment "OMAP Board Type"
21 21
22config MACH_OMAP_INNOVATOR 22config MACH_OMAP_INNOVATOR
23 bool "TI Innovator" 23 bool "TI Innovator"
24 depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX) 24 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
25 help 25 help
26 TI OMAP 1510 or 1610 Innovator board support. Say Y here if you 26 TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
27 have such a board. 27 have such a board.
@@ -64,20 +64,30 @@ config MACH_OMAP_PERSEUS2
64 64
65config MACH_VOICEBLUE 65config MACH_VOICEBLUE
66 bool "Voiceblue" 66 bool "Voiceblue"
67 depends on ARCH_OMAP1 && ARCH_OMAP1510 67 depends on ARCH_OMAP1 && ARCH_OMAP15XX
68 help 68 help
69 Support for Voiceblue GSM/VoIP gateway. Say Y here if you have 69 Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
70 such a board. 70 such a board.
71 71
72config MACH_NETSTAR 72config MACH_NETSTAR
73 bool "NetStar" 73 bool "NetStar"
74 depends on ARCH_OMAP1 && ARCH_OMAP1510 74 depends on ARCH_OMAP1 && ARCH_OMAP15XX
75 help 75 help
76 Support for NetStar PBX. Say Y here if you have such a board. 76 Support for NetStar PBX. Say Y here if you have such a board.
77 77
78config MACH_OMAP_PALMTE
79 bool "Palm Tungsten E"
80 depends on ARCH_OMAP1 && ARCH_OMAP15XX
81 help
82 Support for the Palm Tungsten E PDA. Currently only the LCD panel
83 is supported. To boot the kernel, you'll need a PalmOS compatible
84 bootloader; check out http://palmtelinux.sourceforge.net for more
85 informations.
86 Say Y here if you have such a PDA, say NO otherwise.
87
78config MACH_OMAP_GENERIC 88config MACH_OMAP_GENERIC
79 bool "Generic OMAP board" 89 bool "Generic OMAP board"
80 depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX) 90 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
81 help 91 help
82 Support for generic OMAP-1510, 1610 or 1710 board with 92 Support for generic OMAP-1510, 1610 or 1710 board with
83 no FPGA. Can be used as template for porting Linux to 93 no FPGA. Can be used as template for porting Linux to
@@ -121,32 +131,32 @@ config OMAP_ARM_182MHZ
121 131
122config OMAP_ARM_168MHZ 132config OMAP_ARM_168MHZ
123 bool "OMAP ARM 168 MHz CPU" 133 bool "OMAP ARM 168 MHz CPU"
124 depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) 134 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
125 help 135 help
126 Enable 168MHz clock for OMAP CPU. If unsure, say N. 136 Enable 168MHz clock for OMAP CPU. If unsure, say N.
127 137
128config OMAP_ARM_150MHZ 138config OMAP_ARM_150MHZ
129 bool "OMAP ARM 150 MHz CPU" 139 bool "OMAP ARM 150 MHz CPU"
130 depends on ARCH_OMAP1 && ARCH_OMAP1510 140 depends on ARCH_OMAP1 && ARCH_OMAP15XX
131 help 141 help
132 Enable 150MHz clock for OMAP CPU. If unsure, say N. 142 Enable 150MHz clock for OMAP CPU. If unsure, say N.
133 143
134config OMAP_ARM_120MHZ 144config OMAP_ARM_120MHZ
135 bool "OMAP ARM 120 MHz CPU" 145 bool "OMAP ARM 120 MHz CPU"
136 depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) 146 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
137 help 147 help
138 Enable 120MHz clock for OMAP CPU. If unsure, say N. 148 Enable 120MHz clock for OMAP CPU. If unsure, say N.
139 149
140config OMAP_ARM_60MHZ 150config OMAP_ARM_60MHZ
141 bool "OMAP ARM 60 MHz CPU" 151 bool "OMAP ARM 60 MHz CPU"
142 depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) 152 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
143 default y 153 default y
144 help 154 help
145 Enable 60MHz clock for OMAP CPU. If unsure, say Y. 155 Enable 60MHz clock for OMAP CPU. If unsure, say Y.
146 156
147config OMAP_ARM_30MHZ 157config OMAP_ARM_30MHZ
148 bool "OMAP ARM 30 MHz CPU" 158 bool "OMAP ARM 30 MHz CPU"
149 depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) 159 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
150 help 160 help
151 Enable 30MHz clock for OMAP CPU. If unsure, say N. 161 Enable 30MHz clock for OMAP CPU. If unsure, say N.
152 162
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 181a93deaaee..b0b00156faae 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := io.o id.o irq.o time.o serial.o devices.o 6obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o
7led-y := leds.o 7led-y := leds.o
8 8
9# Specific board support 9# Specific board support
@@ -15,8 +15,9 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
15obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o 15obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
16obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o 16obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
17obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o 17obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o
18obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
18 19
19ifeq ($(CONFIG_ARCH_OMAP1510),y) 20ifeq ($(CONFIG_ARCH_OMAP15XX),y)
20# Innovator-1510 FPGA 21# Innovator-1510 FPGA
21obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o 22obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o
22endif 23endif
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index c209c7172a9a..4b292e93fbe2 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -15,7 +15,7 @@
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/device.h> 18#include <linux/platform_device.h>
19 19
20#include <asm/hardware.h> 20#include <asm/hardware.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
@@ -28,8 +28,6 @@
28#include <asm/arch/board.h> 28#include <asm/arch/board.h>
29#include <asm/arch/common.h> 29#include <asm/arch/common.h>
30 30
31static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
32
33static void __init omap_generic_init_irq(void) 31static void __init omap_generic_init_irq(void)
34{ 32{
35 omap_init_irq(); 33 omap_init_irq();
@@ -37,7 +35,7 @@ static void __init omap_generic_init_irq(void)
37 35
38/* assume no Mini-AB port */ 36/* assume no Mini-AB port */
39 37
40#ifdef CONFIG_ARCH_OMAP1510 38#ifdef CONFIG_ARCH_OMAP15XX
41static struct omap_usb_config generic1510_usb_config __initdata = { 39static struct omap_usb_config generic1510_usb_config __initdata = {
42 .register_host = 1, 40 .register_host = 1,
43 .register_dev = 1, 41 .register_dev = 1,
@@ -76,21 +74,19 @@ static struct omap_mmc_config generic_mmc_config __initdata = {
76 74
77#endif 75#endif
78 76
77static struct omap_uart_config generic_uart_config __initdata = {
78 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
79};
80
79static struct omap_board_config_kernel generic_config[] = { 81static struct omap_board_config_kernel generic_config[] = {
80 { OMAP_TAG_USB, NULL }, 82 { OMAP_TAG_USB, NULL },
81 { OMAP_TAG_MMC, &generic_mmc_config }, 83 { OMAP_TAG_MMC, &generic_mmc_config },
84 { OMAP_TAG_UART, &generic_uart_config },
82}; 85};
83 86
84static void __init omap_generic_init(void) 87static void __init omap_generic_init(void)
85{ 88{
86 const struct omap_uart_config *uart_conf; 89#ifdef CONFIG_ARCH_OMAP15XX
87
88 /*
89 * Make sure the serial ports are muxed on at this point.
90 * You have to mux them off in device drivers later on
91 * if not needed.
92 */
93#ifdef CONFIG_ARCH_OMAP1510
94 if (cpu_is_omap1510()) { 90 if (cpu_is_omap1510()) {
95 generic_config[0].data = &generic1510_usb_config; 91 generic_config[0].data = &generic1510_usb_config;
96 } 92 }
@@ -101,20 +97,9 @@ static void __init omap_generic_init(void)
101 } 97 }
102#endif 98#endif
103 99
104 uart_conf = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
105 if (uart_conf != NULL) {
106 unsigned int enabled_ports, i;
107
108 enabled_ports = uart_conf->enabled_uarts;
109 for (i = 0; i < 3; i++) {
110 if (!(enabled_ports & (1 << i)))
111 generic_serial_ports[i] = 0;
112 }
113 }
114
115 omap_board_config = generic_config; 100 omap_board_config = generic_config;
116 omap_board_config_size = ARRAY_SIZE(generic_config); 101 omap_board_config_size = ARRAY_SIZE(generic_config);
117 omap_serial_init(generic_serial_ports); 102 omap_serial_init();
118} 103}
119 104
120static void __init omap_generic_map_io(void) 105static void __init omap_generic_map_io(void)
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 4ee6bd8a50b8..a07e2c9307fa 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -40,8 +40,6 @@
40 40
41extern int omap_gpio_init(void); 41extern int omap_gpio_init(void);
42 42
43static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
44
45static struct mtd_partition h2_partitions[] = { 43static struct mtd_partition h2_partitions[] = {
46 /* bootloader (U-Boot, etc) in first sector */ 44 /* bootloader (U-Boot, etc) in first sector */
47 { 45 {
@@ -160,9 +158,20 @@ static struct omap_mmc_config h2_mmc_config __initdata = {
160 }, 158 },
161}; 159};
162 160
161static struct omap_uart_config h2_uart_config __initdata = {
162 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
163};
164
165static struct omap_lcd_config h2_lcd_config __initdata = {
166 .panel_name = "h2",
167 .ctrl_name = "internal",
168};
169
163static struct omap_board_config_kernel h2_config[] = { 170static struct omap_board_config_kernel h2_config[] = {
164 { OMAP_TAG_USB, &h2_usb_config }, 171 { OMAP_TAG_USB, &h2_usb_config },
165 { OMAP_TAG_MMC, &h2_mmc_config }, 172 { OMAP_TAG_MMC, &h2_mmc_config },
173 { OMAP_TAG_UART, &h2_uart_config },
174 { OMAP_TAG_LCD, &h2_lcd_config },
166}; 175};
167 176
168static void __init h2_init(void) 177static void __init h2_init(void)
@@ -180,12 +189,12 @@ static void __init h2_init(void)
180 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); 189 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
181 omap_board_config = h2_config; 190 omap_board_config = h2_config;
182 omap_board_config_size = ARRAY_SIZE(h2_config); 191 omap_board_config_size = ARRAY_SIZE(h2_config);
192 omap_serial_init();
183} 193}
184 194
185static void __init h2_map_io(void) 195static void __init h2_map_io(void)
186{ 196{
187 omap_map_common_io(); 197 omap_map_common_io();
188 omap_serial_init(h2_serial_ports);
189} 198}
190 199
191MACHINE_START(OMAP_H2, "TI-H2") 200MACHINE_START(OMAP_H2, "TI-H2")
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index fc824361430d..668e278433c2 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -41,8 +41,6 @@
41 41
42extern int omap_gpio_init(void); 42extern int omap_gpio_init(void);
43 43
44static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
45
46static struct mtd_partition h3_partitions[] = { 44static struct mtd_partition h3_partitions[] = {
47 /* bootloader (U-Boot, etc) in first sector */ 45 /* bootloader (U-Boot, etc) in first sector */
48 { 46 {
@@ -168,9 +166,20 @@ static struct omap_mmc_config h3_mmc_config __initdata = {
168 }, 166 },
169}; 167};
170 168
169static struct omap_uart_config h3_uart_config __initdata = {
170 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
171};
172
173static struct omap_lcd_config h3_lcd_config __initdata = {
174 .panel_name = "h3",
175 .ctrl_name = "internal",
176};
177
171static struct omap_board_config_kernel h3_config[] = { 178static struct omap_board_config_kernel h3_config[] = {
172 { OMAP_TAG_USB, &h3_usb_config }, 179 { OMAP_TAG_USB, &h3_usb_config },
173 { OMAP_TAG_MMC, &h3_mmc_config }, 180 { OMAP_TAG_MMC, &h3_mmc_config },
181 { OMAP_TAG_UART, &h3_uart_config },
182 { OMAP_TAG_LCD, &h3_lcd_config },
174}; 183};
175 184
176static void __init h3_init(void) 185static void __init h3_init(void)
@@ -180,6 +189,7 @@ static void __init h3_init(void)
180 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 189 (void) platform_add_devices(devices, ARRAY_SIZE(devices));
181 omap_board_config = h3_config; 190 omap_board_config = h3_config;
182 omap_board_config_size = ARRAY_SIZE(h3_config); 191 omap_board_config_size = ARRAY_SIZE(h3_config);
192 omap_serial_init();
183} 193}
184 194
185static void __init h3_init_smc91x(void) 195static void __init h3_init_smc91x(void)
@@ -201,7 +211,6 @@ void h3_init_irq(void)
201static void __init h3_map_io(void) 211static void __init h3_map_io(void)
202{ 212{
203 omap_map_common_io(); 213 omap_map_common_io();
204 omap_serial_init(h3_serial_ports);
205} 214}
206 215
207MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") 216MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index a2eac853b2da..95f1ff36cdcb 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -36,8 +36,6 @@
36#include <asm/arch/usb.h> 36#include <asm/arch/usb.h>
37#include <asm/arch/common.h> 37#include <asm/arch/common.h>
38 38
39static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
40
41static struct mtd_partition innovator_partitions[] = { 39static struct mtd_partition innovator_partitions[] = {
42 /* bootloader (U-Boot, etc) in first sector */ 40 /* bootloader (U-Boot, etc) in first sector */
43 { 41 {
@@ -99,7 +97,7 @@ static struct platform_device innovator_flash_device = {
99 .resource = &innovator_flash_resource, 97 .resource = &innovator_flash_resource,
100}; 98};
101 99
102#ifdef CONFIG_ARCH_OMAP1510 100#ifdef CONFIG_ARCH_OMAP15XX
103 101
104/* Only FPGA needs to be mapped here. All others are done with ioremap */ 102/* Only FPGA needs to be mapped here. All others are done with ioremap */
105static struct map_desc innovator1510_io_desc[] __initdata = { 103static struct map_desc innovator1510_io_desc[] __initdata = {
@@ -136,7 +134,7 @@ static struct platform_device *innovator1510_devices[] __initdata = {
136 &innovator1510_smc91x_device, 134 &innovator1510_smc91x_device,
137}; 135};
138 136
139#endif /* CONFIG_ARCH_OMAP1510 */ 137#endif /* CONFIG_ARCH_OMAP15XX */
140 138
141#ifdef CONFIG_ARCH_OMAP16XX 139#ifdef CONFIG_ARCH_OMAP16XX
142 140
@@ -185,7 +183,7 @@ void innovator_init_irq(void)
185{ 183{
186 omap_init_irq(); 184 omap_init_irq();
187 omap_gpio_init(); 185 omap_gpio_init();
188#ifdef CONFIG_ARCH_OMAP1510 186#ifdef CONFIG_ARCH_OMAP15XX
189 if (cpu_is_omap1510()) { 187 if (cpu_is_omap1510()) {
190 omap1510_fpga_init_irq(); 188 omap1510_fpga_init_irq();
191 } 189 }
@@ -193,7 +191,7 @@ void innovator_init_irq(void)
193 innovator_init_smc91x(); 191 innovator_init_smc91x();
194} 192}
195 193
196#ifdef CONFIG_ARCH_OMAP1510 194#ifdef CONFIG_ARCH_OMAP15XX
197static struct omap_usb_config innovator1510_usb_config __initdata = { 195static struct omap_usb_config innovator1510_usb_config __initdata = {
198 /* for bundled non-standard host and peripheral cables */ 196 /* for bundled non-standard host and peripheral cables */
199 .hmc_mode = 4, 197 .hmc_mode = 4,
@@ -205,6 +203,11 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
205 .register_dev = 1, 203 .register_dev = 1,
206 .pins[0] = 2, 204 .pins[0] = 2,
207}; 205};
206
207static struct omap_lcd_config innovator1510_lcd_config __initdata = {
208 .panel_name = "inn1510",
209 .ctrl_name = "internal",
210};
208#endif 211#endif
209 212
210#ifdef CONFIG_ARCH_OMAP16XX 213#ifdef CONFIG_ARCH_OMAP16XX
@@ -222,6 +225,11 @@ static struct omap_usb_config h2_usb_config __initdata = {
222 225
223 .pins[1] = 3, 226 .pins[1] = 3,
224}; 227};
228
229static struct omap_lcd_config innovator1610_lcd_config __initdata = {
230 .panel_name = "inn1610",
231 .ctrl_name = "internal",
232};
225#endif 233#endif
226 234
227static struct omap_mmc_config innovator_mmc_config __initdata = { 235static struct omap_mmc_config innovator_mmc_config __initdata = {
@@ -234,14 +242,20 @@ static struct omap_mmc_config innovator_mmc_config __initdata = {
234 }, 242 },
235}; 243};
236 244
245static struct omap_uart_config innovator_uart_config __initdata = {
246 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
247};
248
237static struct omap_board_config_kernel innovator_config[] = { 249static struct omap_board_config_kernel innovator_config[] = {
238 { OMAP_TAG_USB, NULL }, 250 { OMAP_TAG_USB, NULL },
251 { OMAP_TAG_LCD, NULL },
239 { OMAP_TAG_MMC, &innovator_mmc_config }, 252 { OMAP_TAG_MMC, &innovator_mmc_config },
253 { OMAP_TAG_UART, &innovator_uart_config },
240}; 254};
241 255
242static void __init innovator_init(void) 256static void __init innovator_init(void)
243{ 257{
244#ifdef CONFIG_ARCH_OMAP1510 258#ifdef CONFIG_ARCH_OMAP15XX
245 if (cpu_is_omap1510()) { 259 if (cpu_is_omap1510()) {
246 platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices)); 260 platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
247 } 261 }
@@ -252,23 +266,28 @@ static void __init innovator_init(void)
252 } 266 }
253#endif 267#endif
254 268
255#ifdef CONFIG_ARCH_OMAP1510 269#ifdef CONFIG_ARCH_OMAP15XX
256 if (cpu_is_omap1510()) 270 if (cpu_is_omap1510()) {
257 innovator_config[0].data = &innovator1510_usb_config; 271 innovator_config[0].data = &innovator1510_usb_config;
272 innovator_config[1].data = &innovator1510_lcd_config;
273 }
258#endif 274#endif
259#ifdef CONFIG_ARCH_OMAP16XX 275#ifdef CONFIG_ARCH_OMAP16XX
260 if (cpu_is_omap1610()) 276 if (cpu_is_omap1610()) {
261 innovator_config[0].data = &h2_usb_config; 277 innovator_config[0].data = &h2_usb_config;
278 innovator_config[1].data = &innovator1610_lcd_config;
279 }
262#endif 280#endif
263 omap_board_config = innovator_config; 281 omap_board_config = innovator_config;
264 omap_board_config_size = ARRAY_SIZE(innovator_config); 282 omap_board_config_size = ARRAY_SIZE(innovator_config);
283 omap_serial_init();
265} 284}
266 285
267static void __init innovator_map_io(void) 286static void __init innovator_map_io(void)
268{ 287{
269 omap_map_common_io(); 288 omap_map_common_io();
270 289
271#ifdef CONFIG_ARCH_OMAP1510 290#ifdef CONFIG_ARCH_OMAP15XX
272 if (cpu_is_omap1510()) { 291 if (cpu_is_omap1510()) {
273 iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); 292 iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
274 udelay(10); /* Delay needed for FPGA */ 293 udelay(10); /* Delay needed for FPGA */
@@ -280,7 +299,6 @@ static void __init innovator_map_io(void)
280 fpga_read(OMAP1510_FPGA_BOARD_REV)); 299 fpga_read(OMAP1510_FPGA_BOARD_REV));
281 } 300 }
282#endif 301#endif
283 omap_serial_init(innovator_serial_ports);
284} 302}
285 303
286MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") 304MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index c851c2e4dfcb..0448fa7de8a4 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -55,6 +55,14 @@ static struct platform_device *netstar_devices[] __initdata = {
55 &netstar_smc91x_device, 55 &netstar_smc91x_device,
56}; 56};
57 57
58static struct omap_uart_config netstar_uart_config __initdata = {
59 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
60};
61
62static struct omap_board_config_kernel netstar_config[] = {
63 { OMAP_TAG_UART, &netstar_uart_config },
64};
65
58static void __init netstar_init_irq(void) 66static void __init netstar_init_irq(void)
59{ 67{
60 omap_init_irq(); 68 omap_init_irq();
@@ -92,14 +100,15 @@ static void __init netstar_init(void)
92 /* Switch off red LED */ 100 /* Switch off red LED */
93 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ 101 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
94 omap_writeb(0x80, OMAP_LPG1_LCR); 102 omap_writeb(0x80, OMAP_LPG1_LCR);
95}
96 103
97static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; 104 omap_board_config = netstar_config;
105 omap_board_config_size = ARRAY_SIZE(netstar_config);
106 omap_serial_init();
107}
98 108
99static void __init netstar_map_io(void) 109static void __init netstar_map_io(void)
100{ 110{
101 omap_map_common_io(); 111 omap_map_common_io();
102 omap_serial_init(omap_serial_ports);
103} 112}
104 113
105#define MACHINE_PANICED 1 114#define MACHINE_PANICED 1
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index a88524e7c315..e990e1bc1669 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -46,8 +46,6 @@
46#include <asm/arch/tc.h> 46#include <asm/arch/tc.h>
47#include <asm/arch/common.h> 47#include <asm/arch/common.h>
48 48
49static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
50
51static struct mtd_partition osk_partitions[] = { 49static struct mtd_partition osk_partitions[] = {
52 /* bootloader (U-Boot, etc) in first sector */ 50 /* bootloader (U-Boot, etc) in first sector */
53 { 51 {
@@ -155,7 +153,7 @@ static void __init osk_init_smc91x(void)
155 } 153 }
156 154
157 /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ 155 /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
158 EMIFS_CCS(1) |= 0x2; 156 EMIFS_CCS(1) |= 0x3;
159} 157}
160 158
161static void __init osk_init_cf(void) 159static void __init osk_init_cf(void)
@@ -193,8 +191,19 @@ static struct omap_usb_config osk_usb_config __initdata = {
193 .pins[0] = 2, 191 .pins[0] = 2,
194}; 192};
195 193
194static struct omap_uart_config osk_uart_config __initdata = {
195 .enabled_uarts = (1 << 0),
196};
197
198static struct omap_lcd_config osk_lcd_config __initdata = {
199 .panel_name = "osk",
200 .ctrl_name = "internal",
201};
202
196static struct omap_board_config_kernel osk_config[] = { 203static struct omap_board_config_kernel osk_config[] = {
197 { OMAP_TAG_USB, &osk_usb_config }, 204 { OMAP_TAG_USB, &osk_usb_config },
205 { OMAP_TAG_UART, &osk_uart_config },
206 { OMAP_TAG_LCD, &osk_lcd_config },
198}; 207};
199 208
200#ifdef CONFIG_OMAP_OSK_MISTRAL 209#ifdef CONFIG_OMAP_OSK_MISTRAL
@@ -254,13 +263,13 @@ static void __init osk_init(void)
254 omap_board_config_size = ARRAY_SIZE(osk_config); 263 omap_board_config_size = ARRAY_SIZE(osk_config);
255 USB_TRANSCEIVER_CTRL_REG |= (3 << 1); 264 USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
256 265
266 omap_serial_init();
257 osk_mistral_init(); 267 osk_mistral_init();
258} 268}
259 269
260static void __init osk_map_io(void) 270static void __init osk_map_io(void)
261{ 271{
262 omap_map_common_io(); 272 omap_map_common_io();
263 omap_serial_init(osk_serial_ports);
264} 273}
265 274
266MACHINE_START(OMAP_OSK, "TI-OSK") 275MACHINE_START(OMAP_OSK, "TI-OSK")
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
new file mode 100644
index 000000000000..540b20d78cca
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -0,0 +1,87 @@
1/*
2 * linux/arch/arm/mach-omap1/board-palmte.c
3 *
4 * Modified from board-generic.c
5 *
6 * Support for the Palm Tungsten E PDA.
7 *
8 * Original version : Laurent Gonzalez
9 *
10 * Maintainters : http://palmtelinux.sf.net
11 * palmtelinux-developpers@lists.sf.net
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/platform_device.h>
21#include <linux/notifier.h>
22
23#include <asm/hardware.h>
24#include <asm/mach-types.h>
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27
28#include <asm/arch/gpio.h>
29#include <asm/arch/mux.h>
30#include <asm/arch/usb.h>
31#include <asm/arch/board.h>
32#include <asm/arch/common.h>
33#include <asm/hardware/clock.h>
34
35static void __init omap_generic_init_irq(void)
36{
37 omap_init_irq();
38}
39
40static struct omap_usb_config palmte_usb_config __initdata = {
41 .register_dev = 1,
42 .hmc_mode = 0,
43 .pins[0] = 3,
44};
45
46static struct omap_mmc_config palmte_mmc_config __initdata = {
47 .mmc [0] = {
48 .enabled = 1,
49 .wire4 = 1,
50 .wp_pin = OMAP_MPUIO(3),
51 .power_pin = -1,
52 .switch_pin = -1,
53 },
54};
55
56static struct omap_lcd_config palmte_lcd_config __initdata = {
57 .panel_name = "palmte",
58 .ctrl_name = "internal",
59};
60
61static struct omap_board_config_kernel palmte_config[] = {
62 { OMAP_TAG_USB, &palmte_usb_config },
63 { OMAP_TAG_MMC, &palmte_mmc_config },
64 { OMAP_TAG_LCD, &palmte_lcd_config },
65};
66
67static void __init omap_generic_init(void)
68{
69 omap_board_config = palmte_config;
70 omap_board_config_size = ARRAY_SIZE(palmte_config);
71}
72
73static void __init omap_generic_map_io(void)
74{
75 omap_map_common_io();
76}
77
78MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
79 .phys_ram = 0x10000000,
80 .phys_io = 0xfff00000,
81 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
82 .boot_params = 0x10000100,
83 .map_io = omap_generic_map_io,
84 .init_irq = omap_generic_init_irq,
85 .init_machine = omap_generic_init,
86 .timer = &omap_timer,
87MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 354b157acb3a..bd900b7ab33c 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -29,6 +29,7 @@
29#include <asm/arch/mux.h> 29#include <asm/arch/mux.h>
30#include <asm/arch/fpga.h> 30#include <asm/arch/fpga.h>
31#include <asm/arch/common.h> 31#include <asm/arch/common.h>
32#include <asm/arch/board.h>
32 33
33static struct resource smc91x_resources[] = { 34static struct resource smc91x_resources[] = {
34 [0] = { 35 [0] = {
@@ -43,8 +44,6 @@ static struct resource smc91x_resources[] = {
43 }, 44 },
44}; 45};
45 46
46static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0};
47
48static struct mtd_partition p2_partitions[] = { 47static struct mtd_partition p2_partitions[] = {
49 /* bootloader (U-Boot, etc) in first sector */ 48 /* bootloader (U-Boot, etc) in first sector */
50 { 49 {
@@ -111,9 +110,27 @@ static struct platform_device *devices[] __initdata = {
111 &smc91x_device, 110 &smc91x_device,
112}; 111};
113 112
113static struct omap_uart_config perseus2_uart_config __initdata = {
114 .enabled_uarts = ((1 << 0) | (1 << 1)),
115};
116
117static struct omap_lcd_config perseus2_lcd_config __initdata = {
118 .panel_name = "p2",
119 .ctrl_name = "internal",
120};
121
122static struct omap_board_config_kernel perseus2_config[] = {
123 { OMAP_TAG_UART, &perseus2_uart_config },
124 { OMAP_TAG_LCD, &perseus2_lcd_config },
125};
126
114static void __init omap_perseus2_init(void) 127static void __init omap_perseus2_init(void)
115{ 128{
116 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 129 (void) platform_add_devices(devices, ARRAY_SIZE(devices));
130
131 omap_board_config = perseus2_config;
132 omap_board_config_size = ARRAY_SIZE(perseus2_config);
133 omap_serial_init();
117} 134}
118 135
119static void __init perseus2_init_smc91x(void) 136static void __init perseus2_init_smc91x(void)
@@ -131,7 +148,6 @@ void omap_perseus2_init_irq(void)
131 omap_gpio_init(); 148 omap_gpio_init();
132 perseus2_init_smc91x(); 149 perseus2_init_smc91x();
133} 150}
134
135/* Only FPGA needs to be mapped here. All others are done with ioremap */ 151/* Only FPGA needs to be mapped here. All others are done with ioremap */
136static struct map_desc omap_perseus2_io_desc[] __initdata = { 152static struct map_desc omap_perseus2_io_desc[] __initdata = {
137 { 153 {
@@ -179,7 +195,6 @@ static void __init omap_perseus2_map_io(void)
179 * It is used as the Ethernet controller interrupt 195 * It is used as the Ethernet controller interrupt
180 */ 196 */
181 omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9); 197 omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
182 omap_serial_init(p2_serial_ports);
183} 198}
184 199
185MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") 200MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 3f018b296861..6f9a6220e78a 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -150,9 +150,14 @@ static struct omap_mmc_config voiceblue_mmc_config __initdata = {
150 }, 150 },
151}; 151};
152 152
153static struct omap_uart_config voiceblue_uart_config __initdata = {
154 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
155};
156
153static struct omap_board_config_kernel voiceblue_config[] = { 157static struct omap_board_config_kernel voiceblue_config[] = {
154 { OMAP_TAG_USB, &voiceblue_usb_config }, 158 { OMAP_TAG_USB, &voiceblue_usb_config },
155 { OMAP_TAG_MMC, &voiceblue_mmc_config }, 159 { OMAP_TAG_MMC, &voiceblue_mmc_config },
160 { OMAP_TAG_UART, &voiceblue_uart_config },
156}; 161};
157 162
158static void __init voiceblue_init_irq(void) 163static void __init voiceblue_init_irq(void)
@@ -191,6 +196,7 @@ static void __init voiceblue_init(void)
191 platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); 196 platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
192 omap_board_config = voiceblue_config; 197 omap_board_config = voiceblue_config;
193 omap_board_config_size = ARRAY_SIZE(voiceblue_config); 198 omap_board_config_size = ARRAY_SIZE(voiceblue_config);
199 omap_serial_init();
194 200
195 /* There is a good chance board is going up, so enable power LED 201 /* There is a good chance board is going up, so enable power LED
196 * (it is connected through invertor) */ 202 * (it is connected through invertor) */
@@ -198,12 +204,9 @@ static void __init voiceblue_init(void)
198 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ 204 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
199} 205}
200 206
201static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
202
203static void __init voiceblue_map_io(void) 207static void __init voiceblue_map_io(void)
204{ 208{
205 omap_map_common_io(); 209 omap_map_common_io();
206 omap_serial_init(omap_serial_ports);
207} 210}
208 211
209#define MACHINE_PANICED 1 212#define MACHINE_PANICED 1
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
new file mode 100644
index 000000000000..4277eee44ed5
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.c
@@ -0,0 +1,792 @@
1/*
2 * linux/arch/arm/mach-omap1/clock.c
3 *
4 * Copyright (C) 2004 - 2005 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 *
7 * Modified to use omap shared clock framework by
8 * Tony Lindgren <tony@atomide.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19
20#include <asm/io.h>
21#include <asm/hardware/clock.h>
22
23#include <asm/arch/usb.h>
24#include <asm/arch/clock.h>
25#include <asm/arch/sram.h>
26
27#include "clock.h"
28
29__u32 arm_idlect1_mask;
30
31/*-------------------------------------------------------------------------
32 * Omap1 specific clock functions
33 *-------------------------------------------------------------------------*/
34
35static void omap1_watchdog_recalc(struct clk * clk)
36{
37 clk->rate = clk->parent->rate / 14;
38}
39
40static void omap1_uart_recalc(struct clk * clk)
41{
42 unsigned int val = omap_readl(clk->enable_reg);
43 if (val & clk->enable_bit)
44 clk->rate = 48000000;
45 else
46 clk->rate = 12000000;
47}
48
49static int omap1_clk_enable_dsp_domain(struct clk *clk)
50{
51 int retval;
52
53 retval = omap1_clk_use(&api_ck.clk);
54 if (!retval) {
55 retval = omap1_clk_enable(clk);
56 omap1_clk_unuse(&api_ck.clk);
57 }
58
59 return retval;
60}
61
62static void omap1_clk_disable_dsp_domain(struct clk *clk)
63{
64 if (omap1_clk_use(&api_ck.clk) == 0) {
65 omap1_clk_disable(clk);
66 omap1_clk_unuse(&api_ck.clk);
67 }
68}
69
70static int omap1_clk_enable_uart_functional(struct clk *clk)
71{
72 int ret;
73 struct uart_clk *uclk;
74
75 ret = omap1_clk_enable(clk);
76 if (ret == 0) {
77 /* Set smart idle acknowledgement mode */
78 uclk = (struct uart_clk *)clk;
79 omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
80 uclk->sysc_addr);
81 }
82
83 return ret;
84}
85
86static void omap1_clk_disable_uart_functional(struct clk *clk)
87{
88 struct uart_clk *uclk;
89
90 /* Set force idle acknowledgement mode */
91 uclk = (struct uart_clk *)clk;
92 omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
93
94 omap1_clk_disable(clk);
95}
96
97static void omap1_clk_allow_idle(struct clk *clk)
98{
99 struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
100
101 if (!(clk->flags & CLOCK_IDLE_CONTROL))
102 return;
103
104 if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
105 arm_idlect1_mask |= 1 << iclk->idlect_shift;
106}
107
108static void omap1_clk_deny_idle(struct clk *clk)
109{
110 struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
111
112 if (!(clk->flags & CLOCK_IDLE_CONTROL))
113 return;
114
115 if (iclk->no_idle_count++ == 0)
116 arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
117}
118
119static __u16 verify_ckctl_value(__u16 newval)
120{
121 /* This function checks for following limitations set
122 * by the hardware (all conditions must be true):
123 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
124 * ARM_CK >= TC_CK
125 * DSP_CK >= TC_CK
126 * DSPMMU_CK >= TC_CK
127 *
128 * In addition following rules are enforced:
129 * LCD_CK <= TC_CK
130 * ARMPER_CK <= TC_CK
131 *
132 * However, maximum frequencies are not checked for!
133 */
134 __u8 per_exp;
135 __u8 lcd_exp;
136 __u8 arm_exp;
137 __u8 dsp_exp;
138 __u8 tc_exp;
139 __u8 dspmmu_exp;
140
141 per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
142 lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
143 arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
144 dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
145 tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
146 dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
147
148 if (dspmmu_exp < dsp_exp)
149 dspmmu_exp = dsp_exp;
150 if (dspmmu_exp > dsp_exp+1)
151 dspmmu_exp = dsp_exp+1;
152 if (tc_exp < arm_exp)
153 tc_exp = arm_exp;
154 if (tc_exp < dspmmu_exp)
155 tc_exp = dspmmu_exp;
156 if (tc_exp > lcd_exp)
157 lcd_exp = tc_exp;
158 if (tc_exp > per_exp)
159 per_exp = tc_exp;
160
161 newval &= 0xf000;
162 newval |= per_exp << CKCTL_PERDIV_OFFSET;
163 newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
164 newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
165 newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
166 newval |= tc_exp << CKCTL_TCDIV_OFFSET;
167 newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
168
169 return newval;
170}
171
172static int calc_dsor_exp(struct clk *clk, unsigned long rate)
173{
174 /* Note: If target frequency is too low, this function will return 4,
175 * which is invalid value. Caller must check for this value and act
176 * accordingly.
177 *
178 * Note: This function does not check for following limitations set
179 * by the hardware (all conditions must be true):
180 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
181 * ARM_CK >= TC_CK
182 * DSP_CK >= TC_CK
183 * DSPMMU_CK >= TC_CK
184 */
185 unsigned long realrate;
186 struct clk * parent;
187 unsigned dsor_exp;
188
189 if (unlikely(!(clk->flags & RATE_CKCTL)))
190 return -EINVAL;
191
192 parent = clk->parent;
193 if (unlikely(parent == 0))
194 return -EIO;
195
196 realrate = parent->rate;
197 for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
198 if (realrate <= rate)
199 break;
200
201 realrate /= 2;
202 }
203
204 return dsor_exp;
205}
206
207static void omap1_ckctl_recalc(struct clk * clk)
208{
209 int dsor;
210
211 /* Calculate divisor encoded as 2-bit exponent */
212 dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
213
214 if (unlikely(clk->rate == clk->parent->rate / dsor))
215 return; /* No change, quick exit */
216 clk->rate = clk->parent->rate / dsor;
217
218 if (unlikely(clk->flags & RATE_PROPAGATES))
219 propagate_rate(clk);
220}
221
222static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
223{
224 int dsor;
225
226 /* Calculate divisor encoded as 2-bit exponent
227 *
228 * The clock control bits are in DSP domain,
229 * so api_ck is needed for access.
230 * Note that DSP_CKCTL virt addr = phys addr, so
231 * we must use __raw_readw() instead of omap_readw().
232 */
233 omap1_clk_use(&api_ck.clk);
234 dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
235 omap1_clk_unuse(&api_ck.clk);
236
237 if (unlikely(clk->rate == clk->parent->rate / dsor))
238 return; /* No change, quick exit */
239 clk->rate = clk->parent->rate / dsor;
240
241 if (unlikely(clk->flags & RATE_PROPAGATES))
242 propagate_rate(clk);
243}
244
245/* MPU virtual clock functions */
246static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
247{
248 /* Find the highest supported frequency <= rate and switch to it */
249 struct mpu_rate * ptr;
250
251 if (clk != &virtual_ck_mpu)
252 return -EINVAL;
253
254 for (ptr = rate_table; ptr->rate; ptr++) {
255 if (ptr->xtal != ck_ref.rate)
256 continue;
257
258 /* DPLL1 cannot be reprogrammed without risking system crash */
259 if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
260 continue;
261
262 /* Can check only after xtal frequency check */
263 if (ptr->rate <= rate)
264 break;
265 }
266
267 if (!ptr->rate)
268 return -EINVAL;
269
270 /*
271 * In most cases we should not need to reprogram DPLL.
272 * Reprogramming the DPLL is tricky, it must be done from SRAM.
273 */
274 omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
275
276 ck_dpll1.rate = ptr->pll_rate;
277 propagate_rate(&ck_dpll1);
278 return 0;
279}
280
281static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
282{
283 int ret = -EINVAL;
284 int dsor_exp;
285 __u16 regval;
286
287 if (clk->flags & RATE_CKCTL) {
288 dsor_exp = calc_dsor_exp(clk, rate);
289 if (dsor_exp > 3)
290 dsor_exp = -EINVAL;
291 if (dsor_exp < 0)
292 return dsor_exp;
293
294 regval = __raw_readw(DSP_CKCTL);
295 regval &= ~(3 << clk->rate_offset);
296 regval |= dsor_exp << clk->rate_offset;
297 __raw_writew(regval, DSP_CKCTL);
298 clk->rate = clk->parent->rate / (1 << dsor_exp);
299 ret = 0;
300 }
301
302 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
303 propagate_rate(clk);
304
305 return ret;
306}
307
308static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
309{
310 /* Find the highest supported frequency <= rate */
311 struct mpu_rate * ptr;
312 long highest_rate;
313
314 if (clk != &virtual_ck_mpu)
315 return -EINVAL;
316
317 highest_rate = -EINVAL;
318
319 for (ptr = rate_table; ptr->rate; ptr++) {
320 if (ptr->xtal != ck_ref.rate)
321 continue;
322
323 highest_rate = ptr->rate;
324
325 /* Can check only after xtal frequency check */
326 if (ptr->rate <= rate)
327 break;
328 }
329
330 return highest_rate;
331}
332
333static unsigned calc_ext_dsor(unsigned long rate)
334{
335 unsigned dsor;
336
337 /* MCLK and BCLK divisor selection is not linear:
338 * freq = 96MHz / dsor
339 *
340 * RATIO_SEL range: dsor <-> RATIO_SEL
341 * 0..6: (RATIO_SEL+2) <-> (dsor-2)
342 * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
343 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
344 * can not be used.
345 */
346 for (dsor = 2; dsor < 96; ++dsor) {
347 if ((dsor & 1) && dsor > 8)
348 continue;
349 if (rate >= 96000000 / dsor)
350 break;
351 }
352 return dsor;
353}
354
355/* Only needed on 1510 */
356static int omap1_set_uart_rate(struct clk * clk, unsigned long rate)
357{
358 unsigned int val;
359
360 val = omap_readl(clk->enable_reg);
361 if (rate == 12000000)
362 val &= ~(1 << clk->enable_bit);
363 else if (rate == 48000000)
364 val |= (1 << clk->enable_bit);
365 else
366 return -EINVAL;
367 omap_writel(val, clk->enable_reg);
368 clk->rate = rate;
369
370 return 0;
371}
372
373/* External clock (MCLK & BCLK) functions */
374static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
375{
376 unsigned dsor;
377 __u16 ratio_bits;
378
379 dsor = calc_ext_dsor(rate);
380 clk->rate = 96000000 / dsor;
381 if (dsor > 8)
382 ratio_bits = ((dsor - 8) / 2 + 6) << 2;
383 else
384 ratio_bits = (dsor - 2) << 2;
385
386 ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
387 omap_writew(ratio_bits, clk->enable_reg);
388
389 return 0;
390}
391
392static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate)
393{
394 return 96000000 / calc_ext_dsor(rate);
395}
396
397static void omap1_init_ext_clk(struct clk * clk)
398{
399 unsigned dsor;
400 __u16 ratio_bits;
401
402 /* Determine current rate and ensure clock is based on 96MHz APLL */
403 ratio_bits = omap_readw(clk->enable_reg) & ~1;
404 omap_writew(ratio_bits, clk->enable_reg);
405
406 ratio_bits = (ratio_bits & 0xfc) >> 2;
407 if (ratio_bits > 6)
408 dsor = (ratio_bits - 6) * 2 + 8;
409 else
410 dsor = ratio_bits + 2;
411
412 clk-> rate = 96000000 / dsor;
413}
414
415static int omap1_clk_use(struct clk *clk)
416{
417 int ret = 0;
418 if (clk->usecount++ == 0) {
419 if (likely(clk->parent)) {
420 ret = omap1_clk_use(clk->parent);
421
422 if (unlikely(ret != 0)) {
423 clk->usecount--;
424 return ret;
425 }
426
427 if (clk->flags & CLOCK_NO_IDLE_PARENT)
428 if (!cpu_is_omap24xx())
429 omap1_clk_deny_idle(clk->parent);
430 }
431
432 ret = clk->enable(clk);
433
434 if (unlikely(ret != 0) && clk->parent) {
435 omap1_clk_unuse(clk->parent);
436 clk->usecount--;
437 }
438 }
439
440 return ret;
441}
442
443static void omap1_clk_unuse(struct clk *clk)
444{
445 if (clk->usecount > 0 && !(--clk->usecount)) {
446 clk->disable(clk);
447 if (likely(clk->parent)) {
448 omap1_clk_unuse(clk->parent);
449 if (clk->flags & CLOCK_NO_IDLE_PARENT)
450 if (!cpu_is_omap24xx())
451 omap1_clk_allow_idle(clk->parent);
452 }
453 }
454}
455
456static int omap1_clk_enable(struct clk *clk)
457{
458 __u16 regval16;
459 __u32 regval32;
460
461 if (clk->flags & ALWAYS_ENABLED)
462 return 0;
463
464 if (unlikely(clk->enable_reg == 0)) {
465 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
466 clk->name);
467 return 0;
468 }
469
470 if (clk->flags & ENABLE_REG_32BIT) {
471 if (clk->flags & VIRTUAL_IO_ADDRESS) {
472 regval32 = __raw_readl(clk->enable_reg);
473 regval32 |= (1 << clk->enable_bit);
474 __raw_writel(regval32, clk->enable_reg);
475 } else {
476 regval32 = omap_readl(clk->enable_reg);
477 regval32 |= (1 << clk->enable_bit);
478 omap_writel(regval32, clk->enable_reg);
479 }
480 } else {
481 if (clk->flags & VIRTUAL_IO_ADDRESS) {
482 regval16 = __raw_readw(clk->enable_reg);
483 regval16 |= (1 << clk->enable_bit);
484 __raw_writew(regval16, clk->enable_reg);
485 } else {
486 regval16 = omap_readw(clk->enable_reg);
487 regval16 |= (1 << clk->enable_bit);
488 omap_writew(regval16, clk->enable_reg);
489 }
490 }
491
492 return 0;
493}
494
495static void omap1_clk_disable(struct clk *clk)
496{
497 __u16 regval16;
498 __u32 regval32;
499
500 if (clk->enable_reg == 0)
501 return;
502
503 if (clk->flags & ENABLE_REG_32BIT) {
504 if (clk->flags & VIRTUAL_IO_ADDRESS) {
505 regval32 = __raw_readl(clk->enable_reg);
506 regval32 &= ~(1 << clk->enable_bit);
507 __raw_writel(regval32, clk->enable_reg);
508 } else {
509 regval32 = omap_readl(clk->enable_reg);
510 regval32 &= ~(1 << clk->enable_bit);
511 omap_writel(regval32, clk->enable_reg);
512 }
513 } else {
514 if (clk->flags & VIRTUAL_IO_ADDRESS) {
515 regval16 = __raw_readw(clk->enable_reg);
516 regval16 &= ~(1 << clk->enable_bit);
517 __raw_writew(regval16, clk->enable_reg);
518 } else {
519 regval16 = omap_readw(clk->enable_reg);
520 regval16 &= ~(1 << clk->enable_bit);
521 omap_writew(regval16, clk->enable_reg);
522 }
523 }
524}
525
526static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
527{
528 int dsor_exp;
529
530 if (clk->flags & RATE_FIXED)
531 return clk->rate;
532
533 if (clk->flags & RATE_CKCTL) {
534 dsor_exp = calc_dsor_exp(clk, rate);
535 if (dsor_exp < 0)
536 return dsor_exp;
537 if (dsor_exp > 3)
538 dsor_exp = 3;
539 return clk->parent->rate / (1 << dsor_exp);
540 }
541
542 if(clk->round_rate != 0)
543 return clk->round_rate(clk, rate);
544
545 return clk->rate;
546}
547
548static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
549{
550 int ret = -EINVAL;
551 int dsor_exp;
552 __u16 regval;
553
554 if (clk->set_rate)
555 ret = clk->set_rate(clk, rate);
556 else if (clk->flags & RATE_CKCTL) {
557 dsor_exp = calc_dsor_exp(clk, rate);
558 if (dsor_exp > 3)
559 dsor_exp = -EINVAL;
560 if (dsor_exp < 0)
561 return dsor_exp;
562
563 regval = omap_readw(ARM_CKCTL);
564 regval &= ~(3 << clk->rate_offset);
565 regval |= dsor_exp << clk->rate_offset;
566 regval = verify_ckctl_value(regval);
567 omap_writew(regval, ARM_CKCTL);
568 clk->rate = clk->parent->rate / (1 << dsor_exp);
569 ret = 0;
570 }
571
572 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
573 propagate_rate(clk);
574
575 return ret;
576}
577
578/*-------------------------------------------------------------------------
579 * Omap1 clock reset and init functions
580 *-------------------------------------------------------------------------*/
581
582#ifdef CONFIG_OMAP_RESET_CLOCKS
583/*
584 * Resets some clocks that may be left on from bootloader,
585 * but leaves serial clocks on. See also omap_late_clk_reset().
586 */
587static inline void omap1_early_clk_reset(void)
588{
589 //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
590}
591
592static int __init omap1_late_clk_reset(void)
593{
594 /* Turn off all unused clocks */
595 struct clk *p;
596 __u32 regval32;
597
598 /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
599 regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
600 omap_writew(regval32, SOFT_REQ_REG);
601 omap_writew(0, SOFT_REQ_REG2);
602
603 list_for_each_entry(p, &clocks, node) {
604 if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
605 p->enable_reg == 0)
606 continue;
607
608 /* Clocks in the DSP domain need api_ck. Just assume bootloader
609 * has not enabled any DSP clocks */
610 if ((u32)p->enable_reg == DSP_IDLECT2) {
611 printk(KERN_INFO "Skipping reset check for DSP domain "
612 "clock \"%s\"\n", p->name);
613 continue;
614 }
615
616 /* Is the clock already disabled? */
617 if (p->flags & ENABLE_REG_32BIT) {
618 if (p->flags & VIRTUAL_IO_ADDRESS)
619 regval32 = __raw_readl(p->enable_reg);
620 else
621 regval32 = omap_readl(p->enable_reg);
622 } else {
623 if (p->flags & VIRTUAL_IO_ADDRESS)
624 regval32 = __raw_readw(p->enable_reg);
625 else
626 regval32 = omap_readw(p->enable_reg);
627 }
628
629 if ((regval32 & (1 << p->enable_bit)) == 0)
630 continue;
631
632 /* FIXME: This clock seems to be necessary but no-one
633 * has asked for its activation. */
634 if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
635 || p == &ck_dpll1out.clk // FIX: SoSSI, SSR
636 || p == &arm_gpio_ck // FIX: GPIO code for 1510
637 ) {
638 printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
639 p->name);
640 continue;
641 }
642
643 printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
644 p->disable(p);
645 printk(" done\n");
646 }
647
648 return 0;
649}
650late_initcall(omap1_late_clk_reset);
651
652#else
653#define omap1_early_clk_reset() {}
654#endif
655
656static struct clk_functions omap1_clk_functions = {
657 .clk_use = omap1_clk_use,
658 .clk_unuse = omap1_clk_unuse,
659 .clk_round_rate = omap1_clk_round_rate,
660 .clk_set_rate = omap1_clk_set_rate,
661};
662
663int __init omap1_clk_init(void)
664{
665 struct clk ** clkp;
666 const struct omap_clock_config *info;
667 int crystal_type = 0; /* Default 12 MHz */
668
669 omap1_early_clk_reset();
670 clk_init(&omap1_clk_functions);
671
672 /* By default all idlect1 clocks are allowed to idle */
673 arm_idlect1_mask = ~0;
674
675 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
676 if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
677 clk_register(*clkp);
678 continue;
679 }
680
681 if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
682 clk_register(*clkp);
683 continue;
684 }
685
686 if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
687 clk_register(*clkp);
688 continue;
689 }
690 }
691
692 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
693 if (info != NULL) {
694 if (!cpu_is_omap1510())
695 crystal_type = info->system_clock_type;
696 }
697
698#if defined(CONFIG_ARCH_OMAP730)
699 ck_ref.rate = 13000000;
700#elif defined(CONFIG_ARCH_OMAP16XX)
701 if (crystal_type == 2)
702 ck_ref.rate = 19200000;
703#endif
704
705 printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
706 omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
707 omap_readw(ARM_CKCTL));
708
709 /* We want to be in syncronous scalable mode */
710 omap_writew(0x1000, ARM_SYSST);
711
712#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
713 /* Use values set by bootloader. Determine PLL rate and recalculate
714 * dependent clocks as if kernel had changed PLL or divisors.
715 */
716 {
717 unsigned pll_ctl_val = omap_readw(DPLL_CTL);
718
719 ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
720 if (pll_ctl_val & 0x10) {
721 /* PLL enabled, apply multiplier and divisor */
722 if (pll_ctl_val & 0xf80)
723 ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
724 ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
725 } else {
726 /* PLL disabled, apply bypass divisor */
727 switch (pll_ctl_val & 0xc) {
728 case 0:
729 break;
730 case 0x4:
731 ck_dpll1.rate /= 2;
732 break;
733 default:
734 ck_dpll1.rate /= 4;
735 break;
736 }
737 }
738 }
739 propagate_rate(&ck_dpll1);
740#else
741 /* Find the highest supported frequency and enable it */
742 if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
743 printk(KERN_ERR "System frequencies not set. Check your config.\n");
744 /* Guess sane values (60MHz) */
745 omap_writew(0x2290, DPLL_CTL);
746 omap_writew(0x1005, ARM_CKCTL);
747 ck_dpll1.rate = 60000000;
748 propagate_rate(&ck_dpll1);
749 }
750#endif
751 /* Cache rates for clocks connected to ck_ref (not dpll1) */
752 propagate_rate(&ck_ref);
753 printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
754 "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
755 ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
756 ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
757 arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
758
759#ifdef CONFIG_MACH_OMAP_PERSEUS2
760 /* Select slicer output as OMAP input clock */
761 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
762#endif
763
764 /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
765 omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
766
767 /* Put DSP/MPUI into reset until needed */
768 omap_writew(0, ARM_RSTCT1);
769 omap_writew(1, ARM_RSTCT2);
770 omap_writew(0x400, ARM_IDLECT1);
771
772 /*
773 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
774 * of the ARM_IDLECT2 register must be set to zero. The power-on
775 * default value of this bit is one.
776 */
777 omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
778
779 /*
780 * Only enable those clocks we will need, let the drivers
781 * enable other clocks as necessary
782 */
783 clk_use(&armper_ck.clk);
784 clk_use(&armxor_ck.clk);
785 clk_use(&armtim_ck.clk); /* This should be done by timer code */
786
787 if (cpu_is_omap1510())
788 clk_enable(&arm_gpio_ck);
789
790 return 0;
791}
792
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
new file mode 100644
index 000000000000..f3bdfb50e01a
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.h
@@ -0,0 +1,768 @@
1/*
2 * linux/arch/arm/mach-omap1/clock.h
3 *
4 * Copyright (C) 2004 - 2005 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
14#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
15
16static int omap1_clk_enable(struct clk * clk);
17static void omap1_clk_disable(struct clk * clk);
18static void omap1_ckctl_recalc(struct clk * clk);
19static void omap1_watchdog_recalc(struct clk * clk);
20static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
21static int omap1_clk_enable_dsp_domain(struct clk * clk);
22static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
23static void omap1_clk_disable_dsp_domain(struct clk * clk);
24static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
25static void omap1_uart_recalc(struct clk * clk);
26static int omap1_clk_enable_uart_functional(struct clk * clk);
27static void omap1_clk_disable_uart_functional(struct clk * clk);
28static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate);
29static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
30static void omap1_init_ext_clk(struct clk * clk);
31static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
32static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
33static int omap1_clk_use(struct clk *clk);
34static void omap1_clk_unuse(struct clk *clk);
35
36struct mpu_rate {
37 unsigned long rate;
38 unsigned long xtal;
39 unsigned long pll_rate;
40 __u16 ckctl_val;
41 __u16 dpllctl_val;
42};
43
44struct uart_clk {
45 struct clk clk;
46 unsigned long sysc_addr;
47};
48
49/* Provide a method for preventing idling some ARM IDLECT clocks */
50struct arm_idlect1_clk {
51 struct clk clk;
52 unsigned long no_idle_count;
53 __u8 idlect_shift;
54};
55
56/* ARM_CKCTL bit shifts */
57#define CKCTL_PERDIV_OFFSET 0
58#define CKCTL_LCDDIV_OFFSET 2
59#define CKCTL_ARMDIV_OFFSET 4
60#define CKCTL_DSPDIV_OFFSET 6
61#define CKCTL_TCDIV_OFFSET 8
62#define CKCTL_DSPMMUDIV_OFFSET 10
63/*#define ARM_TIMXO 12*/
64#define EN_DSPCK 13
65/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
66/* DSP_CKCTL bit shifts */
67#define CKCTL_DSPPERDIV_OFFSET 0
68
69/* ARM_IDLECT2 bit shifts */
70#define EN_WDTCK 0
71#define EN_XORPCK 1
72#define EN_PERCK 2
73#define EN_LCDCK 3
74#define EN_LBCK 4 /* Not on 1610/1710 */
75/*#define EN_HSABCK 5*/
76#define EN_APICK 6
77#define EN_TIMCK 7
78#define DMACK_REQ 8
79#define EN_GPIOCK 9 /* Not on 1610/1710 */
80/*#define EN_LBFREECK 10*/
81#define EN_CKOUT_ARM 11
82
83/* ARM_IDLECT3 bit shifts */
84#define EN_OCPI_CK 0
85#define EN_TC1_CK 2
86#define EN_TC2_CK 4
87
88/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
89#define EN_DSPTIMCK 5
90
91/* Various register defines for clock controls scattered around OMAP chip */
92#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
93#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
94#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
95#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
96#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
97#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
98#define SOFT_REQ_REG 0xfffe0834
99#define SOFT_REQ_REG2 0xfffe0880
100
101/*-------------------------------------------------------------------------
102 * Omap1 MPU rate table
103 *-------------------------------------------------------------------------*/
104static struct mpu_rate rate_table[] = {
105 /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
106 * NOTE: Comment order here is different from bits in CKCTL value:
107 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
108 */
109#if defined(CONFIG_OMAP_ARM_216MHZ)
110 { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
111#endif
112#if defined(CONFIG_OMAP_ARM_195MHZ)
113 { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
114#endif
115#if defined(CONFIG_OMAP_ARM_192MHZ)
116 { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
117 { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
118 { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
119 { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */
120 { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
121#endif
122#if defined(CONFIG_OMAP_ARM_182MHZ)
123 { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
124#endif
125#if defined(CONFIG_OMAP_ARM_168MHZ)
126 { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
127#endif
128#if defined(CONFIG_OMAP_ARM_150MHZ)
129 { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
130#endif
131#if defined(CONFIG_OMAP_ARM_120MHZ)
132 { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
133#endif
134#if defined(CONFIG_OMAP_ARM_96MHZ)
135 { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
136#endif
137#if defined(CONFIG_OMAP_ARM_60MHZ)
138 { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
139#endif
140#if defined(CONFIG_OMAP_ARM_30MHZ)
141 { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
142#endif
143 { 0, 0, 0, 0, 0 },
144};
145
146/*-------------------------------------------------------------------------
147 * Omap1 clocks
148 *-------------------------------------------------------------------------*/
149
150static struct clk ck_ref = {
151 .name = "ck_ref",
152 .rate = 12000000,
153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
154 ALWAYS_ENABLED,
155 .enable = &omap1_clk_enable,
156 .disable = &omap1_clk_disable,
157};
158
159static struct clk ck_dpll1 = {
160 .name = "ck_dpll1",
161 .parent = &ck_ref,
162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
163 RATE_PROPAGATES | ALWAYS_ENABLED,
164 .enable = &omap1_clk_enable,
165 .disable = &omap1_clk_disable,
166};
167
168static struct arm_idlect1_clk ck_dpll1out = {
169 .clk = {
170 .name = "ck_dpll1out",
171 .parent = &ck_dpll1,
172 .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL,
173 .enable_reg = (void __iomem *)ARM_IDLECT2,
174 .enable_bit = EN_CKOUT_ARM,
175 .recalc = &followparent_recalc,
176 .enable = &omap1_clk_enable,
177 .disable = &omap1_clk_disable,
178 },
179 .idlect_shift = 12,
180};
181
182static struct clk arm_ck = {
183 .name = "arm_ck",
184 .parent = &ck_dpll1,
185 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
186 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
187 .rate_offset = CKCTL_ARMDIV_OFFSET,
188 .recalc = &omap1_ckctl_recalc,
189 .enable = &omap1_clk_enable,
190 .disable = &omap1_clk_disable,
191};
192
193static struct arm_idlect1_clk armper_ck = {
194 .clk = {
195 .name = "armper_ck",
196 .parent = &ck_dpll1,
197 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
198 RATE_CKCTL | CLOCK_IDLE_CONTROL,
199 .enable_reg = (void __iomem *)ARM_IDLECT2,
200 .enable_bit = EN_PERCK,
201 .rate_offset = CKCTL_PERDIV_OFFSET,
202 .recalc = &omap1_ckctl_recalc,
203 .enable = &omap1_clk_enable,
204 .disable = &omap1_clk_disable,
205 },
206 .idlect_shift = 2,
207};
208
209static struct clk arm_gpio_ck = {
210 .name = "arm_gpio_ck",
211 .parent = &ck_dpll1,
212 .flags = CLOCK_IN_OMAP1510,
213 .enable_reg = (void __iomem *)ARM_IDLECT2,
214 .enable_bit = EN_GPIOCK,
215 .recalc = &followparent_recalc,
216 .enable = &omap1_clk_enable,
217 .disable = &omap1_clk_disable,
218};
219
220static struct arm_idlect1_clk armxor_ck = {
221 .clk = {
222 .name = "armxor_ck",
223 .parent = &ck_ref,
224 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
225 CLOCK_IDLE_CONTROL,
226 .enable_reg = (void __iomem *)ARM_IDLECT2,
227 .enable_bit = EN_XORPCK,
228 .recalc = &followparent_recalc,
229 .enable = &omap1_clk_enable,
230 .disable = &omap1_clk_disable,
231 },
232 .idlect_shift = 1,
233};
234
235static struct arm_idlect1_clk armtim_ck = {
236 .clk = {
237 .name = "armtim_ck",
238 .parent = &ck_ref,
239 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
240 CLOCK_IDLE_CONTROL,
241 .enable_reg = (void __iomem *)ARM_IDLECT2,
242 .enable_bit = EN_TIMCK,
243 .recalc = &followparent_recalc,
244 .enable = &omap1_clk_enable,
245 .disable = &omap1_clk_disable,
246 },
247 .idlect_shift = 9,
248};
249
250static struct arm_idlect1_clk armwdt_ck = {
251 .clk = {
252 .name = "armwdt_ck",
253 .parent = &ck_ref,
254 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
255 CLOCK_IDLE_CONTROL,
256 .enable_reg = (void __iomem *)ARM_IDLECT2,
257 .enable_bit = EN_WDTCK,
258 .recalc = &omap1_watchdog_recalc,
259 .enable = &omap1_clk_enable,
260 .disable = &omap1_clk_disable,
261 },
262 .idlect_shift = 0,
263};
264
265static struct clk arminth_ck16xx = {
266 .name = "arminth_ck",
267 .parent = &arm_ck,
268 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
269 .recalc = &followparent_recalc,
270 /* Note: On 16xx the frequency can be divided by 2 by programming
271 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
272 *
273 * 1510 version is in TC clocks.
274 */
275 .enable = &omap1_clk_enable,
276 .disable = &omap1_clk_disable,
277};
278
279static struct clk dsp_ck = {
280 .name = "dsp_ck",
281 .parent = &ck_dpll1,
282 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
283 RATE_CKCTL,
284 .enable_reg = (void __iomem *)ARM_CKCTL,
285 .enable_bit = EN_DSPCK,
286 .rate_offset = CKCTL_DSPDIV_OFFSET,
287 .recalc = &omap1_ckctl_recalc,
288 .enable = &omap1_clk_enable,
289 .disable = &omap1_clk_disable,
290};
291
292static struct clk dspmmu_ck = {
293 .name = "dspmmu_ck",
294 .parent = &ck_dpll1,
295 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
296 RATE_CKCTL | ALWAYS_ENABLED,
297 .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
298 .recalc = &omap1_ckctl_recalc,
299 .enable = &omap1_clk_enable,
300 .disable = &omap1_clk_disable,
301};
302
303static struct clk dspper_ck = {
304 .name = "dspper_ck",
305 .parent = &ck_dpll1,
306 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
307 RATE_CKCTL | VIRTUAL_IO_ADDRESS,
308 .enable_reg = (void __iomem *)DSP_IDLECT2,
309 .enable_bit = EN_PERCK,
310 .rate_offset = CKCTL_PERDIV_OFFSET,
311 .recalc = &omap1_ckctl_recalc_dsp_domain,
312 .set_rate = &omap1_clk_set_rate_dsp_domain,
313 .enable = &omap1_clk_enable_dsp_domain,
314 .disable = &omap1_clk_disable_dsp_domain,
315};
316
317static struct clk dspxor_ck = {
318 .name = "dspxor_ck",
319 .parent = &ck_ref,
320 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
321 VIRTUAL_IO_ADDRESS,
322 .enable_reg = (void __iomem *)DSP_IDLECT2,
323 .enable_bit = EN_XORPCK,
324 .recalc = &followparent_recalc,
325 .enable = &omap1_clk_enable_dsp_domain,
326 .disable = &omap1_clk_disable_dsp_domain,
327};
328
329static struct clk dsptim_ck = {
330 .name = "dsptim_ck",
331 .parent = &ck_ref,
332 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
333 VIRTUAL_IO_ADDRESS,
334 .enable_reg = (void __iomem *)DSP_IDLECT2,
335 .enable_bit = EN_DSPTIMCK,
336 .recalc = &followparent_recalc,
337 .enable = &omap1_clk_enable_dsp_domain,
338 .disable = &omap1_clk_disable_dsp_domain,
339};
340
341/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
342static struct arm_idlect1_clk tc_ck = {
343 .clk = {
344 .name = "tc_ck",
345 .parent = &ck_dpll1,
346 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
347 CLOCK_IN_OMAP730 | RATE_CKCTL |
348 RATE_PROPAGATES | ALWAYS_ENABLED |
349 CLOCK_IDLE_CONTROL,
350 .rate_offset = CKCTL_TCDIV_OFFSET,
351 .recalc = &omap1_ckctl_recalc,
352 .enable = &omap1_clk_enable,
353 .disable = &omap1_clk_disable,
354 },
355 .idlect_shift = 6,
356};
357
358static struct clk arminth_ck1510 = {
359 .name = "arminth_ck",
360 .parent = &tc_ck.clk,
361 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
362 .recalc = &followparent_recalc,
363 /* Note: On 1510 the frequency follows TC_CK
364 *
365 * 16xx version is in MPU clocks.
366 */
367 .enable = &omap1_clk_enable,
368 .disable = &omap1_clk_disable,
369};
370
371static struct clk tipb_ck = {
372 /* No-idle controlled by "tc_ck" */
373 .name = "tibp_ck",
374 .parent = &tc_ck.clk,
375 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
376 .recalc = &followparent_recalc,
377 .enable = &omap1_clk_enable,
378 .disable = &omap1_clk_disable,
379};
380
381static struct clk l3_ocpi_ck = {
382 /* No-idle controlled by "tc_ck" */
383 .name = "l3_ocpi_ck",
384 .parent = &tc_ck.clk,
385 .flags = CLOCK_IN_OMAP16XX,
386 .enable_reg = (void __iomem *)ARM_IDLECT3,
387 .enable_bit = EN_OCPI_CK,
388 .recalc = &followparent_recalc,
389 .enable = &omap1_clk_enable,
390 .disable = &omap1_clk_disable,
391};
392
393static struct clk tc1_ck = {
394 .name = "tc1_ck",
395 .parent = &tc_ck.clk,
396 .flags = CLOCK_IN_OMAP16XX,
397 .enable_reg = (void __iomem *)ARM_IDLECT3,
398 .enable_bit = EN_TC1_CK,
399 .recalc = &followparent_recalc,
400 .enable = &omap1_clk_enable,
401 .disable = &omap1_clk_disable,
402};
403
404static struct clk tc2_ck = {
405 .name = "tc2_ck",
406 .parent = &tc_ck.clk,
407 .flags = CLOCK_IN_OMAP16XX,
408 .enable_reg = (void __iomem *)ARM_IDLECT3,
409 .enable_bit = EN_TC2_CK,
410 .recalc = &followparent_recalc,
411 .enable = &omap1_clk_enable,
412 .disable = &omap1_clk_disable,
413};
414
415static struct clk dma_ck = {
416 /* No-idle controlled by "tc_ck" */
417 .name = "dma_ck",
418 .parent = &tc_ck.clk,
419 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
420 ALWAYS_ENABLED,
421 .recalc = &followparent_recalc,
422 .enable = &omap1_clk_enable,
423 .disable = &omap1_clk_disable,
424};
425
426static struct clk dma_lcdfree_ck = {
427 .name = "dma_lcdfree_ck",
428 .parent = &tc_ck.clk,
429 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
430 .recalc = &followparent_recalc,
431 .enable = &omap1_clk_enable,
432 .disable = &omap1_clk_disable,
433};
434
435static struct arm_idlect1_clk api_ck = {
436 .clk = {
437 .name = "api_ck",
438 .parent = &tc_ck.clk,
439 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
440 CLOCK_IDLE_CONTROL,
441 .enable_reg = (void __iomem *)ARM_IDLECT2,
442 .enable_bit = EN_APICK,
443 .recalc = &followparent_recalc,
444 .enable = &omap1_clk_enable,
445 .disable = &omap1_clk_disable,
446 },
447 .idlect_shift = 8,
448};
449
450static struct arm_idlect1_clk lb_ck = {
451 .clk = {
452 .name = "lb_ck",
453 .parent = &tc_ck.clk,
454 .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL,
455 .enable_reg = (void __iomem *)ARM_IDLECT2,
456 .enable_bit = EN_LBCK,
457 .recalc = &followparent_recalc,
458 .enable = &omap1_clk_enable,
459 .disable = &omap1_clk_disable,
460 },
461 .idlect_shift = 4,
462};
463
464static struct clk rhea1_ck = {
465 .name = "rhea1_ck",
466 .parent = &tc_ck.clk,
467 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
468 .recalc = &followparent_recalc,
469 .enable = &omap1_clk_enable,
470 .disable = &omap1_clk_disable,
471};
472
473static struct clk rhea2_ck = {
474 .name = "rhea2_ck",
475 .parent = &tc_ck.clk,
476 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
477 .recalc = &followparent_recalc,
478 .enable = &omap1_clk_enable,
479 .disable = &omap1_clk_disable,
480};
481
482static struct clk lcd_ck_16xx = {
483 .name = "lcd_ck",
484 .parent = &ck_dpll1,
485 .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL,
486 .enable_reg = (void __iomem *)ARM_IDLECT2,
487 .enable_bit = EN_LCDCK,
488 .rate_offset = CKCTL_LCDDIV_OFFSET,
489 .recalc = &omap1_ckctl_recalc,
490 .enable = &omap1_clk_enable,
491 .disable = &omap1_clk_disable,
492};
493
494static struct arm_idlect1_clk lcd_ck_1510 = {
495 .clk = {
496 .name = "lcd_ck",
497 .parent = &ck_dpll1,
498 .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL |
499 CLOCK_IDLE_CONTROL,
500 .enable_reg = (void __iomem *)ARM_IDLECT2,
501 .enable_bit = EN_LCDCK,
502 .rate_offset = CKCTL_LCDDIV_OFFSET,
503 .recalc = &omap1_ckctl_recalc,
504 .enable = &omap1_clk_enable,
505 .disable = &omap1_clk_disable,
506 },
507 .idlect_shift = 3,
508};
509
510static struct clk uart1_1510 = {
511 .name = "uart1_ck",
512 /* Direct from ULPD, no real parent */
513 .parent = &armper_ck.clk,
514 .rate = 12000000,
515 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
516 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
517 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
518 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
519 .set_rate = &omap1_set_uart_rate,
520 .recalc = &omap1_uart_recalc,
521 .enable = &omap1_clk_enable,
522 .disable = &omap1_clk_disable,
523};
524
525static struct uart_clk uart1_16xx = {
526 .clk = {
527 .name = "uart1_ck",
528 /* Direct from ULPD, no real parent */
529 .parent = &armper_ck.clk,
530 .rate = 48000000,
531 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
532 ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
533 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
534 .enable_bit = 29,
535 .enable = &omap1_clk_enable_uart_functional,
536 .disable = &omap1_clk_disable_uart_functional,
537 },
538 .sysc_addr = 0xfffb0054,
539};
540
541static struct clk uart2_ck = {
542 .name = "uart2_ck",
543 /* Direct from ULPD, no real parent */
544 .parent = &armper_ck.clk,
545 .rate = 12000000,
546 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
547 ENABLE_REG_32BIT | ALWAYS_ENABLED |
548 CLOCK_NO_IDLE_PARENT,
549 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
550 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
551 .set_rate = &omap1_set_uart_rate,
552 .recalc = &omap1_uart_recalc,
553 .enable = &omap1_clk_enable,
554 .disable = &omap1_clk_disable,
555};
556
557static struct clk uart3_1510 = {
558 .name = "uart3_ck",
559 /* Direct from ULPD, no real parent */
560 .parent = &armper_ck.clk,
561 .rate = 12000000,
562 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
563 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
564 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
565 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
566 .set_rate = &omap1_set_uart_rate,
567 .recalc = &omap1_uart_recalc,
568 .enable = &omap1_clk_enable,
569 .disable = &omap1_clk_disable,
570};
571
572static struct uart_clk uart3_16xx = {
573 .clk = {
574 .name = "uart3_ck",
575 /* Direct from ULPD, no real parent */
576 .parent = &armper_ck.clk,
577 .rate = 48000000,
578 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
579 ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
580 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
581 .enable_bit = 31,
582 .enable = &omap1_clk_enable_uart_functional,
583 .disable = &omap1_clk_disable_uart_functional,
584 },
585 .sysc_addr = 0xfffb9854,
586};
587
588static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
589 .name = "usb_clko",
590 /* Direct from ULPD, no parent */
591 .rate = 6000000,
592 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
593 RATE_FIXED | ENABLE_REG_32BIT,
594 .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
595 .enable_bit = USB_MCLK_EN_BIT,
596 .enable = &omap1_clk_enable,
597 .disable = &omap1_clk_disable,
598};
599
600static struct clk usb_hhc_ck1510 = {
601 .name = "usb_hhc_ck",
602 /* Direct from ULPD, no parent */
603 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
604 .flags = CLOCK_IN_OMAP1510 |
605 RATE_FIXED | ENABLE_REG_32BIT,
606 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
607 .enable_bit = USB_HOST_HHC_UHOST_EN,
608 .enable = &omap1_clk_enable,
609 .disable = &omap1_clk_disable,
610};
611
612static struct clk usb_hhc_ck16xx = {
613 .name = "usb_hhc_ck",
614 /* Direct from ULPD, no parent */
615 .rate = 48000000,
616 /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
617 .flags = CLOCK_IN_OMAP16XX |
618 RATE_FIXED | ENABLE_REG_32BIT,
619 .enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
620 .enable_bit = 8 /* UHOST_EN */,
621 .enable = &omap1_clk_enable,
622 .disable = &omap1_clk_disable,
623};
624
625static struct clk usb_dc_ck = {
626 .name = "usb_dc_ck",
627 /* Direct from ULPD, no parent */
628 .rate = 48000000,
629 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
630 .enable_reg = (void __iomem *)SOFT_REQ_REG,
631 .enable_bit = 4,
632 .enable = &omap1_clk_enable,
633 .disable = &omap1_clk_disable,
634};
635
636static struct clk mclk_1510 = {
637 .name = "mclk",
638 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
639 .rate = 12000000,
640 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
641 .enable = &omap1_clk_enable,
642 .disable = &omap1_clk_disable,
643};
644
645static struct clk mclk_16xx = {
646 .name = "mclk",
647 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
648 .flags = CLOCK_IN_OMAP16XX,
649 .enable_reg = (void __iomem *)COM_CLK_DIV_CTRL_SEL,
650 .enable_bit = COM_ULPD_PLL_CLK_REQ,
651 .set_rate = &omap1_set_ext_clk_rate,
652 .round_rate = &omap1_round_ext_clk_rate,
653 .init = &omap1_init_ext_clk,
654 .enable = &omap1_clk_enable,
655 .disable = &omap1_clk_disable,
656};
657
658static struct clk bclk_1510 = {
659 .name = "bclk",
660 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
661 .rate = 12000000,
662 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
663 .enable = &omap1_clk_enable,
664 .disable = &omap1_clk_disable,
665};
666
667static struct clk bclk_16xx = {
668 .name = "bclk",
669 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
670 .flags = CLOCK_IN_OMAP16XX,
671 .enable_reg = (void __iomem *)SWD_CLK_DIV_CTRL_SEL,
672 .enable_bit = SWD_ULPD_PLL_CLK_REQ,
673 .set_rate = &omap1_set_ext_clk_rate,
674 .round_rate = &omap1_round_ext_clk_rate,
675 .init = &omap1_init_ext_clk,
676 .enable = &omap1_clk_enable,
677 .disable = &omap1_clk_disable,
678};
679
680static struct clk mmc1_ck = {
681 .name = "mmc1_ck",
682 /* Functional clock is direct from ULPD, interface clock is ARMPER */
683 .parent = &armper_ck.clk,
684 .rate = 48000000,
685 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
686 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
687 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
688 .enable_bit = 23,
689 .enable = &omap1_clk_enable,
690 .disable = &omap1_clk_disable,
691};
692
693static struct clk mmc2_ck = {
694 .name = "mmc2_ck",
695 /* Functional clock is direct from ULPD, interface clock is ARMPER */
696 .parent = &armper_ck.clk,
697 .rate = 48000000,
698 .flags = CLOCK_IN_OMAP16XX |
699 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
700 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
701 .enable_bit = 20,
702 .enable = &omap1_clk_enable,
703 .disable = &omap1_clk_disable,
704};
705
706static struct clk virtual_ck_mpu = {
707 .name = "mpu",
708 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
709 VIRTUAL_CLOCK | ALWAYS_ENABLED,
710 .parent = &arm_ck, /* Is smarter alias for */
711 .recalc = &followparent_recalc,
712 .set_rate = &omap1_select_table_rate,
713 .round_rate = &omap1_round_to_table_rate,
714 .enable = &omap1_clk_enable,
715 .disable = &omap1_clk_disable,
716};
717
718static struct clk * onchip_clks[] = {
719 /* non-ULPD clocks */
720 &ck_ref,
721 &ck_dpll1,
722 /* CK_GEN1 clocks */
723 &ck_dpll1out.clk,
724 &arm_ck,
725 &armper_ck.clk,
726 &arm_gpio_ck,
727 &armxor_ck.clk,
728 &armtim_ck.clk,
729 &armwdt_ck.clk,
730 &arminth_ck1510, &arminth_ck16xx,
731 /* CK_GEN2 clocks */
732 &dsp_ck,
733 &dspmmu_ck,
734 &dspper_ck,
735 &dspxor_ck,
736 &dsptim_ck,
737 /* CK_GEN3 clocks */
738 &tc_ck.clk,
739 &tipb_ck,
740 &l3_ocpi_ck,
741 &tc1_ck,
742 &tc2_ck,
743 &dma_ck,
744 &dma_lcdfree_ck,
745 &api_ck.clk,
746 &lb_ck.clk,
747 &rhea1_ck,
748 &rhea2_ck,
749 &lcd_ck_16xx,
750 &lcd_ck_1510.clk,
751 /* ULPD clocks */
752 &uart1_1510,
753 &uart1_16xx.clk,
754 &uart2_ck,
755 &uart3_1510,
756 &uart3_16xx.clk,
757 &usb_clko,
758 &usb_hhc_ck1510, &usb_hhc_ck16xx,
759 &usb_dc_ck,
760 &mclk_1510, &mclk_16xx,
761 &bclk_1510, &bclk_16xx,
762 &mmc1_ck,
763 &mmc2_ck,
764 /* Virtual clocks */
765 &virtual_ck_mpu,
766};
767
768#endif
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 3c5d901efeaa..ecbc47514adc 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -25,56 +25,7 @@
25#include <asm/arch/mux.h> 25#include <asm/arch/mux.h>
26#include <asm/arch/gpio.h> 26#include <asm/arch/gpio.h>
27 27
28 28extern void omap_nop_release(struct device *dev);
29static void omap_nop_release(struct device *dev)
30{
31 /* Nothing */
32}
33
34/*-------------------------------------------------------------------------*/
35
36#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
37
38#define OMAP_I2C_BASE 0xfffb3800
39
40static struct resource i2c_resources[] = {
41 {
42 .start = OMAP_I2C_BASE,
43 .end = OMAP_I2C_BASE + 0x3f,
44 .flags = IORESOURCE_MEM,
45 },
46 {
47 .start = INT_I2C,
48 .flags = IORESOURCE_IRQ,
49 },
50};
51
52/* DMA not used; works around erratum writing to non-empty i2c fifo */
53
54static struct platform_device omap_i2c_device = {
55 .name = "i2c_omap",
56 .id = -1,
57 .dev = {
58 .release = omap_nop_release,
59 },
60 .num_resources = ARRAY_SIZE(i2c_resources),
61 .resource = i2c_resources,
62};
63
64static void omap_init_i2c(void)
65{
66 /* FIXME define and use a boot tag, in case of boards that
67 * either don't wire up I2C, or chips that mux it differently...
68 * it can include clocking and address info, maybe more.
69 */
70 omap_cfg_reg(I2C_SCL);
71 omap_cfg_reg(I2C_SDA);
72
73 (void) platform_device_register(&omap_i2c_device);
74}
75#else
76static inline void omap_init_i2c(void) {}
77#endif
78 29
79/*-------------------------------------------------------------------------*/ 30/*-------------------------------------------------------------------------*/
80 31
@@ -110,137 +61,6 @@ static inline void omap_init_irda(void) {}
110 61
111/*-------------------------------------------------------------------------*/ 62/*-------------------------------------------------------------------------*/
112 63
113#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
114
115#define OMAP_MMC1_BASE 0xfffb7800
116#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
117
118static struct omap_mmc_conf mmc1_conf;
119
120static u64 mmc1_dmamask = 0xffffffff;
121
122static struct resource mmc1_resources[] = {
123 {
124 .start = IO_ADDRESS(OMAP_MMC1_BASE),
125 .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
126 .flags = IORESOURCE_MEM,
127 },
128 {
129 .start = INT_MMC,
130 .flags = IORESOURCE_IRQ,
131 },
132};
133
134static struct platform_device mmc_omap_device1 = {
135 .name = "mmci-omap",
136 .id = 1,
137 .dev = {
138 .release = omap_nop_release,
139 .dma_mask = &mmc1_dmamask,
140 .platform_data = &mmc1_conf,
141 },
142 .num_resources = ARRAY_SIZE(mmc1_resources),
143 .resource = mmc1_resources,
144};
145
146#ifdef CONFIG_ARCH_OMAP16XX
147
148static struct omap_mmc_conf mmc2_conf;
149
150static u64 mmc2_dmamask = 0xffffffff;
151
152static struct resource mmc2_resources[] = {
153 {
154 .start = IO_ADDRESS(OMAP_MMC2_BASE),
155 .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
156 .flags = IORESOURCE_MEM,
157 },
158 {
159 .start = INT_1610_MMC2,
160 .flags = IORESOURCE_IRQ,
161 },
162};
163
164static struct platform_device mmc_omap_device2 = {
165 .name = "mmci-omap",
166 .id = 2,
167 .dev = {
168 .release = omap_nop_release,
169 .dma_mask = &mmc2_dmamask,
170 .platform_data = &mmc2_conf,
171 },
172 .num_resources = ARRAY_SIZE(mmc2_resources),
173 .resource = mmc2_resources,
174};
175#endif
176
177static void __init omap_init_mmc(void)
178{
179 const struct omap_mmc_config *mmc_conf;
180 const struct omap_mmc_conf *mmc;
181
182 /* NOTE: assumes MMC was never (wrongly) enabled */
183 mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
184 if (!mmc_conf)
185 return;
186
187 /* block 1 is always available and has just one pinout option */
188 mmc = &mmc_conf->mmc[0];
189 if (mmc->enabled) {
190 omap_cfg_reg(MMC_CMD);
191 omap_cfg_reg(MMC_CLK);
192 omap_cfg_reg(MMC_DAT0);
193 if (cpu_is_omap1710()) {
194 omap_cfg_reg(M15_1710_MMC_CLKI);
195 omap_cfg_reg(P19_1710_MMC_CMDDIR);
196 omap_cfg_reg(P20_1710_MMC_DATDIR0);
197 }
198 if (mmc->wire4) {
199 omap_cfg_reg(MMC_DAT1);
200 /* NOTE: DAT2 can be on W10 (here) or M15 */
201 if (!mmc->nomux)
202 omap_cfg_reg(MMC_DAT2);
203 omap_cfg_reg(MMC_DAT3);
204 }
205 mmc1_conf = *mmc;
206 (void) platform_device_register(&mmc_omap_device1);
207 }
208
209#ifdef CONFIG_ARCH_OMAP16XX
210 /* block 2 is on newer chips, and has many pinout options */
211 mmc = &mmc_conf->mmc[1];
212 if (mmc->enabled) {
213 if (!mmc->nomux) {
214 omap_cfg_reg(Y8_1610_MMC2_CMD);
215 omap_cfg_reg(Y10_1610_MMC2_CLK);
216 omap_cfg_reg(R18_1610_MMC2_CLKIN);
217 omap_cfg_reg(W8_1610_MMC2_DAT0);
218 if (mmc->wire4) {
219 omap_cfg_reg(V8_1610_MMC2_DAT1);
220 omap_cfg_reg(W15_1610_MMC2_DAT2);
221 omap_cfg_reg(R10_1610_MMC2_DAT3);
222 }
223
224 /* These are needed for the level shifter */
225 omap_cfg_reg(V9_1610_MMC2_CMDDIR);
226 omap_cfg_reg(V5_1610_MMC2_DATDIR0);
227 omap_cfg_reg(W19_1610_MMC2_DATDIR1);
228 }
229
230 /* Feedback clock must be set on OMAP-1710 MMC2 */
231 if (cpu_is_omap1710())
232 omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
233 MOD_CONF_CTRL_1);
234 mmc2_conf = *mmc;
235 (void) platform_device_register(&mmc_omap_device2);
236 }
237#endif
238 return;
239}
240#else
241static inline void omap_init_mmc(void) {}
242#endif
243
244#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC) 64#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
245 65
246#define OMAP_RTC_BASE 0xfffb4800 66#define OMAP_RTC_BASE 0xfffb4800
@@ -279,38 +99,6 @@ static void omap_init_rtc(void)
279static inline void omap_init_rtc(void) {} 99static inline void omap_init_rtc(void) {}
280#endif 100#endif
281 101
282/*-------------------------------------------------------------------------*/
283
284#if defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
285
286#define OMAP_WDT_BASE 0xfffeb000
287
288static struct resource wdt_resources[] = {
289 {
290 .start = OMAP_WDT_BASE,
291 .end = OMAP_WDT_BASE + 0x4f,
292 .flags = IORESOURCE_MEM,
293 },
294};
295
296static struct platform_device omap_wdt_device = {
297 .name = "omap1610_wdt",
298 .id = -1,
299 .dev = {
300 .release = omap_nop_release,
301 },
302 .num_resources = ARRAY_SIZE(wdt_resources),
303 .resource = wdt_resources,
304};
305
306static void omap_init_wdt(void)
307{
308 (void) platform_device_register(&omap_wdt_device);
309}
310#else
311static inline void omap_init_wdt(void) {}
312#endif
313
314 102
315/*-------------------------------------------------------------------------*/ 103/*-------------------------------------------------------------------------*/
316 104
@@ -334,18 +122,15 @@ static inline void omap_init_wdt(void) {}
334 * may be handled by the boot loader, and drivers should expect it will 122 * may be handled by the boot loader, and drivers should expect it will
335 * normally have been done by the time they're probed. 123 * normally have been done by the time they're probed.
336 */ 124 */
337static int __init omap_init_devices(void) 125static int __init omap1_init_devices(void)
338{ 126{
339 /* please keep these calls, and their implementations above, 127 /* please keep these calls, and their implementations above,
340 * in alphabetical order so they're easier to sort through. 128 * in alphabetical order so they're easier to sort through.
341 */ 129 */
342 omap_init_i2c();
343 omap_init_irda(); 130 omap_init_irda();
344 omap_init_mmc();
345 omap_init_rtc(); 131 omap_init_rtc();
346 omap_init_wdt();
347 132
348 return 0; 133 return 0;
349} 134}
350arch_initcall(omap_init_devices); 135arch_initcall(omap1_init_devices);
351 136
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
index 986c3b7e09bb..5c637c048368 100644
--- a/arch/arm/mach-omap1/id.c
+++ b/arch/arm/mach-omap1/id.c
@@ -18,6 +18,13 @@
18 18
19#include <asm/io.h> 19#include <asm/io.h>
20 20
21#define OMAP_DIE_ID_0 0xfffe1800
22#define OMAP_DIE_ID_1 0xfffe1804
23#define OMAP_PRODUCTION_ID_0 0xfffe2000
24#define OMAP_PRODUCTION_ID_1 0xfffe2004
25#define OMAP32_ID_0 0xfffed400
26#define OMAP32_ID_1 0xfffed404
27
21struct omap_id { 28struct omap_id {
22 u16 jtag_id; /* Used to determine OMAP type */ 29 u16 jtag_id; /* Used to determine OMAP type */
23 u8 die_rev; /* Processor revision */ 30 u8 die_rev; /* Processor revision */
@@ -27,6 +34,7 @@ struct omap_id {
27 34
28/* Register values to detect the OMAP version */ 35/* Register values to detect the OMAP version */
29static struct omap_id omap_ids[] __initdata = { 36static struct omap_id omap_ids[] __initdata = {
37 { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
30 { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, 38 { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
31 { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, 39 { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
32 { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, 40 { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
@@ -164,6 +172,7 @@ void __init omap_check_revision(void)
164 case 0x07: 172 case 0x07:
165 system_rev |= 0x07; 173 system_rev |= 0x07;
166 break; 174 break;
175 case 0x03:
167 case 0x15: 176 case 0x15:
168 system_rev |= 0x15; 177 system_rev |= 0x15;
169 break; 178 break;
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 79fb86535ebc..a7a19f75b9e1 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -15,9 +15,10 @@
15 15
16#include <asm/mach/map.h> 16#include <asm/mach/map.h>
17#include <asm/io.h> 17#include <asm/io.h>
18#include <asm/arch/mux.h>
18#include <asm/arch/tc.h> 19#include <asm/arch/tc.h>
19 20
20extern int clk_init(void); 21extern int omap1_clk_init(void);
21extern void omap_check_revision(void); 22extern void omap_check_revision(void);
22extern void omap_sram_init(void); 23extern void omap_sram_init(void);
23 24
@@ -50,7 +51,7 @@ static struct map_desc omap730_io_desc[] __initdata = {
50}; 51};
51#endif 52#endif
52 53
53#ifdef CONFIG_ARCH_OMAP1510 54#ifdef CONFIG_ARCH_OMAP15XX
54static struct map_desc omap1510_io_desc[] __initdata = { 55static struct map_desc omap1510_io_desc[] __initdata = {
55 { 56 {
56 .virtual = OMAP1510_DSP_BASE, 57 .virtual = OMAP1510_DSP_BASE,
@@ -98,7 +99,7 @@ static void __init _omap_map_io(void)
98 iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc)); 99 iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
99 } 100 }
100#endif 101#endif
101#ifdef CONFIG_ARCH_OMAP1510 102#ifdef CONFIG_ARCH_OMAP15XX
102 if (cpu_is_omap1510()) { 103 if (cpu_is_omap1510()) {
103 iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); 104 iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
104 } 105 }
@@ -119,7 +120,7 @@ static void __init _omap_map_io(void)
119 120
120 /* Must init clocks early to assure that timer interrupt works 121 /* Must init clocks early to assure that timer interrupt works
121 */ 122 */
122 clk_init(); 123 omap1_clk_init();
123} 124}
124 125
125/* 126/*
@@ -127,7 +128,9 @@ static void __init _omap_map_io(void)
127 */ 128 */
128void __init omap_map_common_io(void) 129void __init omap_map_common_io(void)
129{ 130{
130 if (!initialized) 131 if (!initialized) {
131 _omap_map_io(); 132 _omap_map_io();
133 omap1_mux_init();
134 }
132} 135}
133 136
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 192ce6055faa..ed65a7d2e941 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -47,6 +47,7 @@
47#include <asm/irq.h> 47#include <asm/irq.h>
48#include <asm/mach/irq.h> 48#include <asm/mach/irq.h>
49#include <asm/arch/gpio.h> 49#include <asm/arch/gpio.h>
50#include <asm/arch/cpu.h>
50 51
51#include <asm/io.h> 52#include <asm/io.h>
52 53
@@ -147,11 +148,15 @@ static struct omap_irq_bank omap730_irq_banks[] = {
147}; 148};
148#endif 149#endif
149 150
150#ifdef CONFIG_ARCH_OMAP1510 151#ifdef CONFIG_ARCH_OMAP15XX
151static struct omap_irq_bank omap1510_irq_banks[] = { 152static struct omap_irq_bank omap1510_irq_banks[] = {
152 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, 153 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
153 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, 154 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
154}; 155};
156static struct omap_irq_bank omap310_irq_banks[] = {
157 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
158 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
159};
155#endif 160#endif
156 161
157#if defined(CONFIG_ARCH_OMAP16XX) 162#if defined(CONFIG_ARCH_OMAP16XX)
@@ -181,11 +186,15 @@ void __init omap_init_irq(void)
181 irq_bank_count = ARRAY_SIZE(omap730_irq_banks); 186 irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
182 } 187 }
183#endif 188#endif
184#ifdef CONFIG_ARCH_OMAP1510 189#ifdef CONFIG_ARCH_OMAP15XX
185 if (cpu_is_omap1510()) { 190 if (cpu_is_omap1510()) {
186 irq_banks = omap1510_irq_banks; 191 irq_banks = omap1510_irq_banks;
187 irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); 192 irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
188 } 193 }
194 if (cpu_is_omap310()) {
195 irq_banks = omap310_irq_banks;
196 irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
197 }
189#endif 198#endif
190#if defined(CONFIG_ARCH_OMAP16XX) 199#if defined(CONFIG_ARCH_OMAP16XX)
191 if (cpu_is_omap16xx()) { 200 if (cpu_is_omap16xx()) {
@@ -226,9 +235,11 @@ void __init omap_init_irq(void)
226 } 235 }
227 236
228 /* Unmask level 2 handler */ 237 /* Unmask level 2 handler */
229 if (cpu_is_omap730()) { 238
239 if (cpu_is_omap730())
230 omap_unmask_irq(INT_730_IH2_IRQ); 240 omap_unmask_irq(INT_730_IH2_IRQ);
231 } else { 241 else if (cpu_is_omap1510())
232 omap_unmask_irq(INT_IH2_IRQ); 242 omap_unmask_irq(INT_1510_IH2_IRQ);
233 } 243 else if (cpu_is_omap16xx())
244 omap_unmask_irq(INT_1610_IH2_IRQ);
234} 245}
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
index be283cda63dd..650650815915 100644
--- a/arch/arm/mach-omap1/leds-h2p2-debug.c
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -13,12 +13,12 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel_stat.h> 14#include <linux/kernel_stat.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/version.h>
17 16
18#include <asm/io.h> 17#include <asm/io.h>
19#include <asm/hardware.h> 18#include <asm/hardware.h>
20#include <asm/leds.h> 19#include <asm/leds.h>
21#include <asm/system.h> 20#include <asm/system.h>
21#include <asm/mach-types.h>
22 22
23#include <asm/arch/fpga.h> 23#include <asm/arch/fpga.h>
24#include <asm/arch/gpio.h> 24#include <asm/arch/gpio.h>
@@ -64,14 +64,19 @@ void h2p2_dbg_leds_event(led_event_t evt)
64 case led_stop: 64 case led_stop:
65 case led_halted: 65 case led_halted:
66 /* all leds off during suspend or shutdown */ 66 /* all leds off during suspend or shutdown */
67 omap_set_gpio_dataout(GPIO_TIMER, 0); 67
68 omap_set_gpio_dataout(GPIO_IDLE, 0); 68 if (! machine_is_omap_perseus2()) {
69 omap_set_gpio_dataout(GPIO_TIMER, 0);
70 omap_set_gpio_dataout(GPIO_IDLE, 0);
71 }
72
69 __raw_writew(~0, &fpga->leds); 73 __raw_writew(~0, &fpga->leds);
70 led_state &= ~LED_STATE_ENABLED; 74 led_state &= ~LED_STATE_ENABLED;
71 if (evt == led_halted) { 75 if (evt == led_halted) {
72 iounmap(fpga); 76 iounmap(fpga);
73 fpga = NULL; 77 fpga = NULL;
74 } 78 }
79
75 goto done; 80 goto done;
76 81
77 case led_claim: 82 case led_claim:
@@ -86,18 +91,37 @@ void h2p2_dbg_leds_event(led_event_t evt)
86#ifdef CONFIG_LEDS_TIMER 91#ifdef CONFIG_LEDS_TIMER
87 case led_timer: 92 case led_timer:
88 led_state ^= LED_TIMER_ON; 93 led_state ^= LED_TIMER_ON;
89 omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON); 94
90 goto done; 95 if (machine_is_omap_perseus2())
96 hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
97 else {
98 omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
99 goto done;
100 }
101
102 break;
91#endif 103#endif
92 104
93#ifdef CONFIG_LEDS_CPU 105#ifdef CONFIG_LEDS_CPU
94 case led_idle_start: 106 case led_idle_start:
95 omap_set_gpio_dataout(GPIO_IDLE, 1); 107 if (machine_is_omap_perseus2())
96 goto done; 108 hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
109 else {
110 omap_set_gpio_dataout(GPIO_IDLE, 1);
111 goto done;
112 }
113
114 break;
97 115
98 case led_idle_end: 116 case led_idle_end:
99 omap_set_gpio_dataout(GPIO_IDLE, 0); 117 if (machine_is_omap_perseus2())
100 goto done; 118 hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
119 else {
120 omap_set_gpio_dataout(GPIO_IDLE, 0);
121 goto done;
122 }
123
124 break;
101#endif 125#endif
102 126
103 case led_green_on: 127 case led_green_on:
@@ -136,7 +160,7 @@ void h2p2_dbg_leds_event(led_event_t evt)
136 /* 160 /*
137 * Actually burn the LEDs 161 * Actually burn the LEDs
138 */ 162 */
139 if (led_state & LED_STATE_CLAIMED) 163 if (led_state & LED_STATE_ENABLED)
140 __raw_writew(~hw_led_state, &fpga->leds); 164 __raw_writew(~hw_led_state, &fpga->leds);
141 165
142done: 166done:
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c
index 5c6b1bb6e722..3f9dcac4fd41 100644
--- a/arch/arm/mach-omap1/leds.c
+++ b/arch/arm/mach-omap1/leds.c
@@ -33,7 +33,6 @@ omap_leds_init(void)
33 33
34 if (machine_is_omap_h2() 34 if (machine_is_omap_h2()
35 || machine_is_omap_h3() 35 || machine_is_omap_h3()
36 || machine_is_omap_perseus2()
37#ifdef CONFIG_OMAP_OSK_MISTRAL 36#ifdef CONFIG_OMAP_OSK_MISTRAL
38 || machine_is_omap_osk() 37 || machine_is_omap_osk()
39#endif 38#endif
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
new file mode 100644
index 000000000000..d4b8d624e742
--- /dev/null
+++ b/arch/arm/mach-omap1/mux.c
@@ -0,0 +1,289 @@
1/*
2 * linux/arch/arm/mach-omap1/mux.c
3 *
4 * OMAP1 pin multiplexing configurations
5 *
6 * Copyright (C) 2003 - 2005 Nokia Corporation
7 *
8 * Written by Tony Lindgren <tony.lindgren@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25#include <linux/config.h>
26#include <linux/module.h>
27#include <linux/init.h>
28#include <asm/system.h>
29#include <asm/io.h>
30#include <linux/spinlock.h>
31
32#include <asm/arch/mux.h>
33
34#ifdef CONFIG_OMAP_MUX
35
36#ifdef CONFIG_ARCH_OMAP730
37struct pin_config __initdata_or_module omap730_pins[] = {
38MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0)
39MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0)
40MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0)
41MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0)
42MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0)
43MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0)
44MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0)
45MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0)
46MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0)
47MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0)
48};
49#endif
50
51#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
52struct pin_config __initdata_or_module omap1xxx_pins[] = {
53/*
54 * description mux mode mux pull pull pull pu_pd pu dbg
55 * reg offset mode reg bit ena reg
56 */
57MUX_CFG("UART1_TX", 9, 21, 1, 2, 3, 0, NA, 0, 0)
58MUX_CFG("UART1_RTS", 9, 12, 1, 2, 0, 0, NA, 0, 0)
59
60/* UART2 (COM_UART_GATING), conflicts with USB2 */
61MUX_CFG("UART2_TX", C, 27, 1, 3, 3, 0, NA, 0, 0)
62MUX_CFG("UART2_RX", C, 18, 0, 3, 1, 1, NA, 0, 0)
63MUX_CFG("UART2_CTS", C, 21, 0, 3, 1, 1, NA, 0, 0)
64MUX_CFG("UART2_RTS", C, 24, 1, 3, 2, 0, NA, 0, 0)
65
66/* UART3 (GIGA_UART_GATING) */
67MUX_CFG("UART3_TX", 6, 0, 1, 0, 30, 0, NA, 0, 0)
68MUX_CFG("UART3_RX", 6, 3, 0, 0, 31, 1, NA, 0, 0)
69MUX_CFG("UART3_CTS", 5, 12, 2, 0, 24, 0, NA, 0, 0)
70MUX_CFG("UART3_RTS", 5, 15, 2, 0, 25, 0, NA, 0, 0)
71MUX_CFG("UART3_CLKREQ", 9, 27, 0, 2, 5, 0, NA, 0, 0)
72MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
73MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
74
75/* PWT & PWL, conflicts with UART3 */
76MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
77MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
78
79/* USB internal master generic */
80MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
81MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1)
82/* works around erratum: W4_USB_PUEN and W4_USB_PUDIS are switched! */
83MUX_CFG("W4_USB_PUEN", D, 3, 3, 3, 5, 1, NA, 0, 1)
84MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1)
85MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1)
86MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1)
87
88/* USB1 master */
89MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1)
90MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1)
91MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1)
92MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1)
93MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1)
94MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1)
95MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1)
96MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1)
97MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1)
98MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1)
99MUX_CFG("R13_1710_USB1_SEO", A, 12, 5, 2, 10, 0, NA, 0, 1)
100
101/* USB2 master */
102MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1)
103MUX_CFG("USB2_VP", B, 6, 1, 2, 18, 0, NA, 0, 1)
104MUX_CFG("USB2_TXEN", B, 9, 1, 2, 19, 0, NA, 0, 1)
105MUX_CFG("USB2_VM", C, 18, 1, 3, 0, 0, NA, 0, 1)
106MUX_CFG("USB2_RCV", C, 21, 1, 3, 1, 0, NA, 0, 1)
107MUX_CFG("USB2_SE0", C, 24, 2, 3, 2, 0, NA, 0, 1)
108MUX_CFG("USB2_TXD", C, 27, 2, 3, 3, 0, NA, 0, 1)
109
110/* OMAP-1510 GPIO */
111MUX_CFG("R18_1510_GPIO0", 7, 9, 0, 1, 11, 1, 0, 0, 1)
112MUX_CFG("R19_1510_GPIO1", 7, 6, 0, 1, 10, 1, 0, 0, 1)
113MUX_CFG("M14_1510_GPIO2", 7, 3, 0, 1, 9, 1, 0, 0, 1)
114
115/* OMAP1610 GPIO */
116MUX_CFG("P18_1610_GPIO3", 7, 0, 0, 1, 8, 0, NA, 0, 1)
117MUX_CFG("Y15_1610_GPIO17", A, 0, 7, 2, 6, 0, NA, 0, 1)
118
119/* OMAP-1710 GPIO */
120MUX_CFG("R18_1710_GPIO0", 7, 9, 0, 1, 11, 1, 1, 1, 1)
121MUX_CFG("V2_1710_GPIO10", F, 27, 1, 4, 3, 1, 4, 1, 1)
122MUX_CFG("N21_1710_GPIO14", 6, 9, 0, 1, 1, 1, 1, 1, 1)
123MUX_CFG("W15_1710_GPIO40", 9, 27, 7, 2, 5, 1, 2, 1, 1)
124
125/* MPUIO */
126MUX_CFG("MPUIO2", 7, 18, 0, 1, 14, 1, NA, 0, 1)
127MUX_CFG("N15_1610_MPUIO2", 7, 18, 0, 1, 14, 1, 1, 0, 1)
128MUX_CFG("MPUIO4", 7, 15, 0, 1, 13, 1, NA, 0, 1)
129MUX_CFG("MPUIO5", 7, 12, 0, 1, 12, 1, NA, 0, 1)
130
131MUX_CFG("T20_1610_MPUIO5", 7, 12, 0, 1, 12, 0, 3, 0, 1)
132MUX_CFG("W11_1610_MPUIO6", 10, 15, 2, 3, 8, 0, 3, 0, 1)
133MUX_CFG("V10_1610_MPUIO7", A, 24, 2, 2, 14, 0, 2, 0, 1)
134MUX_CFG("W11_1610_MPUIO9", 10, 15, 1, 3, 8, 0, 3, 0, 1)
135MUX_CFG("V10_1610_MPUIO10", A, 24, 1, 2, 14, 0, 2, 0, 1)
136MUX_CFG("W10_1610_MPUIO11", A, 18, 2, 2, 11, 0, 2, 0, 1)
137MUX_CFG("E20_1610_MPUIO13", 3, 21, 1, 0, 7, 0, 0, 0, 1)
138MUX_CFG("U20_1610_MPUIO14", 9, 6, 6, 0, 30, 0, 0, 0, 1)
139MUX_CFG("E19_1610_MPUIO15", 3, 18, 1, 0, 6, 0, 0, 0, 1)
140
141/* MCBSP2 */
142MUX_CFG("MCBSP2_CLKR", C, 6, 0, 2, 27, 1, NA, 0, 1)
143MUX_CFG("MCBSP2_CLKX", C, 9, 0, 2, 29, 1, NA, 0, 1)
144MUX_CFG("MCBSP2_DR", C, 0, 0, 2, 26, 1, NA, 0, 1)
145MUX_CFG("MCBSP2_DX", C, 15, 0, 2, 31, 1, NA, 0, 1)
146MUX_CFG("MCBSP2_FSR", C, 12, 0, 2, 30, 1, NA, 0, 1)
147MUX_CFG("MCBSP2_FSX", C, 3, 0, 2, 27, 1, NA, 0, 1)
148
149/* MCBSP3 NOTE: Mode must 1 for clock */
150MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
151
152/* Misc ballouts */
153MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
154MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
155
156/* OMAP-1610 MMC2 */
157MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
158MUX_CFG("V8_1610_MMC2_DAT1", B, 27, 6, 2, 25, 1, 2, 1, 1)
159MUX_CFG("W15_1610_MMC2_DAT2", 9, 12, 6, 2, 5, 1, 2, 1, 1)
160MUX_CFG("R10_1610_MMC2_DAT3", B, 18, 6, 2, 22, 1, 2, 1, 1)
161MUX_CFG("Y10_1610_MMC2_CLK", B, 3, 6, 2, 17, 0, 2, 0, 1)
162MUX_CFG("Y8_1610_MMC2_CMD", B, 24, 6, 2, 24, 1, 2, 1, 1)
163MUX_CFG("V9_1610_MMC2_CMDDIR", B, 12, 6, 2, 20, 0, 2, 1, 1)
164MUX_CFG("V5_1610_MMC2_DATDIR0", B, 15, 6, 2, 21, 0, 2, 1, 1)
165MUX_CFG("W19_1610_MMC2_DATDIR1", 8, 15, 6, 1, 23, 0, 1, 1, 1)
166MUX_CFG("R18_1610_MMC2_CLKIN", 7, 9, 6, 1, 11, 0, 1, 11, 1)
167
168/* OMAP-1610 External Trace Interface */
169MUX_CFG("M19_1610_ETM_PSTAT0", 5, 27, 1, 0, 29, 0, 0, 0, 1)
170MUX_CFG("L15_1610_ETM_PSTAT1", 5, 24, 1, 0, 28, 0, 0, 0, 1)
171MUX_CFG("L18_1610_ETM_PSTAT2", 5, 21, 1, 0, 27, 0, 0, 0, 1)
172MUX_CFG("L19_1610_ETM_D0", 5, 18, 1, 0, 26, 0, 0, 0, 1)
173MUX_CFG("J19_1610_ETM_D6", 5, 0, 1, 0, 20, 0, 0, 0, 1)
174MUX_CFG("J18_1610_ETM_D7", 5, 27, 1, 0, 19, 0, 0, 0, 1)
175
176/* OMAP16XX GPIO */
177MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1)
178MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1)
179MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1)
180MUX_CFG("N20_1610_GPIO11", 6, 18, 0, 1, 4, 0, 1, 1, 1)
181MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1)
182MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1)
183MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1)
184MUX_CFG("AA20_1610_GPIO_41", 9, 9, 7, 1, 31, 0, 1, 1, 1)
185MUX_CFG("W19_1610_GPIO48", 8, 15, 7, 1, 23, 1, 1, 0, 1)
186MUX_CFG("M7_1610_GPIO62", 10, 0, 0, 4, 24, 0, 4, 0, 1)
187MUX_CFG("V14_16XX_GPIO37", 9, 18, 7, 2, 2, 0, 2, 2, 0)
188MUX_CFG("R9_16XX_GPIO18", C, 18, 7, 3, 0, 0, 3, 0, 0)
189MUX_CFG("L14_16XX_GPIO49", 6, 3, 7, 0, 31, 0, 0, 31, 0)
190
191/* OMAP-1610 uWire */
192MUX_CFG("V19_1610_UWIRE_SCLK", 8, 6, 0, 1, 20, 0, 1, 1, 1)
193MUX_CFG("U18_1610_UWIRE_SDI", 8, 0, 0, 1, 18, 0, 1, 1, 1)
194MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1)
195MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
196MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
197MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
198
199/* OMAP-1610 Flash */
200MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
201MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
202
203/* First MMC interface, same on 1510, 1610 and 1710 */
204MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1)
205MUX_CFG("MMC_DAT1", A, 24, 0, 2, 14, 1, 2, 1, 1)
206MUX_CFG("MMC_DAT2", A, 18, 0, 2, 12, 1, 2, 1, 1)
207MUX_CFG("MMC_DAT0", B, 0, 0, 2, 16, 1, 2, 1, 1)
208MUX_CFG("MMC_CLK", A, 21, 0, NA, 0, 0, NA, 0, 1)
209MUX_CFG("MMC_DAT3", 10, 15, 0, 3, 8, 1, 3, 1, 1)
210MUX_CFG("M15_1710_MMC_CLKI", 6, 21, 2, 0, 0, 0, NA, 0, 1)
211MUX_CFG("P19_1710_MMC_CMDDIR", 6, 24, 6, 0, 0, 0, NA, 0, 1)
212MUX_CFG("P20_1710_MMC_DATDIR0", 6, 27, 5, 0, 0, 0, NA, 0, 1)
213
214/* OMAP-1610 USB0 alternate configuration */
215MUX_CFG("W9_USB0_TXEN", B, 9, 5, 2, 19, 0, 2, 0, 1)
216MUX_CFG("AA9_USB0_VP", B, 6, 5, 2, 18, 0, 2, 0, 1)
217MUX_CFG("Y5_USB0_RCV", C, 21, 5, 3, 1, 0, 1, 0, 1)
218MUX_CFG("R9_USB0_VM", C, 18, 5, 3, 0, 0, 3, 0, 1)
219MUX_CFG("V6_USB0_TXD", C, 27, 5, 3, 3, 0, 3, 0, 1)
220MUX_CFG("W5_USB0_SE0", C, 24, 5, 3, 2, 0, 3, 0, 1)
221MUX_CFG("V9_USB0_SPEED", B, 12, 5, 2, 20, 0, 2, 0, 1)
222MUX_CFG("Y10_USB0_SUSP", B, 3, 5, 2, 17, 0, 2, 0, 1)
223
224/* USB2 interface */
225MUX_CFG("W9_USB2_TXEN", B, 9, 1, NA, 0, 0, NA, 0, 1)
226MUX_CFG("AA9_USB2_VP", B, 6, 1, NA, 0, 0, NA, 0, 1)
227MUX_CFG("Y5_USB2_RCV", C, 21, 1, NA, 0, 0, NA, 0, 1)
228MUX_CFG("R9_USB2_VM", C, 18, 1, NA, 0, 0, NA, 0, 1)
229MUX_CFG("V6_USB2_TXD", C, 27, 2, NA, 0, 0, NA, 0, 1)
230MUX_CFG("W5_USB2_SE0", C, 24, 2, NA, 0, 0, NA, 0, 1)
231
232/* 16XX UART */
233MUX_CFG("R13_1610_UART1_TX", A, 12, 6, 2, 10, 0, 2, 10, 1)
234MUX_CFG("V14_16XX_UART1_RX", 9, 18, 0, 2, 2, 0, 2, 2, 1)
235MUX_CFG("R14_1610_UART1_CTS", 9, 15, 0, 2, 1, 0, 2, 1, 1)
236MUX_CFG("AA15_1610_UART1_RTS", 9, 12, 1, 2, 0, 0, 2, 0, 1)
237MUX_CFG("R9_16XX_UART2_RX", C, 18, 0, 3, 0, 0, 3, 0, 1)
238MUX_CFG("L14_16XX_UART3_RX", 6, 3, 0, 0, 31, 0, 0, 31, 1)
239
240/* I2C interface */
241MUX_CFG("I2C_SCL", 7, 24, 0, NA, 0, 0, NA, 0, 0)
242MUX_CFG("I2C_SDA", 7, 27, 0, NA, 0, 0, NA, 0, 0)
243
244/* Keypad */
245MUX_CFG("F18_1610_KBC0", 3, 15, 0, 0, 5, 1, 0, 0, 0)
246MUX_CFG("D20_1610_KBC1", 3, 12, 0, 0, 4, 1, 0, 0, 0)
247MUX_CFG("D19_1610_KBC2", 3, 9, 0, 0, 3, 1, 0, 0, 0)
248MUX_CFG("E18_1610_KBC3", 3, 6, 0, 0, 2, 1, 0, 0, 0)
249MUX_CFG("C21_1610_KBC4", 3, 3, 0, 0, 1, 1, 0, 0, 0)
250MUX_CFG("G18_1610_KBR0", 4, 0, 0, 0, 10, 1, 0, 1, 0)
251MUX_CFG("F19_1610_KBR1", 3, 27, 0, 0, 9, 1, 0, 1, 0)
252MUX_CFG("H14_1610_KBR2", 3, 24, 0, 0, 8, 1, 0, 1, 0)
253MUX_CFG("E20_1610_KBR3", 3, 21, 0, 0, 7, 1, 0, 1, 0)
254MUX_CFG("E19_1610_KBR4", 3, 18, 0, 0, 6, 1, 0, 1, 0)
255MUX_CFG("N19_1610_KBR5", 6, 12, 1, 1, 2, 1, 1, 1, 0)
256
257/* Power management */
258MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0)
259
260/* MCLK Settings */
261MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0)
262MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0)
263MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0)
264MUX_CFG("R10_1610_MCLK_OFF", B, 18, 6, 2, 22, 1, 2, 1, 1)
265
266/* CompactFlash controller, conflicts with MMC1 */
267MUX_CFG("P11_1610_CF_CD2", A, 27, 3, 2, 15, 1, 2, 1, 1)
268MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1)
269MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1)
270MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1)
271MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1)
272};
273#endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
274
275int __init omap1_mux_init(void)
276{
277
278#ifdef CONFIG_ARCH_OMAP730
279 omap_mux_register(omap730_pins, ARRAY_SIZE(omap730_pins));
280#endif
281
282#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
283 omap_mux_register(omap1xxx_pins, ARRAY_SIZE(omap1xxx_pins));
284#endif
285
286 return 0;
287}
288
289#endif
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 40c4f7c40e73..6810cfb84462 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -109,9 +109,10 @@ static struct platform_device serial_device = {
109 * By default UART2 does not work on Innovator-1510 if you have 109 * By default UART2 does not work on Innovator-1510 if you have
110 * USB OHCI enabled. To use UART2, you must disable USB2 first. 110 * USB OHCI enabled. To use UART2, you must disable USB2 first.
111 */ 111 */
112void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) 112void __init omap_serial_init(void)
113{ 113{
114 int i; 114 int i;
115 const struct omap_uart_config *info;
115 116
116 if (cpu_is_omap730()) { 117 if (cpu_is_omap730()) {
117 serial_platform_data[0].regshift = 0; 118 serial_platform_data[0].regshift = 0;
@@ -126,10 +127,14 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
126 serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; 127 serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
127 } 128 }
128 129
130 info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
131 if (info == NULL)
132 return;
133
129 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { 134 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
130 unsigned char reg; 135 unsigned char reg;
131 136
132 if (ports[i] == 0) { 137 if (!((1 << i) & info->enabled_uarts)) {
133 serial_platform_data[i].membase = NULL; 138 serial_platform_data[i].membase = NULL;
134 serial_platform_data[i].mapbase = 0; 139 serial_platform_data[i].mapbase = 0;
135 continue; 140 continue;
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 191a9b1ee9b7..cdbf4d7620c6 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -226,8 +226,8 @@ unsigned long long sched_clock(void)
226 226
227#ifdef CONFIG_OMAP_32K_TIMER 227#ifdef CONFIG_OMAP_32K_TIMER
228 228
229#ifdef CONFIG_ARCH_OMAP1510 229#ifdef CONFIG_ARCH_OMAP15XX
230#error OMAP 32KHz timer does not currently work on 1510! 230#error OMAP 32KHz timer does not currently work on 15XX!
231#endif 231#endif
232 232
233/* 233/*
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
new file mode 100644
index 000000000000..578880943cf2
--- /dev/null
+++ b/arch/arm/mach-omap2/Kconfig
@@ -0,0 +1,22 @@
1comment "OMAP Core Type"
2 depends on ARCH_OMAP2
3
4config ARCH_OMAP24XX
5 bool "OMAP24xx Based System"
6 depends on ARCH_OMAP2
7
8config ARCH_OMAP2420
9 bool "OMAP2420 support"
10 depends on ARCH_OMAP24XX
11
12comment "OMAP Board Type"
13 depends on ARCH_OMAP2
14
15config MACH_OMAP_GENERIC
16 bool "Generic OMAP board"
17 depends on ARCH_OMAP2 && ARCH_OMAP24XX
18
19config MACH_OMAP_H4
20 bool "OMAP 2420 H4 board"
21 depends on ARCH_OMAP2 && ARCH_OMAP24XX
22
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
new file mode 100644
index 000000000000..42041166435c
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile
@@ -0,0 +1,13 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Common support
6obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o
7
8obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o
9
10# Specific board support
11obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
12obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
13
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot
new file mode 100644
index 000000000000..565aff7f37a9
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x80008000
2params_phys-y := 0x80000100
3initrd_phys-y := 0x80800000
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
new file mode 100644
index 000000000000..c602e7a3d93e
--- /dev/null
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -0,0 +1,80 @@
1/*
2 * linux/arch/arm/mach-omap/omap2/board-generic.c
3 *
4 * Copyright (C) 2005 Nokia Corporation
5 * Author: Paul Mundt <paul.mundt@nokia.com>
6 *
7 * Modified from mach-omap/omap1/board-generic.c
8 *
9 * Code for generic OMAP2 board. Should work on many OMAP2 systems where
10 * the bootloader passes the board-specific data to the kernel.
11 * Do not put any board specific code to this file; create a new machine
12 * type if you need custom low-level initializations.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/device.h>
22
23#include <asm/hardware.h>
24#include <asm/mach-types.h>
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27
28#include <asm/arch/gpio.h>
29#include <asm/arch/mux.h>
30#include <asm/arch/usb.h>
31#include <asm/arch/board.h>
32#include <asm/arch/common.h>
33
34static void __init omap_generic_init_irq(void)
35{
36 omap_init_irq();
37}
38
39static struct omap_uart_config generic_uart_config __initdata = {
40 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
41};
42
43static struct omap_mmc_config generic_mmc_config __initdata = {
44 .mmc [0] = {
45 .enabled = 0,
46 .wire4 = 0,
47 .wp_pin = -1,
48 .power_pin = -1,
49 .switch_pin = -1,
50 },
51};
52
53static struct omap_board_config_kernel generic_config[] = {
54 { OMAP_TAG_UART, &generic_uart_config },
55 { OMAP_TAG_MMC, &generic_mmc_config },
56};
57
58static void __init omap_generic_init(void)
59{
60 omap_board_config = generic_config;
61 omap_board_config_size = ARRAY_SIZE(generic_config);
62 omap_serial_init();
63}
64
65static void __init omap_generic_map_io(void)
66{
67 omap_map_common_io();
68}
69
70MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
71 /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
72 .phys_ram = 0x80000000,
73 .phys_io = 0x48000000,
74 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
75 .boot_params = 0x80000100,
76 .map_io = omap_generic_map_io,
77 .init_irq = omap_generic_init_irq,
78 .init_machine = omap_generic_init,
79 .timer = &omap_timer,
80MACHINE_END
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
new file mode 100644
index 000000000000..f2554469a76a
--- /dev/null
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -0,0 +1,197 @@
1/*
2 * linux/arch/arm/mach-omap/omap2/board-h4.c
3 *
4 * Copyright (C) 2005 Nokia Corporation
5 * Author: Paul Mundt <paul.mundt@nokia.com>
6 *
7 * Modified from mach-omap/omap1/board-generic.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/partitions.h>
19#include <linux/delay.h>
20
21#include <asm/hardware.h>
22#include <asm/mach-types.h>
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25#include <asm/mach/flash.h>
26
27#include <asm/arch/gpio.h>
28#include <asm/arch/mux.h>
29#include <asm/arch/usb.h>
30#include <asm/arch/board.h>
31#include <asm/arch/common.h>
32#include <asm/arch/prcm.h>
33
34#include <asm/io.h>
35#include <asm/delay.h>
36
37static struct mtd_partition h4_partitions[] = {
38 /* bootloader (U-Boot, etc) in first sector */
39 {
40 .name = "bootloader",
41 .offset = 0,
42 .size = SZ_128K,
43 .mask_flags = MTD_WRITEABLE, /* force read-only */
44 },
45 /* bootloader params in the next sector */
46 {
47 .name = "params",
48 .offset = MTDPART_OFS_APPEND,
49 .size = SZ_128K,
50 .mask_flags = 0,
51 },
52 /* kernel */
53 {
54 .name = "kernel",
55 .offset = MTDPART_OFS_APPEND,
56 .size = SZ_2M,
57 .mask_flags = 0
58 },
59 /* file system */
60 {
61 .name = "filesystem",
62 .offset = MTDPART_OFS_APPEND,
63 .size = MTDPART_SIZ_FULL,
64 .mask_flags = 0
65 }
66};
67
68static struct flash_platform_data h4_flash_data = {
69 .map_name = "cfi_probe",
70 .width = 2,
71 .parts = h4_partitions,
72 .nr_parts = ARRAY_SIZE(h4_partitions),
73};
74
75static struct resource h4_flash_resource = {
76 .start = H4_CS0_BASE,
77 .end = H4_CS0_BASE + SZ_64M - 1,
78 .flags = IORESOURCE_MEM,
79};
80
81static struct platform_device h4_flash_device = {
82 .name = "omapflash",
83 .id = 0,
84 .dev = {
85 .platform_data = &h4_flash_data,
86 },
87 .num_resources = 1,
88 .resource = &h4_flash_resource,
89};
90
91static struct resource h4_smc91x_resources[] = {
92 [0] = {
93 .start = OMAP24XX_ETHR_START, /* Physical */
94 .end = OMAP24XX_ETHR_START + 0xf,
95 .flags = IORESOURCE_MEM,
96 },
97 [1] = {
98 .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
99 .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
100 .flags = IORESOURCE_IRQ,
101 },
102};
103
104static struct platform_device h4_smc91x_device = {
105 .name = "smc91x",
106 .id = -1,
107 .num_resources = ARRAY_SIZE(h4_smc91x_resources),
108 .resource = h4_smc91x_resources,
109};
110
111static struct platform_device *h4_devices[] __initdata = {
112 &h4_smc91x_device,
113 &h4_flash_device,
114};
115
116static inline void __init h4_init_smc91x(void)
117{
118 /* Make sure CS1 timings are correct */
119 GPMC_CONFIG1_1 = 0x00011200;
120 GPMC_CONFIG2_1 = 0x001f1f01;
121 GPMC_CONFIG3_1 = 0x00080803;
122 GPMC_CONFIG4_1 = 0x1c091c09;
123 GPMC_CONFIG5_1 = 0x041f1f1f;
124 GPMC_CONFIG6_1 = 0x000004c4;
125 GPMC_CONFIG7_1 = 0x00000f40 | (0x08000000 >> 24);
126 udelay(100);
127
128 omap_cfg_reg(M15_24XX_GPIO92);
129 if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) {
130 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
131 OMAP24XX_ETHR_GPIO_IRQ);
132 return;
133 }
134 omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
135}
136
137static void __init omap_h4_init_irq(void)
138{
139 omap_init_irq();
140 omap_gpio_init();
141 h4_init_smc91x();
142}
143
144static struct omap_uart_config h4_uart_config __initdata = {
145 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
146};
147
148static struct omap_mmc_config h4_mmc_config __initdata = {
149 .mmc [0] = {
150 .enabled = 1,
151 .wire4 = 1,
152 .wp_pin = -1,
153 .power_pin = -1,
154 .switch_pin = -1,
155 },
156};
157
158static struct omap_lcd_config h4_lcd_config __initdata = {
159 .panel_name = "h4",
160 .ctrl_name = "internal",
161};
162
163static struct omap_board_config_kernel h4_config[] = {
164 { OMAP_TAG_UART, &h4_uart_config },
165 { OMAP_TAG_MMC, &h4_mmc_config },
166 { OMAP_TAG_LCD, &h4_lcd_config },
167};
168
169static void __init omap_h4_init(void)
170{
171 /*
172 * Make sure the serial ports are muxed on at this point.
173 * You have to mux them off in device drivers later on
174 * if not needed.
175 */
176 platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
177 omap_board_config = h4_config;
178 omap_board_config_size = ARRAY_SIZE(h4_config);
179 omap_serial_init();
180}
181
182static void __init omap_h4_map_io(void)
183{
184 omap_map_common_io();
185}
186
187MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
188 /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
189 .phys_ram = 0x80000000,
190 .phys_io = 0x48000000,
191 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
192 .boot_params = 0x80000100,
193 .map_io = omap_h4_map_io,
194 .init_irq = omap_h4_init_irq,
195 .init_machine = omap_h4_init,
196 .timer = &omap_timer,
197MACHINE_END
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
new file mode 100644
index 000000000000..85818d9f2635
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.c
@@ -0,0 +1,1129 @@
1/*
2 * linux/arch/arm/mach-omap2/clock.c
3 *
4 * Copyright (C) 2005 Texas Instruments Inc.
5 * Richard Woodruff <r-woodruff2@ti.com>
6 * Created for OMAP2.
7 *
8 * Cleaned up and modified to use omap shared clock framework by
9 * Tony Lindgren <tony@atomide.com>
10 *
11 * Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation
12 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/device.h>
22#include <linux/list.h>
23#include <linux/errno.h>
24#include <linux/delay.h>
25
26#include <asm/io.h>
27
28#include <asm/hardware/clock.h>
29#include <asm/arch/clock.h>
30#include <asm/arch/sram.h>
31#include <asm/arch/prcm.h>
32
33#include "clock.h"
34
35//#define DOWN_VARIABLE_DPLL 1 /* Experimental */
36
37static struct prcm_config *curr_prcm_set;
38static struct memory_timings mem_timings;
39static u32 curr_perf_level = PRCM_FULL_SPEED;
40
41/*-------------------------------------------------------------------------
42 * Omap2 specific clock functions
43 *-------------------------------------------------------------------------*/
44
45/* Recalculate SYST_CLK */
46static void omap2_sys_clk_recalc(struct clk * clk)
47{
48 u32 div = PRCM_CLKSRC_CTRL;
49 div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */
50 div >>= clk->rate_offset;
51 clk->rate = (clk->parent->rate / div);
52 propagate_rate(clk);
53}
54
55static u32 omap2_get_dpll_rate(struct clk * tclk)
56{
57 int dpll_clk, dpll_mult, dpll_div, amult;
58
59 dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */
60 dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */
61 dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
62 amult = CM_CLKSEL2_PLL & 0x3;
63 dpll_clk *= amult;
64
65 return dpll_clk;
66}
67
68static void omap2_followparent_recalc(struct clk *clk)
69{
70 followparent_recalc(clk);
71}
72
73static void omap2_propagate_rate(struct clk * clk)
74{
75 if (!(clk->flags & RATE_FIXED))
76 clk->rate = clk->parent->rate;
77
78 propagate_rate(clk);
79}
80
81/* Enable an APLL if off */
82static void omap2_clk_fixed_enable(struct clk *clk)
83{
84 u32 cval, i=0;
85
86 if (clk->enable_bit == 0xff) /* Parent will do it */
87 return;
88
89 cval = CM_CLKEN_PLL;
90
91 if ((cval & (0x3 << clk->enable_bit)) == (0x3 << clk->enable_bit))
92 return;
93
94 cval &= ~(0x3 << clk->enable_bit);
95 cval |= (0x3 << clk->enable_bit);
96 CM_CLKEN_PLL = cval;
97
98 if (clk == &apll96_ck)
99 cval = (1 << 8);
100 else if (clk == &apll54_ck)
101 cval = (1 << 6);
102
103 while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */
104 ++i;
105 udelay(1);
106 if (i == 100000)
107 break;
108 }
109}
110
111/* Enables clock without considering parent dependencies or use count
112 * REVISIT: Maybe change this to use clk->enable like on omap1?
113 */
114static int omap2_clk_enable(struct clk * clk)
115{
116 u32 regval32;
117
118 if (clk->flags & ALWAYS_ENABLED)
119 return 0;
120
121 if (unlikely(clk->enable_reg == 0)) {
122 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
123 clk->name);
124 return 0;
125 }
126
127 if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
128 omap2_clk_fixed_enable(clk);
129 return 0;
130 }
131
132 regval32 = __raw_readl(clk->enable_reg);
133 regval32 |= (1 << clk->enable_bit);
134 __raw_writel(regval32, clk->enable_reg);
135
136 return 0;
137}
138
139/* Stop APLL */
140static void omap2_clk_fixed_disable(struct clk *clk)
141{
142 u32 cval;
143
144 if(clk->enable_bit == 0xff) /* let parent off do it */
145 return;
146
147 cval = CM_CLKEN_PLL;
148 cval &= ~(0x3 << clk->enable_bit);
149 CM_CLKEN_PLL = cval;
150}
151
152/* Disables clock without considering parent dependencies or use count */
153static void omap2_clk_disable(struct clk *clk)
154{
155 u32 regval32;
156
157 if (clk->enable_reg == 0)
158 return;
159
160 if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
161 omap2_clk_fixed_disable(clk);
162 return;
163 }
164
165 regval32 = __raw_readl(clk->enable_reg);
166 regval32 &= ~(1 << clk->enable_bit);
167 __raw_writel(regval32, clk->enable_reg);
168}
169
170static int omap2_clk_use(struct clk *clk)
171{
172 int ret = 0;
173
174 if (clk->usecount++ == 0) {
175 if (likely((u32)clk->parent))
176 ret = omap2_clk_use(clk->parent);
177
178 if (unlikely(ret != 0)) {
179 clk->usecount--;
180 return ret;
181 }
182
183 ret = omap2_clk_enable(clk);
184
185 if (unlikely(ret != 0) && clk->parent) {
186 omap2_clk_unuse(clk->parent);
187 clk->usecount--;
188 }
189 }
190
191 return ret;
192}
193
194static void omap2_clk_unuse(struct clk *clk)
195{
196 if (clk->usecount > 0 && !(--clk->usecount)) {
197 omap2_clk_disable(clk);
198 if (likely((u32)clk->parent))
199 omap2_clk_unuse(clk->parent);
200 }
201}
202
203/*
204 * Uses the current prcm set to tell if a rate is valid.
205 * You can go slower, but not faster within a given rate set.
206 */
207static u32 omap2_dpll_round_rate(unsigned long target_rate)
208{
209 u32 high, low;
210
211 if ((CM_CLKSEL2_PLL & 0x3) == 1) { /* DPLL clockout */
212 high = curr_prcm_set->dpll_speed * 2;
213 low = curr_prcm_set->dpll_speed;
214 } else { /* DPLL clockout x 2 */
215 high = curr_prcm_set->dpll_speed;
216 low = curr_prcm_set->dpll_speed / 2;
217 }
218
219#ifdef DOWN_VARIABLE_DPLL
220 if (target_rate > high)
221 return high;
222 else
223 return target_rate;
224#else
225 if (target_rate > low)
226 return high;
227 else
228 return low;
229#endif
230
231}
232
233/*
234 * Used for clocks that are part of CLKSEL_xyz governed clocks.
235 * REVISIT: Maybe change to use clk->enable() functions like on omap1?
236 */
237static void omap2_clksel_recalc(struct clk * clk)
238{
239 u32 fixed = 0, div = 0;
240
241 if (clk == &dpll_ck) {
242 clk->rate = omap2_get_dpll_rate(clk);
243 fixed = 1;
244 div = 0;
245 }
246
247 if (clk == &iva1_mpu_int_ifck) {
248 div = 2;
249 fixed = 1;
250 }
251
252 if ((clk == &dss1_fck) && ((CM_CLKSEL1_CORE & (0x1f << 8)) == 0)) {
253 clk->rate = sys_ck.rate;
254 return;
255 }
256
257 if (!fixed) {
258 div = omap2_clksel_get_divisor(clk);
259 if (div == 0)
260 return;
261 }
262
263 if (div != 0) {
264 if (unlikely(clk->rate == clk->parent->rate / div))
265 return;
266 clk->rate = clk->parent->rate / div;
267 }
268
269 if (unlikely(clk->flags & RATE_PROPAGATES))
270 propagate_rate(clk);
271}
272
273/*
274 * Finds best divider value in an array based on the source and target
275 * rates. The divider array must be sorted with smallest divider first.
276 */
277static inline u32 omap2_divider_from_table(u32 size, u32 *div_array,
278 u32 src_rate, u32 tgt_rate)
279{
280 int i, test_rate;
281
282 if (div_array == NULL)
283 return ~1;
284
285 for (i=0; i < size; i++) {
286 test_rate = src_rate / *div_array;
287 if (test_rate <= tgt_rate)
288 return *div_array;
289 ++div_array;
290 }
291
292 return ~0; /* No acceptable divider */
293}
294
295/*
296 * Find divisor for the given clock and target rate.
297 *
298 * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
299 * they are only settable as part of virtual_prcm set.
300 */
301static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate,
302 u32 *new_div)
303{
304 u32 gfx_div[] = {2, 3, 4};
305 u32 sysclkout_div[] = {1, 2, 4, 8, 16};
306 u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
307 u32 vylnq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
308 u32 best_div = ~0, asize = 0;
309 u32 *div_array = NULL;
310
311 switch (tclk->flags & SRC_RATE_SEL_MASK) {
312 case CM_GFX_SEL1:
313 asize = 3;
314 div_array = gfx_div;
315 break;
316 case CM_PLL_SEL1:
317 return omap2_dpll_round_rate(target_rate);
318 case CM_SYSCLKOUT_SEL1:
319 asize = 5;
320 div_array = sysclkout_div;
321 break;
322 case CM_CORE_SEL1:
323 if(tclk == &dss1_fck){
324 if(tclk->parent == &core_ck){
325 asize = 10;
326 div_array = dss1_div;
327 } else {
328 *new_div = 0; /* fixed clk */
329 return(tclk->parent->rate);
330 }
331 } else if((tclk == &vlynq_fck) && cpu_is_omap2420()){
332 if(tclk->parent == &core_ck){
333 asize = 10;
334 div_array = vylnq_div;
335 } else {
336 *new_div = 0; /* fixed clk */
337 return(tclk->parent->rate);
338 }
339 }
340 break;
341 }
342
343 best_div = omap2_divider_from_table(asize, div_array,
344 tclk->parent->rate, target_rate);
345 if (best_div == ~0){
346 *new_div = 1;
347 return best_div; /* signal error */
348 }
349
350 *new_div = best_div;
351 return (tclk->parent->rate / best_div);
352}
353
354/* Given a clock and a rate apply a clock specific rounding function */
355static long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
356{
357 u32 new_div = 0;
358 int valid_rate;
359
360 if (clk->flags & RATE_FIXED)
361 return clk->rate;
362
363 if (clk->flags & RATE_CKCTL) {
364 valid_rate = omap2_clksel_round_rate(clk, rate, &new_div);
365 return valid_rate;
366 }
367
368 if (clk->round_rate != 0)
369 return clk->round_rate(clk, rate);
370
371 return clk->rate;
372}
373
374/*
375 * Check the DLL lock state, and return tue if running in unlock mode.
376 * This is needed to compenste for the shifted DLL value in unlock mode.
377 */
378static u32 omap2_dll_force_needed(void)
379{
380 u32 dll_state = SDRC_DLLA_CTRL; /* dlla and dllb are a set */
381
382 if ((dll_state & (1 << 2)) == (1 << 2))
383 return 1;
384 else
385 return 0;
386}
387
388static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
389{
390 unsigned long dll_cnt;
391 u32 fast_dll = 0;
392
393 mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
394
395 /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
396 * In the case of 2422, its ok to use CS1 instead of CS0.
397 */
398
399#if 0 /* FIXME: Enable after 24xx cpu detection works */
400 ctype = get_cpu_type();
401 if (cpu_is_omap2422())
402 mem_timings.base_cs = 1;
403 else
404#endif
405 mem_timings.base_cs = 0;
406
407 if (mem_timings.m_type != M_DDR)
408 return;
409
410 /* With DDR we need to determine the low frequency DLL value */
411 if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
412 mem_timings.dll_mode = M_UNLOCK;
413 else
414 mem_timings.dll_mode = M_LOCK;
415
416 if (mem_timings.base_cs == 0) {
417 fast_dll = SDRC_DLLA_CTRL;
418 dll_cnt = SDRC_DLLA_STATUS & 0xff00;
419 } else {
420 fast_dll = SDRC_DLLB_CTRL;
421 dll_cnt = SDRC_DLLB_STATUS & 0xff00;
422 }
423 if (force_lock_to_unlock_mode) {
424 fast_dll &= ~0xff00;
425 fast_dll |= dll_cnt; /* Current lock mode */
426 }
427 mem_timings.fast_dll_ctrl = fast_dll;
428
429 /* No disruptions, DDR will be offline & C-ABI not followed */
430 omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
431 mem_timings.fast_dll_ctrl,
432 mem_timings.base_cs,
433 force_lock_to_unlock_mode);
434 mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
435
436 /* Turn status into unlock ctrl */
437 mem_timings.slow_dll_ctrl |=
438 ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
439
440 /* 90 degree phase for anything below 133Mhz */
441 mem_timings.slow_dll_ctrl |= (1 << 1);
442}
443
444static u32 omap2_reprogram_sdrc(u32 level, u32 force)
445{
446 u32 prev = curr_perf_level, flags;
447
448 if ((curr_perf_level == level) && !force)
449 return prev;
450
451 if (level == PRCM_HALF_SPEED) {
452 local_irq_save(flags);
453 PRCM_VOLTSETUP = 0xffff;
454 omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
455 mem_timings.slow_dll_ctrl,
456 mem_timings.m_type);
457 curr_perf_level = PRCM_HALF_SPEED;
458 local_irq_restore(flags);
459 }
460 if (level == PRCM_FULL_SPEED) {
461 local_irq_save(flags);
462 PRCM_VOLTSETUP = 0xffff;
463 omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
464 mem_timings.fast_dll_ctrl,
465 mem_timings.m_type);
466 curr_perf_level = PRCM_FULL_SPEED;
467 local_irq_restore(flags);
468 }
469
470 return prev;
471}
472
473static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate)
474{
475 u32 flags, cur_rate, low, mult, div, valid_rate, done_rate;
476 u32 bypass = 0;
477 struct prcm_config tmpset;
478 int ret = -EINVAL;
479
480 local_irq_save(flags);
481 cur_rate = omap2_get_dpll_rate(&dpll_ck);
482 mult = CM_CLKSEL2_PLL & 0x3;
483
484 if ((rate == (cur_rate / 2)) && (mult == 2)) {
485 omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
486 } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
487 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
488 } else if (rate != cur_rate) {
489 valid_rate = omap2_dpll_round_rate(rate);
490 if (valid_rate != rate)
491 goto dpll_exit;
492
493 if ((CM_CLKSEL2_PLL & 0x3) == 1)
494 low = curr_prcm_set->dpll_speed;
495 else
496 low = curr_prcm_set->dpll_speed / 2;
497
498 tmpset.cm_clksel1_pll = CM_CLKSEL1_PLL;
499 tmpset.cm_clksel1_pll &= ~(0x3FFF << 8);
500 div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
501 tmpset.cm_clksel2_pll = CM_CLKSEL2_PLL;
502 tmpset.cm_clksel2_pll &= ~0x3;
503 if (rate > low) {
504 tmpset.cm_clksel2_pll |= 0x2;
505 mult = ((rate / 2) / 1000000);
506 done_rate = PRCM_FULL_SPEED;
507 } else {
508 tmpset.cm_clksel2_pll |= 0x1;
509 mult = (rate / 1000000);
510 done_rate = PRCM_HALF_SPEED;
511 }
512 tmpset.cm_clksel1_pll |= ((div << 8) | (mult << 12));
513
514 /* Worst case */
515 tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS;
516
517 if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
518 bypass = 1;
519
520 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); /* For init_mem */
521
522 /* Force dll lock mode */
523 omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
524 bypass);
525
526 /* Errata: ret dll entry state */
527 omap2_init_memory_params(omap2_dll_force_needed());
528 omap2_reprogram_sdrc(done_rate, 0);
529 }
530 omap2_clksel_recalc(&dpll_ck);
531 ret = 0;
532
533dpll_exit:
534 local_irq_restore(flags);
535 return(ret);
536}
537
538/* Just return the MPU speed */
539static void omap2_mpu_recalc(struct clk * clk)
540{
541 clk->rate = curr_prcm_set->mpu_speed;
542}
543
544/*
545 * Look for a rate equal or less than the target rate given a configuration set.
546 *
547 * What's not entirely clear is "which" field represents the key field.
548 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
549 * just uses the ARM rates.
550 */
551static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate)
552{
553 struct prcm_config * ptr;
554 long highest_rate;
555
556 if (clk != &virt_prcm_set)
557 return -EINVAL;
558
559 highest_rate = -EINVAL;
560
561 for (ptr = rate_table; ptr->mpu_speed; ptr++) {
562 if (ptr->xtal_speed != sys_ck.rate)
563 continue;
564
565 highest_rate = ptr->mpu_speed;
566
567 /* Can check only after xtal frequency check */
568 if (ptr->mpu_speed <= rate)
569 break;
570 }
571 return highest_rate;
572}
573
574/*
575 * omap2_convert_field_to_div() - turn field value into integer divider
576 */
577static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val)
578{
579 u32 i;
580 u32 clkout_array[] = {1, 2, 4, 8, 16};
581
582 if ((div_sel & SRC_RATE_SEL_MASK) == CM_SYSCLKOUT_SEL1) {
583 for (i = 0; i < 5; i++) {
584 if (field_val == i)
585 return clkout_array[i];
586 }
587 return ~0;
588 } else
589 return field_val;
590}
591
592/*
593 * Returns the CLKSEL divider register value
594 * REVISIT: This should be cleaned up to work nicely with void __iomem *
595 */
596static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
597 struct clk *clk)
598{
599 int ret = ~0;
600 u32 reg_val, div_off;
601 u32 div_addr = 0;
602 u32 mask = ~0;
603
604 div_off = clk->rate_offset;
605
606 switch ((*div_sel & SRC_RATE_SEL_MASK)) {
607 case CM_MPU_SEL1:
608 div_addr = (u32)&CM_CLKSEL_MPU;
609 mask = 0x1f;
610 break;
611 case CM_DSP_SEL1:
612 div_addr = (u32)&CM_CLKSEL_DSP;
613 if (cpu_is_omap2420()) {
614 if ((div_off == 0) || (div_off == 8))
615 mask = 0x1f;
616 else if (div_off == 5)
617 mask = 0x3;
618 } else if (cpu_is_omap2430()) {
619 if (div_off == 0)
620 mask = 0x1f;
621 else if (div_off == 5)
622 mask = 0x3;
623 }
624 break;
625 case CM_GFX_SEL1:
626 div_addr = (u32)&CM_CLKSEL_GFX;
627 if (div_off == 0)
628 mask = 0x7;
629 break;
630 case CM_MODEM_SEL1:
631 div_addr = (u32)&CM_CLKSEL_MDM;
632 if (div_off == 0)
633 mask = 0xf;
634 break;
635 case CM_SYSCLKOUT_SEL1:
636 div_addr = (u32)&PRCM_CLKOUT_CTRL;
637 if ((div_off == 3) || (div_off = 11))
638 mask= 0x3;
639 break;
640 case CM_CORE_SEL1:
641 div_addr = (u32)&CM_CLKSEL1_CORE;
642 switch (div_off) {
643 case 0: /* l3 */
644 case 8: /* dss1 */
645 case 15: /* vylnc-2420 */
646 case 20: /* ssi */
647 mask = 0x1f; break;
648 case 5: /* l4 */
649 mask = 0x3; break;
650 case 13: /* dss2 */
651 mask = 0x1; break;
652 case 25: /* usb */
653 mask = 0xf; break;
654 }
655 }
656
657 *field_mask = mask;
658
659 if (unlikely(mask == ~0))
660 div_addr = 0;
661
662 *div_sel = div_addr;
663
664 if (unlikely(div_addr == 0))
665 return ret;
666
667 /* Isolate field */
668 reg_val = __raw_readl((void __iomem *)div_addr) & (mask << div_off);
669
670 /* Normalize back to divider value */
671 reg_val >>= div_off;
672
673 return reg_val;
674}
675
676/*
677 * Return divider to be applied to parent clock.
678 * Return 0 on error.
679 */
680static u32 omap2_clksel_get_divisor(struct clk *clk)
681{
682 int ret = 0;
683 u32 div, div_sel, div_off, field_mask, field_val;
684
685 /* isolate control register */
686 div_sel = (SRC_RATE_SEL_MASK & clk->flags);
687
688 div_off = clk->rate_offset;
689 field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
690 if (div_sel == 0)
691 return ret;
692
693 div_sel = (SRC_RATE_SEL_MASK & clk->flags);
694 div = omap2_clksel_to_divisor(div_sel, field_val);
695
696 return div;
697}
698
699/* Set the clock rate for a clock source */
700static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
701
702{
703 int ret = -EINVAL;
704 void __iomem * reg;
705 u32 div_sel, div_off, field_mask, field_val, reg_val, validrate;
706 u32 new_div = 0;
707
708 if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) {
709 if (clk == &dpll_ck)
710 return omap2_reprogram_dpll(clk, rate);
711
712 /* Isolate control register */
713 div_sel = (SRC_RATE_SEL_MASK & clk->flags);
714 div_off = clk->src_offset;
715
716 validrate = omap2_clksel_round_rate(clk, rate, &new_div);
717 if(validrate != rate)
718 return(ret);
719
720 field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
721 if (div_sel == 0)
722 return ret;
723
724 if(clk->flags & CM_SYSCLKOUT_SEL1){
725 switch(new_div){
726 case 16: field_val = 4; break;
727 case 8: field_val = 3; break;
728 case 4: field_val = 2; break;
729 case 2: field_val = 1; break;
730 case 1: field_val = 0; break;
731 }
732 }
733 else
734 field_val = new_div;
735
736 reg = (void __iomem *)div_sel;
737
738 reg_val = __raw_readl(reg);
739 reg_val &= ~(field_mask << div_off);
740 reg_val |= (field_val << div_off);
741
742 __raw_writel(reg_val, reg);
743 clk->rate = clk->parent->rate / field_val;
744
745 if (clk->flags & DELAYED_APP)
746 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
747 ret = 0;
748 } else if (clk->set_rate != 0)
749 ret = clk->set_rate(clk, rate);
750
751 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
752 propagate_rate(clk);
753
754 return ret;
755}
756
757/* Converts encoded control register address into a full address */
758static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
759 struct clk *src_clk, u32 *field_mask)
760{
761 u32 val = ~0, src_reg_addr = 0, mask = 0;
762
763 /* Find target control register.*/
764 switch ((*type_to_addr & SRC_RATE_SEL_MASK)) {
765 case CM_CORE_SEL1:
766 src_reg_addr = (u32)&CM_CLKSEL1_CORE;
767 if (reg_offset == 13) { /* DSS2_fclk */
768 mask = 0x1;
769 if (src_clk == &sys_ck)
770 val = 0;
771 if (src_clk == &func_48m_ck)
772 val = 1;
773 } else if (reg_offset == 8) { /* DSS1_fclk */
774 mask = 0x1f;
775 if (src_clk == &sys_ck)
776 val = 0;
777 else if (src_clk == &core_ck) /* divided clock */
778 val = 0x10; /* rate needs fixing */
779 } else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/
780 mask = 0x1F;
781 if(src_clk == &func_96m_ck)
782 val = 0;
783 else if (src_clk == &core_ck)
784 val = 0x10;
785 }
786 break;
787 case CM_CORE_SEL2:
788 src_reg_addr = (u32)&CM_CLKSEL2_CORE;
789 mask = 0x3;
790 if (src_clk == &func_32k_ck)
791 val = 0x0;
792 if (src_clk == &sys_ck)
793 val = 0x1;
794 if (src_clk == &alt_ck)
795 val = 0x2;
796 break;
797 case CM_WKUP_SEL1:
798 src_reg_addr = (u32)&CM_CLKSEL2_CORE;
799 mask = 0x3;
800 if (src_clk == &func_32k_ck)
801 val = 0x0;
802 if (src_clk == &sys_ck)
803 val = 0x1;
804 if (src_clk == &alt_ck)
805 val = 0x2;
806 break;
807 case CM_PLL_SEL1:
808 src_reg_addr = (u32)&CM_CLKSEL1_PLL;
809 mask = 0x1;
810 if (reg_offset == 0x3) {
811 if (src_clk == &apll96_ck)
812 val = 0;
813 if (src_clk == &alt_ck)
814 val = 1;
815 }
816 else if (reg_offset == 0x5) {
817 if (src_clk == &apll54_ck)
818 val = 0;
819 if (src_clk == &alt_ck)
820 val = 1;
821 }
822 break;
823 case CM_PLL_SEL2:
824 src_reg_addr = (u32)&CM_CLKSEL2_PLL;
825 mask = 0x3;
826 if (src_clk == &func_32k_ck)
827 val = 0x0;
828 if (src_clk == &dpll_ck)
829 val = 0x2;
830 break;
831 case CM_SYSCLKOUT_SEL1:
832 src_reg_addr = (u32)&PRCM_CLKOUT_CTRL;
833 mask = 0x3;
834 if (src_clk == &dpll_ck)
835 val = 0;
836 if (src_clk == &sys_ck)
837 val = 1;
838 if (src_clk == &func_54m_ck)
839 val = 2;
840 if (src_clk == &func_96m_ck)
841 val = 3;
842 break;
843 }
844
845 if (val == ~0) /* Catch errors in offset */
846 *type_to_addr = 0;
847 else
848 *type_to_addr = src_reg_addr;
849 *field_mask = mask;
850
851 return val;
852}
853
854static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
855{
856 void __iomem * reg;
857 u32 src_sel, src_off, field_val, field_mask, reg_val, rate;
858 int ret = -EINVAL;
859
860 if (unlikely(clk->flags & CONFIG_PARTICIPANT))
861 return ret;
862
863 if (clk->flags & SRC_SEL_MASK) { /* On-chip SEL collection */
864 src_sel = (SRC_RATE_SEL_MASK & clk->flags);
865 src_off = clk->src_offset;
866
867 if (src_sel == 0)
868 goto set_parent_error;
869
870 field_val = omap2_get_src_field(&src_sel, src_off, new_parent,
871 &field_mask);
872
873 reg = (void __iomem *)src_sel;
874
875 if (clk->usecount > 0)
876 omap2_clk_disable(clk);
877
878 /* Set new source value (previous dividers if any in effect) */
879 reg_val = __raw_readl(reg) & ~(field_mask << src_off);
880 reg_val |= (field_val << src_off);
881 __raw_writel(reg_val, reg);
882
883 if (clk->flags & DELAYED_APP)
884 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
885
886 if (clk->usecount > 0)
887 omap2_clk_enable(clk);
888
889 clk->parent = new_parent;
890
891 /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
892 if ((new_parent == &core_ck) && (clk == &dss1_fck))
893 clk->rate = new_parent->rate / 0x10;
894 else
895 clk->rate = new_parent->rate;
896
897 if (unlikely(clk->flags & RATE_PROPAGATES))
898 propagate_rate(clk);
899
900 return 0;
901 } else {
902 clk->parent = new_parent;
903 rate = new_parent->rate;
904 omap2_clk_set_rate(clk, rate);
905 ret = 0;
906 }
907
908 set_parent_error:
909 return ret;
910}
911
912/* Sets basic clocks based on the specified rate */
913static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
914{
915 u32 flags, cur_rate, done_rate, bypass = 0;
916 u8 cpu_mask = 0;
917 struct prcm_config *prcm;
918 unsigned long found_speed = 0;
919
920 if (clk != &virt_prcm_set)
921 return -EINVAL;
922
923 /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */
924 if (cpu_is_omap2420())
925 cpu_mask = RATE_IN_242X;
926 else if (cpu_is_omap2430())
927 cpu_mask = RATE_IN_243X;
928
929 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
930 if (!(prcm->flags & cpu_mask))
931 continue;
932
933 if (prcm->xtal_speed != sys_ck.rate)
934 continue;
935
936 if (prcm->mpu_speed <= rate) {
937 found_speed = prcm->mpu_speed;
938 break;
939 }
940 }
941
942 if (!found_speed) {
943 printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
944 rate / 1000000);
945 return -EINVAL;
946 }
947
948 curr_prcm_set = prcm;
949 cur_rate = omap2_get_dpll_rate(&dpll_ck);
950
951 if (prcm->dpll_speed == cur_rate / 2) {
952 omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
953 } else if (prcm->dpll_speed == cur_rate * 2) {
954 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
955 } else if (prcm->dpll_speed != cur_rate) {
956 local_irq_save(flags);
957
958 if (prcm->dpll_speed == prcm->xtal_speed)
959 bypass = 1;
960
961 if ((prcm->cm_clksel2_pll & 0x3) == 2)
962 done_rate = PRCM_FULL_SPEED;
963 else
964 done_rate = PRCM_HALF_SPEED;
965
966 /* MPU divider */
967 CM_CLKSEL_MPU = prcm->cm_clksel_mpu;
968
969 /* dsp + iva1 div(2420), iva2.1(2430) */
970 CM_CLKSEL_DSP = prcm->cm_clksel_dsp;
971
972 CM_CLKSEL_GFX = prcm->cm_clksel_gfx;
973
974 /* Major subsystem dividers */
975 CM_CLKSEL1_CORE = prcm->cm_clksel1_core;
976 if (cpu_is_omap2430())
977 CM_CLKSEL_MDM = prcm->cm_clksel_mdm;
978
979 /* x2 to enter init_mem */
980 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
981
982 omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
983 bypass);
984
985 omap2_init_memory_params(omap2_dll_force_needed());
986 omap2_reprogram_sdrc(done_rate, 0);
987
988 local_irq_restore(flags);
989 }
990 omap2_clksel_recalc(&dpll_ck);
991
992 return 0;
993}
994
995/*-------------------------------------------------------------------------
996 * Omap2 clock reset and init functions
997 *-------------------------------------------------------------------------*/
998
999static struct clk_functions omap2_clk_functions = {
1000 .clk_enable = omap2_clk_enable,
1001 .clk_disable = omap2_clk_disable,
1002 .clk_use = omap2_clk_use,
1003 .clk_unuse = omap2_clk_unuse,
1004 .clk_round_rate = omap2_clk_round_rate,
1005 .clk_set_rate = omap2_clk_set_rate,
1006 .clk_set_parent = omap2_clk_set_parent,
1007};
1008
1009static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
1010{
1011 u32 div, aplls, sclk = 13000000;
1012
1013 aplls = CM_CLKSEL1_PLL;
1014 aplls &= ((1 << 23) | (1 << 24) | (1 << 25));
1015 aplls >>= 23; /* Isolate field, 0,2,3 */
1016
1017 if (aplls == 0)
1018 sclk = 19200000;
1019 else if (aplls == 2)
1020 sclk = 13000000;
1021 else if (aplls == 3)
1022 sclk = 12000000;
1023
1024 div = PRCM_CLKSRC_CTRL;
1025 div &= ((1 << 7) | (1 << 6));
1026 div >>= sys->rate_offset;
1027
1028 osc->rate = sclk * div;
1029 sys->rate = sclk;
1030}
1031
1032#ifdef CONFIG_OMAP_RESET_CLOCKS
1033static void __init omap2_disable_unused_clocks(void)
1034{
1035 struct clk *ck;
1036 u32 regval32;
1037
1038 list_for_each_entry(ck, &clocks, node) {
1039 if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
1040 ck->enable_reg == 0)
1041 continue;
1042
1043 regval32 = __raw_readl(ck->enable_reg);
1044 if ((regval32 & (1 << ck->enable_bit)) == 0)
1045 continue;
1046
1047 printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
1048 omap2_clk_disable(ck);
1049 }
1050}
1051late_initcall(omap2_disable_unused_clocks);
1052#endif
1053
1054/*
1055 * Switch the MPU rate if specified on cmdline.
1056 * We cannot do this early until cmdline is parsed.
1057 */
1058static int __init omap2_clk_arch_init(void)
1059{
1060 if (!mpurate)
1061 return -EINVAL;
1062
1063 if (omap2_select_table_rate(&virt_prcm_set, mpurate))
1064 printk(KERN_ERR "Could not find matching MPU rate\n");
1065
1066 propagate_rate(&osc_ck); /* update main root fast */
1067 propagate_rate(&func_32k_ck); /* update main root slow */
1068
1069 printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
1070 "%ld.%01ld/%ld/%ld MHz\n",
1071 (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1072 (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1073
1074 return 0;
1075}
1076arch_initcall(omap2_clk_arch_init);
1077
1078int __init omap2_clk_init(void)
1079{
1080 struct prcm_config *prcm;
1081 struct clk ** clkp;
1082 u32 clkrate;
1083
1084 clk_init(&omap2_clk_functions);
1085 omap2_get_crystal_rate(&osc_ck, &sys_ck);
1086
1087 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
1088 clkp++) {
1089
1090 if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
1091 clk_register(*clkp);
1092 continue;
1093 }
1094
1095 if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
1096 clk_register(*clkp);
1097 continue;
1098 }
1099 }
1100
1101 /* Check the MPU rate set by bootloader */
1102 clkrate = omap2_get_dpll_rate(&dpll_ck);
1103 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
1104 if (prcm->xtal_speed != sys_ck.rate)
1105 continue;
1106 if (prcm->dpll_speed <= clkrate)
1107 break;
1108 }
1109 curr_prcm_set = prcm;
1110
1111 propagate_rate(&osc_ck); /* update main root fast */
1112 propagate_rate(&func_32k_ck); /* update main root slow */
1113
1114 printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
1115 "%ld.%01ld/%ld/%ld MHz\n",
1116 (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1117 (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1118
1119 /*
1120 * Only enable those clocks we will need, let the drivers
1121 * enable other clocks as necessary
1122 */
1123 clk_use(&sync_32k_ick);
1124 clk_use(&omapctrl_ick);
1125 if (cpu_is_omap2430())
1126 clk_use(&sdrc_ick);
1127
1128 return 0;
1129}
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
new file mode 100644
index 000000000000..4aeab5591bd3
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.h
@@ -0,0 +1,2103 @@
1/*
2 * linux/arch/arm/mach-omap24xx/clock.h
3 *
4 * Copyright (C) 2005 Texas Instruments Inc.
5 * Richard Woodruff <r-woodruff2@ti.com>
6 * Created for OMAP2.
7 *
8 * Copyright (C) 2004 Nokia corporation
9 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
10 * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
18#define __ARCH_ARM_MACH_OMAP2_CLOCK_H
19
20static void omap2_sys_clk_recalc(struct clk * clk);
21static void omap2_clksel_recalc(struct clk * clk);
22static void omap2_followparent_recalc(struct clk * clk);
23static void omap2_propagate_rate(struct clk * clk);
24static void omap2_mpu_recalc(struct clk * clk);
25static int omap2_select_table_rate(struct clk * clk, unsigned long rate);
26static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate);
27static void omap2_clk_unuse(struct clk *clk);
28static void omap2_sys_clk_recalc(struct clk * clk);
29static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val);
30static u32 omap2_clksel_get_divisor(struct clk *clk);
31
32
33#define RATE_IN_242X (1 << 0)
34#define RATE_IN_243X (1 << 1)
35
36/* Memory timings */
37#define M_DDR 1
38#define M_LOCK_CTRL (1 << 2)
39#define M_UNLOCK 0
40#define M_LOCK 1
41
42struct memory_timings {
43 u32 m_type; /* ddr = 1, sdr = 0 */
44 u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
45 u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
46 u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
47 u32 base_cs; /* base chip select to use for calculations */
48};
49
50/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
51 * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
52 * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
53 */
54struct prcm_config {
55 unsigned long xtal_speed; /* crystal rate */
56 unsigned long dpll_speed; /* dpll: out*xtal*M/(N-1)table_recalc */
57 unsigned long mpu_speed; /* speed of MPU */
58 unsigned long cm_clksel_mpu; /* mpu divider */
59 unsigned long cm_clksel_dsp; /* dsp+iva1 div(2420), iva2.1(2430) */
60 unsigned long cm_clksel_gfx; /* gfx dividers */
61 unsigned long cm_clksel1_core; /* major subsystem dividers */
62 unsigned long cm_clksel1_pll; /* m,n */
63 unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */
64 unsigned long cm_clksel_mdm; /* modem dividers 2430 only */
65 unsigned long base_sdrc_rfr; /* base refresh timing for a set */
66 unsigned char flags;
67};
68
69/* Mask for clksel which support parent settign in set_rate */
70#define SRC_SEL_MASK (CM_CORE_SEL1 | CM_CORE_SEL2 | CM_WKUP_SEL1 | \
71 CM_PLL_SEL1 | CM_PLL_SEL2 | CM_SYSCLKOUT_SEL1)
72
73/* Mask for clksel regs which support rate operations */
74#define SRC_RATE_SEL_MASK (CM_MPU_SEL1 | CM_DSP_SEL1 | CM_GFX_SEL1 | \
75 CM_MODEM_SEL1 | CM_CORE_SEL1 | CM_CORE_SEL2 | \
76 CM_WKUP_SEL1 | CM_PLL_SEL1 | CM_PLL_SEL2 | \
77 CM_SYSCLKOUT_SEL1)
78
79/*
80 * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
81 * These configurations are characterized by voltage and speed for clocks.
82 * The device is only validated for certain combinations. One way to express
83 * these combinations is via the 'ratio's' which the clocks operate with
84 * respect to each other. These ratio sets are for a given voltage/DPLL
85 * setting. All configurations can be described by a DPLL setting and a ratio
86 * There are 3 ratio sets for the 2430 and X ratio sets for 2420.
87 *
88 * 2430 differs from 2420 in that there are no more phase synchronizers used.
89 * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
90 * 2430 (iva2.1, NOdsp, mdm)
91 */
92
93/* Core fields for cm_clksel, not ratio governed */
94#define RX_CLKSEL_DSS1 (0x10 << 8)
95#define RX_CLKSEL_DSS2 (0x0 << 13)
96#define RX_CLKSEL_SSI (0x5 << 20)
97
98/*-------------------------------------------------------------------------
99 * Voltage/DPLL ratios
100 *-------------------------------------------------------------------------*/
101
102/* 2430 Ratio's, 2430-Ratio Config 1 */
103#define R1_CLKSEL_L3 (4 << 0)
104#define R1_CLKSEL_L4 (2 << 5)
105#define R1_CLKSEL_USB (4 << 25)
106#define R1_CM_CLKSEL1_CORE_VAL R1_CLKSEL_USB | RX_CLKSEL_SSI | \
107 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
108 R1_CLKSEL_L4 | R1_CLKSEL_L3
109#define R1_CLKSEL_MPU (2 << 0)
110#define R1_CM_CLKSEL_MPU_VAL R1_CLKSEL_MPU
111#define R1_CLKSEL_DSP (2 << 0)
112#define R1_CLKSEL_DSP_IF (2 << 5)
113#define R1_CM_CLKSEL_DSP_VAL R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF
114#define R1_CLKSEL_GFX (2 << 0)
115#define R1_CM_CLKSEL_GFX_VAL R1_CLKSEL_GFX
116#define R1_CLKSEL_MDM (4 << 0)
117#define R1_CM_CLKSEL_MDM_VAL R1_CLKSEL_MDM
118
119/* 2430-Ratio Config 2 */
120#define R2_CLKSEL_L3 (6 << 0)
121#define R2_CLKSEL_L4 (2 << 5)
122#define R2_CLKSEL_USB (2 << 25)
123#define R2_CM_CLKSEL1_CORE_VAL R2_CLKSEL_USB | RX_CLKSEL_SSI | \
124 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
125 R2_CLKSEL_L4 | R2_CLKSEL_L3
126#define R2_CLKSEL_MPU (2 << 0)
127#define R2_CM_CLKSEL_MPU_VAL R2_CLKSEL_MPU
128#define R2_CLKSEL_DSP (2 << 0)
129#define R2_CLKSEL_DSP_IF (3 << 5)
130#define R2_CM_CLKSEL_DSP_VAL R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF
131#define R2_CLKSEL_GFX (2 << 0)
132#define R2_CM_CLKSEL_GFX_VAL R2_CLKSEL_GFX
133#define R2_CLKSEL_MDM (6 << 0)
134#define R2_CM_CLKSEL_MDM_VAL R2_CLKSEL_MDM
135
136/* 2430-Ratio Bootm (BYPASS) */
137#define RB_CLKSEL_L3 (1 << 0)
138#define RB_CLKSEL_L4 (1 << 5)
139#define RB_CLKSEL_USB (1 << 25)
140#define RB_CM_CLKSEL1_CORE_VAL RB_CLKSEL_USB | RX_CLKSEL_SSI | \
141 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
142 RB_CLKSEL_L4 | RB_CLKSEL_L3
143#define RB_CLKSEL_MPU (1 << 0)
144#define RB_CM_CLKSEL_MPU_VAL RB_CLKSEL_MPU
145#define RB_CLKSEL_DSP (1 << 0)
146#define RB_CLKSEL_DSP_IF (1 << 5)
147#define RB_CM_CLKSEL_DSP_VAL RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF
148#define RB_CLKSEL_GFX (1 << 0)
149#define RB_CM_CLKSEL_GFX_VAL RB_CLKSEL_GFX
150#define RB_CLKSEL_MDM (1 << 0)
151#define RB_CM_CLKSEL_MDM_VAL RB_CLKSEL_MDM
152
153/* 2420 Ratio Equivalents */
154#define RXX_CLKSEL_VLYNQ (0x12 << 15)
155#define RXX_CLKSEL_SSI (0x8 << 20)
156
157/* 2420-PRCM III 532MHz core */
158#define RIII_CLKSEL_L3 (4 << 0) /* 133MHz */
159#define RIII_CLKSEL_L4 (2 << 5) /* 66.5MHz */
160#define RIII_CLKSEL_USB (4 << 25) /* 33.25MHz */
161#define RIII_CM_CLKSEL1_CORE_VAL RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \
162 RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
163 RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \
164 RIII_CLKSEL_L3
165#define RIII_CLKSEL_MPU (2 << 0) /* 266MHz */
166#define RIII_CM_CLKSEL_MPU_VAL RIII_CLKSEL_MPU
167#define RIII_CLKSEL_DSP (3 << 0) /* c5x - 177.3MHz */
168#define RIII_CLKSEL_DSP_IF (2 << 5) /* c5x - 88.67MHz */
169#define RIII_SYNC_DSP (1 << 7) /* Enable sync */
170#define RIII_CLKSEL_IVA (6 << 8) /* iva1 - 88.67MHz */
171#define RIII_SYNC_IVA (1 << 13) /* Enable sync */
172#define RIII_CM_CLKSEL_DSP_VAL RIII_SYNC_IVA | RIII_CLKSEL_IVA | \
173 RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \
174 RIII_CLKSEL_DSP
175#define RIII_CLKSEL_GFX (2 << 0) /* 66.5MHz */
176#define RIII_CM_CLKSEL_GFX_VAL RIII_CLKSEL_GFX
177
178/* 2420-PRCM II 600MHz core */
179#define RII_CLKSEL_L3 (6 << 0) /* 100MHz */
180#define RII_CLKSEL_L4 (2 << 5) /* 50MHz */
181#define RII_CLKSEL_USB (2 << 25) /* 50MHz */
182#define RII_CM_CLKSEL1_CORE_VAL RII_CLKSEL_USB | \
183 RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \
184 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
185 RII_CLKSEL_L4 | RII_CLKSEL_L3
186#define RII_CLKSEL_MPU (2 << 0) /* 300MHz */
187#define RII_CM_CLKSEL_MPU_VAL RII_CLKSEL_MPU
188#define RII_CLKSEL_DSP (3 << 0) /* c5x - 200MHz */
189#define RII_CLKSEL_DSP_IF (2 << 5) /* c5x - 100MHz */
190#define RII_SYNC_DSP (0 << 7) /* Bypass sync */
191#define RII_CLKSEL_IVA (6 << 8) /* iva1 - 200MHz */
192#define RII_SYNC_IVA (0 << 13) /* Bypass sync */
193#define RII_CM_CLKSEL_DSP_VAL RII_SYNC_IVA | RII_CLKSEL_IVA | \
194 RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \
195 RII_CLKSEL_DSP
196#define RII_CLKSEL_GFX (2 << 0) /* 50MHz */
197#define RII_CM_CLKSEL_GFX_VAL RII_CLKSEL_GFX
198
199/* 2420-PRCM VII (boot) */
200#define RVII_CLKSEL_L3 (1 << 0)
201#define RVII_CLKSEL_L4 (1 << 5)
202#define RVII_CLKSEL_DSS1 (1 << 8)
203#define RVII_CLKSEL_DSS2 (0 << 13)
204#define RVII_CLKSEL_VLYNQ (1 << 15)
205#define RVII_CLKSEL_SSI (1 << 20)
206#define RVII_CLKSEL_USB (1 << 25)
207
208#define RVII_CM_CLKSEL1_CORE_VAL RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \
209 RVII_CLKSEL_VLYNQ | RVII_CLKSEL_DSS2 | \
210 RVII_CLKSEL_DSS1 | RVII_CLKSEL_L4 | RVII_CLKSEL_L3
211
212#define RVII_CLKSEL_MPU (1 << 0) /* all divide by 1 */
213#define RVII_CM_CLKSEL_MPU_VAL RVII_CLKSEL_MPU
214
215#define RVII_CLKSEL_DSP (1 << 0)
216#define RVII_CLKSEL_DSP_IF (1 << 5)
217#define RVII_SYNC_DSP (0 << 7)
218#define RVII_CLKSEL_IVA (1 << 8)
219#define RVII_SYNC_IVA (0 << 13)
220#define RVII_CM_CLKSEL_DSP_VAL RVII_SYNC_IVA | RVII_CLKSEL_IVA | RVII_SYNC_DSP | \
221 RVII_CLKSEL_DSP_IF | RVII_CLKSEL_DSP
222
223#define RVII_CLKSEL_GFX (1 << 0)
224#define RVII_CM_CLKSEL_GFX_VAL RVII_CLKSEL_GFX
225
226/*-------------------------------------------------------------------------
227 * 2430 Target modes: Along with each configuration the CPU has several
228 * modes which goes along with them. Modes mainly are the addition of
229 * describe DPLL combinations to go along with a ratio.
230 *-------------------------------------------------------------------------*/
231
232/* Hardware governed */
233#define MX_48M_SRC (0 << 3)
234#define MX_54M_SRC (0 << 5)
235#define MX_APLLS_CLIKIN_12 (3 << 23)
236#define MX_APLLS_CLIKIN_13 (2 << 23)
237#define MX_APLLS_CLIKIN_19_2 (0 << 23)
238
239/*
240 * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed
241 * #2 (ratio1) baseport-target
242 * #5a (ratio1) baseport-target, target DPLL = 266*2 = 532MHz
243 */
244#define M5A_DPLL_MULT_12 (133 << 12)
245#define M5A_DPLL_DIV_12 (5 << 8)
246#define M5A_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
247 M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \
248 MX_APLLS_CLIKIN_12
249#define M5A_DPLL_MULT_13 (266 << 12)
250#define M5A_DPLL_DIV_13 (12 << 8)
251#define M5A_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
252 M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \
253 MX_APLLS_CLIKIN_13
254#define M5A_DPLL_MULT_19 (180 << 12)
255#define M5A_DPLL_DIV_19 (12 << 8)
256#define M5A_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \
257 M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \
258 MX_APLLS_CLIKIN_19_2
259/* #5b (ratio1) target DPLL = 200*2 = 400MHz */
260#define M5B_DPLL_MULT_12 (50 << 12)
261#define M5B_DPLL_DIV_12 (2 << 8)
262#define M5B_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
263 M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \
264 MX_APLLS_CLIKIN_12
265#define M5B_DPLL_MULT_13 (200 << 12)
266#define M5B_DPLL_DIV_13 (12 << 8)
267
268#define M5B_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
269 M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \
270 MX_APLLS_CLIKIN_13
271#define M5B_DPLL_MULT_19 (125 << 12)
272#define M5B_DPLL_DIV_19 (31 << 8)
273#define M5B_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \
274 M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \
275 MX_APLLS_CLIKIN_19_2
276/*
277 * #4 (ratio2)
278 * #3 (ratio2) baseport-target, target DPLL = 330*2 = 660MHz
279 */
280#define M3_DPLL_MULT_12 (55 << 12)
281#define M3_DPLL_DIV_12 (1 << 8)
282#define M3_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
283 M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \
284 MX_APLLS_CLIKIN_12
285#define M3_DPLL_MULT_13 (330 << 12)
286#define M3_DPLL_DIV_13 (12 << 8)
287#define M3_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
288 M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \
289 MX_APLLS_CLIKIN_13
290#define M3_DPLL_MULT_19 (275 << 12)
291#define M3_DPLL_DIV_19 (15 << 8)
292#define M3_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \
293 M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \
294 MX_APLLS_CLIKIN_19_2
295/* boot (boot) */
296#define MB_DPLL_MULT (1 << 12)
297#define MB_DPLL_DIV (0 << 8)
298#define MB_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
299 MB_DPLL_MULT | MX_APLLS_CLIKIN_12
300
301#define MB_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
302 MB_DPLL_MULT | MX_APLLS_CLIKIN_13
303
304#define MB_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
305 MB_DPLL_MULT | MX_APLLS_CLIKIN_19
306
307/*
308 * 2430 - chassis (sedna)
309 * 165 (ratio1) same as above #2
310 * 150 (ratio1)
311 * 133 (ratio2) same as above #4
312 * 110 (ratio2) same as above #3
313 * 104 (ratio2)
314 * boot (boot)
315 */
316
317/*
318 * 2420 Equivalent - mode registers
319 * PRCM II , target DPLL = 2*300MHz = 600MHz
320 */
321#define MII_DPLL_MULT_12 (50 << 12)
322#define MII_DPLL_DIV_12 (1 << 8)
323#define MII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
324 MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \
325 MX_APLLS_CLIKIN_12
326#define MII_DPLL_MULT_13 (300 << 12)
327#define MII_DPLL_DIV_13 (12 << 8)
328#define MII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
329 MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \
330 MX_APLLS_CLIKIN_13
331
332/* PRCM III target DPLL = 2*266 = 532MHz*/
333#define MIII_DPLL_MULT_12 (133 << 12)
334#define MIII_DPLL_DIV_12 (5 << 8)
335#define MIII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \
336 MIII_DPLL_DIV_12 | MIII_DPLL_MULT_12 | \
337 MX_APLLS_CLIKIN_12
338#define MIII_DPLL_MULT_13 (266 << 12)
339#define MIII_DPLL_DIV_13 (12 << 8)
340#define MIII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \
341 MIII_DPLL_DIV_13 | MIII_DPLL_MULT_13 | \
342 MX_APLLS_CLIKIN_13
343
344/* PRCM VII (boot bypass) */
345#define MVII_CM_CLKSEL1_PLL_12_VAL MB_CM_CLKSEL1_PLL_12_VAL
346#define MVII_CM_CLKSEL1_PLL_13_VAL MB_CM_CLKSEL1_PLL_13_VAL
347
348/* High and low operation value */
349#define MX_CLKSEL2_PLL_2x_VAL (2 << 0)
350#define MX_CLKSEL2_PLL_1x_VAL (1 << 0)
351
352/*
353 * These represent optimal values for common parts, it won't work for all.
354 * As long as you scale down, most parameters are still work, they just
355 * become sub-optimal. The RFR value goes in the oppisite direction. If you
356 * don't adjust it down as your clock period increases the refresh interval
357 * will not be met. Setting all parameters for complete worst case may work,
358 * but may cut memory performance by 2x. Due to errata the DLLs need to be
359 * unlocked and their value needs run time calibration. A dynamic call is
360 * need for that as no single right value exists acorss production samples.
361 *
362 * Only the FULL speed values are given. Current code is such that rate
363 * changes must be made at DPLLoutx2. The actual value adjustment for low
364 * frequency operation will be handled by omap_set_performance()
365 *
366 * By having the boot loader boot up in the fastest L4 speed available likely
367 * will result in something which you can switch between.
368 */
369#define V24XX_SDRC_RFR_CTRL_133MHz (0x0003de00 | 1)
370#define V24XX_SDRC_RFR_CTRL_100MHz (0x0002da01 | 1)
371#define V24XX_SDRC_RFR_CTRL_110MHz (0x0002da01 | 1) /* Need to calc */
372#define V24XX_SDRC_RFR_CTRL_BYPASS (0x00005000 | 1) /* Need to calc */
373
374/* MPU speed defines */
375#define S12M 12000000
376#define S13M 13000000
377#define S19M 19200000
378#define S26M 26000000
379#define S100M 100000000
380#define S133M 133000000
381#define S150M 150000000
382#define S165M 165000000
383#define S200M 200000000
384#define S266M 266000000
385#define S300M 300000000
386#define S330M 330000000
387#define S400M 400000000
388#define S532M 532000000
389#define S600M 600000000
390#define S660M 660000000
391
392/*-------------------------------------------------------------------------
393 * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
394 * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
395 * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
396 * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
397 *
398 * Filling in table based on H4 boards and 2430-SDPs variants available.
399 * There are quite a few more rates combinations which could be defined.
400 *
401 * When multiple values are defiend the start up will try and choose the
402 * fastest one. If a 'fast' value is defined, then automatically, the /2
403 * one should be included as it can be used. Generally having more that
404 * one fast set does not make sense, as static timings need to be changed
405 * to change the set. The exception is the bypass setting which is
406 * availble for low power bypass.
407 *
408 * Note: This table needs to be sorted, fastest to slowest.
409 *-------------------------------------------------------------------------*/
410static struct prcm_config rate_table[] = {
411 /* PRCM II - FAST */
412 {S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */
413 RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
414 RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
415 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
416 RATE_IN_242X},
417
418 {S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */
419 RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
420 RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
421 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
422 RATE_IN_242X},
423
424 /* PRCM III - FAST */
425 {S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
426 RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
427 RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
428 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
429 RATE_IN_242X},
430
431 {S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
432 RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
433 RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
434 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
435 RATE_IN_242X},
436
437 /* PRCM II - SLOW */
438 {S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */
439 RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
440 RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
441 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
442 RATE_IN_242X},
443
444 {S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */
445 RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
446 RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
447 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
448 RATE_IN_242X},
449
450 /* PRCM III - SLOW */
451 {S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
452 RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
453 RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
454 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
455 RATE_IN_242X},
456
457 {S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
458 RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
459 RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
460 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
461 RATE_IN_242X},
462
463 /* PRCM-VII (boot-bypass) */
464 {S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL, /* 12MHz ARM*/
465 RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
466 RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL,
467 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS,
468 RATE_IN_242X},
469
470 /* PRCM-VII (boot-bypass) */
471 {S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL, /* 13MHz ARM */
472 RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
473 RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL,
474 MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS,
475 RATE_IN_242X},
476
477 /* PRCM #3 - ratio2 (ES2) - FAST */
478 {S13M, S660M, S330M, R2_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */
479 R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
480 R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL,
481 MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL,
482 V24XX_SDRC_RFR_CTRL_110MHz,
483 RATE_IN_243X},
484
485 /* PRCM #5a - ratio1 - FAST */
486 {S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
487 R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
488 R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
489 MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
490 V24XX_SDRC_RFR_CTRL_133MHz,
491 RATE_IN_243X},
492
493 /* PRCM #5b - ratio1 - FAST */
494 {S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */
495 R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
496 R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
497 MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
498 V24XX_SDRC_RFR_CTRL_100MHz,
499 RATE_IN_243X},
500
501 /* PRCM #3 - ratio2 (ES2) - SLOW */
502 {S13M, S330M, S165M, R2_CM_CLKSEL_MPU_VAL, /* 165MHz ARM */
503 R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
504 R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL,
505 MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL,
506 V24XX_SDRC_RFR_CTRL_110MHz,
507 RATE_IN_243X},
508
509 /* PRCM #5a - ratio1 - SLOW */
510 {S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
511 R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
512 R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
513 MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
514 V24XX_SDRC_RFR_CTRL_133MHz,
515 RATE_IN_243X},
516
517 /* PRCM #5b - ratio1 - SLOW*/
518 {S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL, /* 100MHz ARM */
519 R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
520 R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
521 MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
522 V24XX_SDRC_RFR_CTRL_100MHz,
523 RATE_IN_243X},
524
525 /* PRCM-boot/bypass */
526 {S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL, /* 13Mhz */
527 RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
528 RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL,
529 MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
530 V24XX_SDRC_RFR_CTRL_BYPASS,
531 RATE_IN_243X},
532
533 /* PRCM-boot/bypass */
534 {S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL, /* 12Mhz */
535 RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
536 RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL,
537 MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
538 V24XX_SDRC_RFR_CTRL_BYPASS,
539 RATE_IN_243X},
540
541 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
542};
543
544/*-------------------------------------------------------------------------
545 * 24xx clock tree.
546 *
547 * NOTE:In many cases here we are assigning a 'default' parent. In many
548 * cases the parent is selectable. The get/set parent calls will also
549 * switch sources.
550 *
551 * Many some clocks say always_enabled, but they can be auto idled for
552 * power savings. They will always be available upon clock request.
553 *
554 * Several sources are given initial rates which may be wrong, this will
555 * be fixed up in the init func.
556 *
557 * Things are broadly separated below by clock domains. It is
558 * noteworthy that most periferals have dependencies on multiple clock
559 * domains. Many get their interface clocks from the L4 domain, but get
560 * functional clocks from fixed sources or other core domain derived
561 * clocks.
562 *-------------------------------------------------------------------------*/
563
564/* Base external input clocks */
565static struct clk func_32k_ck = {
566 .name = "func_32k_ck",
567 .rate = 32000,
568 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
569 RATE_FIXED | ALWAYS_ENABLED,
570};
571
572/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
573static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
574 .name = "osc_ck",
575 .rate = 26000000, /* fixed up in clock init */
576 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
577 RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
578};
579
580/* With out modem likely 12MHz, with modem likely 13MHz */
581static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
582 .name = "sys_ck", /* ~ ref_clk also */
583 .parent = &osc_ck,
584 .rate = 13000000,
585 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
586 RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
587 .rate_offset = 6, /* sysclkdiv 1 or 2, already handled or no boot */
588 .recalc = &omap2_sys_clk_recalc,
589};
590
591static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
592 .name = "alt_ck",
593 .rate = 54000000,
594 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
595 RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
596 .recalc = &omap2_propagate_rate,
597};
598
599/*
600 * Analog domain root source clocks
601 */
602
603/* dpll_ck, is broken out in to special cases through clksel */
604static struct clk dpll_ck = {
605 .name = "dpll_ck",
606 .parent = &sys_ck, /* Can be func_32k also */
607 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
608 RATE_PROPAGATES | RATE_CKCTL | CM_PLL_SEL1,
609 .recalc = &omap2_clksel_recalc,
610};
611
612static struct clk apll96_ck = {
613 .name = "apll96_ck",
614 .parent = &sys_ck,
615 .rate = 96000000,
616 .flags = CLOCK_IN_OMAP242X |CLOCK_IN_OMAP243X |
617 RATE_FIXED | RATE_PROPAGATES,
618 .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
619 .enable_bit = 0x2,
620 .recalc = &omap2_propagate_rate,
621};
622
623static struct clk apll54_ck = {
624 .name = "apll54_ck",
625 .parent = &sys_ck,
626 .rate = 54000000,
627 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
628 RATE_FIXED | RATE_PROPAGATES,
629 .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
630 .enable_bit = 0x6,
631 .recalc = &omap2_propagate_rate,
632};
633
634/*
635 * PRCM digital base sources
636 */
637static struct clk func_54m_ck = {
638 .name = "func_54m_ck",
639 .parent = &apll54_ck, /* can also be alt_clk */
640 .rate = 54000000,
641 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
642 RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES,
643 .src_offset = 5,
644 .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
645 .enable_bit = 0xff,
646 .recalc = &omap2_propagate_rate,
647};
648
649static struct clk core_ck = {
650 .name = "core_ck",
651 .parent = &dpll_ck, /* can also be 32k */
652 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
653 ALWAYS_ENABLED | RATE_PROPAGATES,
654 .recalc = &omap2_propagate_rate,
655};
656
657static struct clk sleep_ck = { /* sys_clk or 32k */
658 .name = "sleep_ck",
659 .parent = &func_32k_ck,
660 .rate = 32000,
661 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
662 .recalc = &omap2_propagate_rate,
663};
664
665static struct clk func_96m_ck = {
666 .name = "func_96m_ck",
667 .parent = &apll96_ck,
668 .rate = 96000000,
669 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
670 RATE_FIXED | RATE_PROPAGATES,
671 .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
672 .enable_bit = 0xff,
673 .recalc = &omap2_propagate_rate,
674};
675
676static struct clk func_48m_ck = {
677 .name = "func_48m_ck",
678 .parent = &apll96_ck, /* 96M or Alt */
679 .rate = 48000000,
680 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
681 RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES,
682 .src_offset = 3,
683 .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
684 .enable_bit = 0xff,
685 .recalc = &omap2_propagate_rate,
686};
687
688static struct clk func_12m_ck = {
689 .name = "func_12m_ck",
690 .parent = &func_48m_ck,
691 .rate = 12000000,
692 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
693 RATE_FIXED | RATE_PROPAGATES,
694 .recalc = &omap2_propagate_rate,
695 .enable_reg = (void __iomem *)&CM_CLKEN_PLL,
696 .enable_bit = 0xff,
697};
698
699/* Secure timer, only available in secure mode */
700static struct clk wdt1_osc_ck = {
701 .name = "ck_wdt1_osc",
702 .parent = &osc_ck,
703 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
704 .recalc = &omap2_followparent_recalc,
705};
706
707static struct clk sys_clkout = {
708 .name = "sys_clkout",
709 .parent = &func_54m_ck,
710 .rate = 54000000,
711 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
712 CM_SYSCLKOUT_SEL1 | RATE_CKCTL,
713 .src_offset = 0,
714 .enable_reg = (void __iomem *)&PRCM_CLKOUT_CTRL,
715 .enable_bit = 7,
716 .rate_offset = 3,
717 .recalc = &omap2_clksel_recalc,
718};
719
720/* In 2430, new in 2420 ES2 */
721static struct clk sys_clkout2 = {
722 .name = "sys_clkout2",
723 .parent = &func_54m_ck,
724 .rate = 54000000,
725 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
726 CM_SYSCLKOUT_SEL1 | RATE_CKCTL,
727 .src_offset = 8,
728 .enable_reg = (void __iomem *)&PRCM_CLKOUT_CTRL,
729 .enable_bit = 15,
730 .rate_offset = 11,
731 .recalc = &omap2_clksel_recalc,
732};
733
734/*
735 * MPU clock domain
736 * Clocks:
737 * MPU_FCLK, MPU_ICLK
738 * INT_M_FCLK, INT_M_I_CLK
739 *
740 * - Individual clocks are hardware managed.
741 * - Base divider comes from: CM_CLKSEL_MPU
742 *
743 */
744static struct clk mpu_ck = { /* Control cpu */
745 .name = "mpu_ck",
746 .parent = &core_ck,
747 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL |
748 ALWAYS_ENABLED | CM_MPU_SEL1 | DELAYED_APP |
749 CONFIG_PARTICIPANT | RATE_PROPAGATES,
750 .rate_offset = 0, /* bits 0-4 */
751 .recalc = &omap2_clksel_recalc,
752};
753
754/*
755 * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain
756 * Clocks:
757 * 2430: IVA2.1_FCLK, IVA2.1_ICLK
758 * 2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
759 */
760static struct clk iva2_1_fck = {
761 .name = "iva2_1_fck",
762 .parent = &core_ck,
763 .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 |
764 DELAYED_APP | RATE_PROPAGATES |
765 CONFIG_PARTICIPANT,
766 .rate_offset = 0,
767 .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
768 .enable_bit = 0,
769 .recalc = &omap2_clksel_recalc,
770};
771
772static struct clk iva2_1_ick = {
773 .name = "iva2_1_ick",
774 .parent = &iva2_1_fck,
775 .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 |
776 DELAYED_APP | CONFIG_PARTICIPANT,
777 .rate_offset = 5,
778 .recalc = &omap2_clksel_recalc,
779};
780
781/*
782 * Won't be too specific here. The core clock comes into this block
783 * it is divided then tee'ed. One branch goes directly to xyz enable
784 * controls. The other branch gets further divided by 2 then possibly
785 * routed into a synchronizer and out of clocks abc.
786 */
787static struct clk dsp_fck = {
788 .name = "dsp_fck",
789 .parent = &core_ck,
790 .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 |
791 DELAYED_APP | CONFIG_PARTICIPANT | RATE_PROPAGATES,
792 .rate_offset = 0,
793 .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
794 .enable_bit = 0,
795 .recalc = &omap2_clksel_recalc,
796};
797
798static struct clk dsp_ick = {
799 .name = "dsp_ick", /* apparently ipi and isp */
800 .parent = &dsp_fck,
801 .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 |
802 DELAYED_APP | CONFIG_PARTICIPANT,
803 .rate_offset = 5,
804 .enable_reg = (void __iomem *)&CM_ICLKEN_DSP,
805 .enable_bit = 1, /* for ipi */
806 .recalc = &omap2_clksel_recalc,
807};
808
809static struct clk iva1_ifck = {
810 .name = "iva1_ifck",
811 .parent = &core_ck,
812 .flags = CLOCK_IN_OMAP242X | CM_DSP_SEL1 | RATE_CKCTL |
813 CONFIG_PARTICIPANT | RATE_PROPAGATES | DELAYED_APP,
814 .rate_offset= 8,
815 .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
816 .enable_bit = 10,
817 .recalc = &omap2_clksel_recalc,
818};
819
820/* IVA1 mpu/int/i/f clocks are /2 of parent */
821static struct clk iva1_mpu_int_ifck = {
822 .name = "iva1_mpu_int_ifck",
823 .parent = &iva1_ifck,
824 .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1,
825 .enable_reg = (void __iomem *)&CM_FCLKEN_DSP,
826 .enable_bit = 8,
827 .recalc = &omap2_clksel_recalc,
828};
829
830/*
831 * L3 clock domain
832 * L3 clocks are used for both interface and functional clocks to
833 * multiple entities. Some of these clocks are completely managed
834 * by hardware, and some others allow software control. Hardware
835 * managed ones general are based on directly CLK_REQ signals and
836 * various auto idle settings. The functional spec sets many of these
837 * as 'tie-high' for their enables.
838 *
839 * I-CLOCKS:
840 * L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
841 * CAM, HS-USB.
842 * F-CLOCK
843 * SSI.
844 *
845 * GPMC memories and SDRC have timing and clock sensitive registers which
846 * may very well need notification when the clock changes. Currently for low
847 * operating points, these are taken care of in sleep.S.
848 */
849static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
850 .name = "core_l3_ck",
851 .parent = &core_ck,
852 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
853 RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 |
854 DELAYED_APP | CONFIG_PARTICIPANT |
855 RATE_PROPAGATES,
856 .rate_offset = 0,
857 .recalc = &omap2_clksel_recalc,
858};
859
860static struct clk usb_l4_ick = { /* FS-USB interface clock */
861 .name = "usb_l4_ick",
862 .parent = &core_ck,
863 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
864 RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP |
865 CONFIG_PARTICIPANT,
866 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
867 .enable_bit = 0,
868 .rate_offset = 25,
869 .recalc = &omap2_clksel_recalc,
870};
871
872/*
873 * SSI is in L3 management domain, its direct parent is core not l3,
874 * many core power domain entities are grouped into the L3 clock
875 * domain.
876 * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_CLIK
877 *
878 * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
879 */
880static struct clk ssi_ssr_sst_fck = {
881 .name = "ssi_fck",
882 .parent = &core_ck,
883 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
884 RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
885 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, /* bit 1 */
886 .enable_bit = 1,
887 .rate_offset = 20,
888 .recalc = &omap2_clksel_recalc,
889};
890
891/*
892 * GFX clock domain
893 * Clocks:
894 * GFX_FCLK, GFX_ICLK
895 * GFX_CG1(2d), GFX_CG2(3d)
896 *
897 * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
898 * The 2d and 3d clocks run at a hardware determined
899 * divided value of fclk.
900 *
901 */
902static struct clk gfx_3d_fck = {
903 .name = "gfx_3d_fck",
904 .parent = &core_l3_ck,
905 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
906 RATE_CKCTL | CM_GFX_SEL1,
907 .enable_reg = (void __iomem *)&CM_FCLKEN_GFX,
908 .enable_bit = 2,
909 .rate_offset= 0,
910 .recalc = &omap2_clksel_recalc,
911};
912
913static struct clk gfx_2d_fck = {
914 .name = "gfx_2d_fck",
915 .parent = &core_l3_ck,
916 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
917 RATE_CKCTL | CM_GFX_SEL1,
918 .enable_reg = (void __iomem *)&CM_FCLKEN_GFX,
919 .enable_bit = 1,
920 .rate_offset= 0,
921 .recalc = &omap2_clksel_recalc,
922};
923
924static struct clk gfx_ick = {
925 .name = "gfx_ick", /* From l3 */
926 .parent = &core_l3_ck,
927 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
928 RATE_CKCTL,
929 .enable_reg = (void __iomem *)&CM_ICLKEN_GFX, /* bit 0 */
930 .enable_bit = 0,
931 .recalc = &omap2_followparent_recalc,
932};
933
934/*
935 * Modem clock domain (2430)
936 * CLOCKS:
937 * MDM_OSC_CLK
938 * MDM_ICLK
939 */
940static struct clk mdm_ick = { /* used both as a ick and fck */
941 .name = "mdm_ick",
942 .parent = &core_ck,
943 .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_MODEM_SEL1 |
944 DELAYED_APP | CONFIG_PARTICIPANT,
945 .rate_offset = 0,
946 .enable_reg = (void __iomem *)&CM_ICLKEN_MDM,
947 .enable_bit = 0,
948 .recalc = &omap2_clksel_recalc,
949};
950
951static struct clk mdm_osc_ck = {
952 .name = "mdm_osc_ck",
953 .rate = 26000000,
954 .parent = &osc_ck,
955 .flags = CLOCK_IN_OMAP243X | RATE_FIXED,
956 .enable_reg = (void __iomem *)&CM_FCLKEN_MDM,
957 .enable_bit = 1,
958 .recalc = &omap2_followparent_recalc,
959};
960
961/*
962 * L4 clock management domain
963 *
964 * This domain contains lots of interface clocks from the L4 interface, some
965 * functional clocks. Fixed APLL functional source clocks are managed in
966 * this domain.
967 */
968static struct clk l4_ck = { /* used both as an ick and fck */
969 .name = "l4_ck",
970 .parent = &core_l3_ck,
971 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
972 RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 |
973 DELAYED_APP | RATE_PROPAGATES,
974 .rate_offset = 5,
975 .recalc = &omap2_clksel_recalc,
976};
977
978static struct clk ssi_l4_ick = {
979 .name = "ssi_l4_ick",
980 .parent = &l4_ck,
981 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL,
982 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, /* bit 1 */
983 .enable_bit = 1,
984 .recalc = &omap2_followparent_recalc,
985};
986
987/*
988 * DSS clock domain
989 * CLOCKs:
990 * DSS_L4_ICLK, DSS_L3_ICLK,
991 * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
992 *
993 * DSS is both initiator and target.
994 */
995static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */
996 .name = "dss_ick",
997 .parent = &l4_ck, /* really both l3 and l4 */
998 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL,
999 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1000 .enable_bit = 0,
1001 .recalc = &omap2_followparent_recalc,
1002};
1003
1004static struct clk dss1_fck = {
1005 .name = "dss1_fck",
1006 .parent = &core_ck, /* Core or sys */
1007 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1008 RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
1009 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1010 .enable_bit = 0,
1011 .rate_offset = 8,
1012 .src_offset = 8,
1013 .recalc = &omap2_clksel_recalc,
1014};
1015
1016static struct clk dss2_fck = { /* Alt clk used in power management */
1017 .name = "dss2_fck",
1018 .parent = &sys_ck, /* fixed at sys_ck or 48MHz */
1019 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1020 RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED,
1021 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1022 .enable_bit = 1,
1023 .src_offset = 13,
1024 .recalc = &omap2_followparent_recalc,
1025};
1026
1027static struct clk dss_54m_fck = { /* Alt clk used in power management */
1028 .name = "dss_54m_fck", /* 54m tv clk */
1029 .parent = &func_54m_ck,
1030 .rate = 54000000,
1031 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1032 RATE_FIXED | RATE_PROPAGATES,
1033 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1034 .enable_bit = 2,
1035 .recalc = &omap2_propagate_rate,
1036};
1037
1038/*
1039 * CORE power domain ICLK & FCLK defines.
1040 * Many of the these can have more than one possible parent. Entries
1041 * here will likely have an L4 interface parent, and may have multiple
1042 * functional clock parents.
1043 */
1044static struct clk gpt1_ick = {
1045 .name = "gpt1_ick",
1046 .parent = &l4_ck,
1047 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1048 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, /* Bit4 */
1049 .enable_bit = 0,
1050 .recalc = &omap2_followparent_recalc,
1051};
1052
1053static struct clk gpt1_fck = {
1054 .name = "gpt1_fck",
1055 .parent = &func_32k_ck,
1056 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1057 CM_WKUP_SEL1,
1058 .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP,
1059 .enable_bit = 0,
1060 .src_offset = 0,
1061 .recalc = &omap2_followparent_recalc,
1062};
1063
1064static struct clk gpt2_ick = {
1065 .name = "gpt2_ick",
1066 .parent = &l4_ck,
1067 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1068 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit4 */
1069 .enable_bit = 0,
1070 .recalc = &omap2_followparent_recalc,
1071};
1072
1073static struct clk gpt2_fck = {
1074 .name = "gpt2_fck",
1075 .parent = &func_32k_ck,
1076 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1077 CM_CORE_SEL2,
1078 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1079 .enable_bit = 4,
1080 .src_offset = 2,
1081 .recalc = &omap2_followparent_recalc,
1082};
1083
1084static struct clk gpt3_ick = {
1085 .name = "gpt3_ick",
1086 .parent = &l4_ck,
1087 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1088 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit5 */
1089 .enable_bit = 5,
1090 .recalc = &omap2_followparent_recalc,
1091};
1092
1093static struct clk gpt3_fck = {
1094 .name = "gpt3_fck",
1095 .parent = &func_32k_ck,
1096 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1097 CM_CORE_SEL2,
1098 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1099 .enable_bit = 5,
1100 .src_offset = 4,
1101 .recalc = &omap2_followparent_recalc,
1102};
1103
1104static struct clk gpt4_ick = {
1105 .name = "gpt4_ick",
1106 .parent = &l4_ck,
1107 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1108 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit6 */
1109 .enable_bit = 6,
1110 .recalc = &omap2_followparent_recalc,
1111};
1112
1113static struct clk gpt4_fck = {
1114 .name = "gpt4_fck",
1115 .parent = &func_32k_ck,
1116 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1117 CM_CORE_SEL2,
1118 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1119 .enable_bit = 6,
1120 .src_offset = 6,
1121 .recalc = &omap2_followparent_recalc,
1122};
1123
1124static struct clk gpt5_ick = {
1125 .name = "gpt5_ick",
1126 .parent = &l4_ck,
1127 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1128 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit7 */
1129 .enable_bit = 7,
1130 .recalc = &omap2_followparent_recalc,
1131};
1132
1133static struct clk gpt5_fck = {
1134 .name = "gpt5_fck",
1135 .parent = &func_32k_ck,
1136 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1137 CM_CORE_SEL2,
1138 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1139 .enable_bit = 7,
1140 .src_offset = 8,
1141 .recalc = &omap2_followparent_recalc,
1142};
1143
1144static struct clk gpt6_ick = {
1145 .name = "gpt6_ick",
1146 .parent = &l4_ck,
1147 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1148 .enable_bit = 8,
1149 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit8 */
1150 .recalc = &omap2_followparent_recalc,
1151};
1152
1153static struct clk gpt6_fck = {
1154 .name = "gpt6_fck",
1155 .parent = &func_32k_ck,
1156 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1157 CM_CORE_SEL2,
1158 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1159 .enable_bit = 8,
1160 .src_offset = 10,
1161 .recalc = &omap2_followparent_recalc,
1162};
1163
1164static struct clk gpt7_ick = {
1165 .name = "gpt7_ick",
1166 .parent = &l4_ck,
1167 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1168 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit9 */
1169 .enable_bit = 9,
1170 .recalc = &omap2_followparent_recalc,
1171};
1172
1173static struct clk gpt7_fck = {
1174 .name = "gpt7_fck",
1175 .parent = &func_32k_ck,
1176 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1177 CM_CORE_SEL2,
1178 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1179 .enable_bit = 9,
1180 .src_offset = 12,
1181 .recalc = &omap2_followparent_recalc,
1182};
1183
1184static struct clk gpt8_ick = {
1185 .name = "gpt8_ick",
1186 .parent = &l4_ck,
1187 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1188 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit10 */
1189 .enable_bit = 10,
1190 .recalc = &omap2_followparent_recalc,
1191};
1192
1193static struct clk gpt8_fck = {
1194 .name = "gpt8_fck",
1195 .parent = &func_32k_ck,
1196 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1197 CM_CORE_SEL2,
1198 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1199 .enable_bit = 10,
1200 .src_offset = 14,
1201 .recalc = &omap2_followparent_recalc,
1202};
1203
1204static struct clk gpt9_ick = {
1205 .name = "gpt9_ick",
1206 .parent = &l4_ck,
1207 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1208 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1209 .enable_bit = 11,
1210 .recalc = &omap2_followparent_recalc,
1211};
1212
1213static struct clk gpt9_fck = {
1214 .name = "gpt9_fck",
1215 .parent = &func_32k_ck,
1216 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1217 CM_CORE_SEL2,
1218 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1219 .enable_bit = 11,
1220 .src_offset = 16,
1221 .recalc = &omap2_followparent_recalc,
1222};
1223
1224static struct clk gpt10_ick = {
1225 .name = "gpt10_ick",
1226 .parent = &l4_ck,
1227 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1228 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1229 .enable_bit = 12,
1230 .recalc = &omap2_followparent_recalc,
1231};
1232
1233static struct clk gpt10_fck = {
1234 .name = "gpt10_fck",
1235 .parent = &func_32k_ck,
1236 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1237 CM_CORE_SEL2,
1238 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1239 .enable_bit = 12,
1240 .src_offset = 18,
1241 .recalc = &omap2_followparent_recalc,
1242};
1243
1244static struct clk gpt11_ick = {
1245 .name = "gpt11_ick",
1246 .parent = &l4_ck,
1247 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1248 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1249 .enable_bit = 13,
1250 .recalc = &omap2_followparent_recalc,
1251};
1252
1253static struct clk gpt11_fck = {
1254 .name = "gpt11_fck",
1255 .parent = &func_32k_ck,
1256 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1257 CM_CORE_SEL2,
1258 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1259 .enable_bit = 13,
1260 .src_offset = 20,
1261 .recalc = &omap2_followparent_recalc,
1262};
1263
1264static struct clk gpt12_ick = {
1265 .name = "gpt12_ick",
1266 .parent = &l4_ck,
1267 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1268 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit14 */
1269 .enable_bit = 14,
1270 .recalc = &omap2_followparent_recalc,
1271};
1272
1273static struct clk gpt12_fck = {
1274 .name = "gpt12_fck",
1275 .parent = &func_32k_ck,
1276 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1277 CM_CORE_SEL2,
1278 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1279 .enable_bit = 14,
1280 .src_offset = 22,
1281 .recalc = &omap2_followparent_recalc,
1282};
1283
1284static struct clk mcbsp1_ick = {
1285 .name = "mcbsp1_ick",
1286 .parent = &l4_ck,
1287 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1288 .enable_bit = 15,
1289 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit16 */
1290 .recalc = &omap2_followparent_recalc,
1291};
1292
1293static struct clk mcbsp1_fck = {
1294 .name = "mcbsp1_fck",
1295 .parent = &func_96m_ck,
1296 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1297 .enable_bit = 15,
1298 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1299 .recalc = &omap2_followparent_recalc,
1300};
1301
1302static struct clk mcbsp2_ick = {
1303 .name = "mcbsp2_ick",
1304 .parent = &l4_ck,
1305 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1306 .enable_bit = 16,
1307 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1308 .recalc = &omap2_followparent_recalc,
1309};
1310
1311static struct clk mcbsp2_fck = {
1312 .name = "mcbsp2_fck",
1313 .parent = &func_96m_ck,
1314 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1315 .enable_bit = 16,
1316 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1317 .recalc = &omap2_followparent_recalc,
1318};
1319
1320static struct clk mcbsp3_ick = {
1321 .name = "mcbsp3_ick",
1322 .parent = &l4_ck,
1323 .flags = CLOCK_IN_OMAP243X,
1324 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1325 .enable_bit = 3,
1326 .recalc = &omap2_followparent_recalc,
1327};
1328
1329static struct clk mcbsp3_fck = {
1330 .name = "mcbsp3_fck",
1331 .parent = &func_96m_ck,
1332 .flags = CLOCK_IN_OMAP243X,
1333 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1334 .enable_bit = 3,
1335 .recalc = &omap2_followparent_recalc,
1336};
1337
1338static struct clk mcbsp4_ick = {
1339 .name = "mcbsp4_ick",
1340 .parent = &l4_ck,
1341 .flags = CLOCK_IN_OMAP243X,
1342 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1343 .enable_bit = 4,
1344 .recalc = &omap2_followparent_recalc,
1345};
1346
1347static struct clk mcbsp4_fck = {
1348 .name = "mcbsp4_fck",
1349 .parent = &func_96m_ck,
1350 .flags = CLOCK_IN_OMAP243X,
1351 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1352 .enable_bit = 4,
1353 .recalc = &omap2_followparent_recalc,
1354};
1355
1356static struct clk mcbsp5_ick = {
1357 .name = "mcbsp5_ick",
1358 .parent = &l4_ck,
1359 .flags = CLOCK_IN_OMAP243X,
1360 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1361 .enable_bit = 5,
1362 .recalc = &omap2_followparent_recalc,
1363};
1364
1365static struct clk mcbsp5_fck = {
1366 .name = "mcbsp5_fck",
1367 .parent = &func_96m_ck,
1368 .flags = CLOCK_IN_OMAP243X,
1369 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1370 .enable_bit = 5,
1371 .recalc = &omap2_followparent_recalc,
1372};
1373
1374static struct clk mcspi1_ick = {
1375 .name = "mcspi1_ick",
1376 .parent = &l4_ck,
1377 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1378 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1379 .enable_bit = 17,
1380 .recalc = &omap2_followparent_recalc,
1381};
1382
1383static struct clk mcspi1_fck = {
1384 .name = "mcspi1_fck",
1385 .parent = &func_48m_ck,
1386 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1387 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1388 .enable_bit = 17,
1389 .recalc = &omap2_followparent_recalc,
1390};
1391
1392static struct clk mcspi2_ick = {
1393 .name = "mcspi2_ick",
1394 .parent = &l4_ck,
1395 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1396 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1397 .enable_bit = 18,
1398 .recalc = &omap2_followparent_recalc,
1399};
1400
1401static struct clk mcspi2_fck = {
1402 .name = "mcspi2_fck",
1403 .parent = &func_48m_ck,
1404 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1405 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1406 .enable_bit = 18,
1407 .recalc = &omap2_followparent_recalc,
1408};
1409
1410static struct clk mcspi3_ick = {
1411 .name = "mcspi3_ick",
1412 .parent = &l4_ck,
1413 .flags = CLOCK_IN_OMAP243X,
1414 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1415 .enable_bit = 9,
1416 .recalc = &omap2_followparent_recalc,
1417};
1418
1419static struct clk mcspi3_fck = {
1420 .name = "mcspi3_fck",
1421 .parent = &func_48m_ck,
1422 .flags = CLOCK_IN_OMAP243X,
1423 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1424 .enable_bit = 9,
1425 .recalc = &omap2_followparent_recalc,
1426};
1427
1428static struct clk uart1_ick = {
1429 .name = "uart1_ick",
1430 .parent = &l4_ck,
1431 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1432 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1433 .enable_bit = 21,
1434 .recalc = &omap2_followparent_recalc,
1435};
1436
1437static struct clk uart1_fck = {
1438 .name = "uart1_fck",
1439 .parent = &func_48m_ck,
1440 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1441 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1442 .enable_bit = 21,
1443 .recalc = &omap2_followparent_recalc,
1444};
1445
1446static struct clk uart2_ick = {
1447 .name = "uart2_ick",
1448 .parent = &l4_ck,
1449 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1450 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1451 .enable_bit = 22,
1452 .recalc = &omap2_followparent_recalc,
1453};
1454
1455static struct clk uart2_fck = {
1456 .name = "uart2_fck",
1457 .parent = &func_48m_ck,
1458 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1459 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1460 .enable_bit = 22,
1461 .recalc = &omap2_followparent_recalc,
1462};
1463
1464static struct clk uart3_ick = {
1465 .name = "uart3_ick",
1466 .parent = &l4_ck,
1467 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1468 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1469 .enable_bit = 2,
1470 .recalc = &omap2_followparent_recalc,
1471};
1472
1473static struct clk uart3_fck = {
1474 .name = "uart3_fck",
1475 .parent = &func_48m_ck,
1476 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1477 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1478 .enable_bit = 2,
1479 .recalc = &omap2_followparent_recalc,
1480};
1481
1482static struct clk gpios_ick = {
1483 .name = "gpios_ick",
1484 .parent = &l4_ck,
1485 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1486 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
1487 .enable_bit = 2,
1488 .recalc = &omap2_followparent_recalc,
1489};
1490
1491static struct clk gpios_fck = {
1492 .name = "gpios_fck",
1493 .parent = &func_32k_ck,
1494 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1495 .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP,
1496 .enable_bit = 2,
1497 .recalc = &omap2_followparent_recalc,
1498};
1499
1500static struct clk mpu_wdt_ick = {
1501 .name = "mpu_wdt_ick",
1502 .parent = &l4_ck,
1503 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1504 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
1505 .enable_bit = 3,
1506 .recalc = &omap2_followparent_recalc,
1507};
1508
1509static struct clk mpu_wdt_fck = {
1510 .name = "mpu_wdt_fck",
1511 .parent = &func_32k_ck,
1512 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1513 .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP,
1514 .enable_bit = 3,
1515 .recalc = &omap2_followparent_recalc,
1516};
1517
1518static struct clk sync_32k_ick = {
1519 .name = "sync_32k_ick",
1520 .parent = &l4_ck,
1521 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1522 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
1523 .enable_bit = 1,
1524 .recalc = &omap2_followparent_recalc,
1525};
1526static struct clk wdt1_ick = {
1527 .name = "wdt1_ick",
1528 .parent = &l4_ck,
1529 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1530 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
1531 .enable_bit = 4,
1532 .recalc = &omap2_followparent_recalc,
1533};
1534static struct clk omapctrl_ick = {
1535 .name = "omapctrl_ick",
1536 .parent = &l4_ck,
1537 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1538 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
1539 .enable_bit = 5,
1540 .recalc = &omap2_followparent_recalc,
1541};
1542static struct clk icr_ick = {
1543 .name = "icr_ick",
1544 .parent = &l4_ck,
1545 .flags = CLOCK_IN_OMAP243X,
1546 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP,
1547 .enable_bit = 6,
1548 .recalc = &omap2_followparent_recalc,
1549};
1550
1551static struct clk cam_ick = {
1552 .name = "cam_ick",
1553 .parent = &l4_ck,
1554 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1555 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1556 .enable_bit = 31,
1557 .recalc = &omap2_followparent_recalc,
1558};
1559
1560static struct clk cam_fck = {
1561 .name = "cam_fck",
1562 .parent = &func_96m_ck,
1563 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1564 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1565 .enable_bit = 31,
1566 .recalc = &omap2_followparent_recalc,
1567};
1568
1569static struct clk mailboxes_ick = {
1570 .name = "mailboxes_ick",
1571 .parent = &l4_ck,
1572 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1573 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1574 .enable_bit = 30,
1575 .recalc = &omap2_followparent_recalc,
1576};
1577
1578static struct clk wdt4_ick = {
1579 .name = "wdt4_ick",
1580 .parent = &l4_ck,
1581 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1582 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1583 .enable_bit = 29,
1584 .recalc = &omap2_followparent_recalc,
1585};
1586
1587static struct clk wdt4_fck = {
1588 .name = "wdt4_fck",
1589 .parent = &func_32k_ck,
1590 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1591 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1592 .enable_bit = 29,
1593 .recalc = &omap2_followparent_recalc,
1594};
1595
1596static struct clk wdt3_ick = {
1597 .name = "wdt3_ick",
1598 .parent = &l4_ck,
1599 .flags = CLOCK_IN_OMAP242X,
1600 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1601 .enable_bit = 28,
1602 .recalc = &omap2_followparent_recalc,
1603};
1604
1605static struct clk wdt3_fck = {
1606 .name = "wdt3_fck",
1607 .parent = &func_32k_ck,
1608 .flags = CLOCK_IN_OMAP242X,
1609 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1610 .enable_bit = 28,
1611 .recalc = &omap2_followparent_recalc,
1612};
1613
1614static struct clk mspro_ick = {
1615 .name = "mspro_ick",
1616 .parent = &l4_ck,
1617 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1618 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1619 .enable_bit = 27,
1620 .recalc = &omap2_followparent_recalc,
1621};
1622
1623static struct clk mspro_fck = {
1624 .name = "mspro_fck",
1625 .parent = &func_96m_ck,
1626 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1627 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1628 .enable_bit = 27,
1629 .recalc = &omap2_followparent_recalc,
1630};
1631
1632static struct clk mmc_ick = {
1633 .name = "mmc_ick",
1634 .parent = &l4_ck,
1635 .flags = CLOCK_IN_OMAP242X,
1636 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1637 .enable_bit = 26,
1638 .recalc = &omap2_followparent_recalc,
1639};
1640
1641static struct clk mmc_fck = {
1642 .name = "mmc_fck",
1643 .parent = &func_96m_ck,
1644 .flags = CLOCK_IN_OMAP242X,
1645 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1646 .enable_bit = 26,
1647 .recalc = &omap2_followparent_recalc,
1648};
1649
1650static struct clk fac_ick = {
1651 .name = "fac_ick",
1652 .parent = &l4_ck,
1653 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1654 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1655 .enable_bit = 25,
1656 .recalc = &omap2_followparent_recalc,
1657};
1658
1659static struct clk fac_fck = {
1660 .name = "fac_fck",
1661 .parent = &func_12m_ck,
1662 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1663 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1664 .enable_bit = 25,
1665 .recalc = &omap2_followparent_recalc,
1666};
1667
1668static struct clk eac_ick = {
1669 .name = "eac_ick",
1670 .parent = &l4_ck,
1671 .flags = CLOCK_IN_OMAP242X,
1672 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1673 .enable_bit = 24,
1674 .recalc = &omap2_followparent_recalc,
1675};
1676
1677static struct clk eac_fck = {
1678 .name = "eac_fck",
1679 .parent = &func_96m_ck,
1680 .flags = CLOCK_IN_OMAP242X,
1681 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1682 .enable_bit = 24,
1683 .recalc = &omap2_followparent_recalc,
1684};
1685
1686static struct clk hdq_ick = {
1687 .name = "hdq_ick",
1688 .parent = &l4_ck,
1689 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1690 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1691 .enable_bit = 23,
1692 .recalc = &omap2_followparent_recalc,
1693};
1694
1695static struct clk hdq_fck = {
1696 .name = "hdq_fck",
1697 .parent = &func_12m_ck,
1698 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1699 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1700 .enable_bit = 23,
1701 .recalc = &omap2_followparent_recalc,
1702};
1703
1704static struct clk i2c2_ick = {
1705 .name = "i2c2_ick",
1706 .parent = &l4_ck,
1707 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1708 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1709 .enable_bit = 20,
1710 .recalc = &omap2_followparent_recalc,
1711};
1712
1713static struct clk i2c2_fck = {
1714 .name = "i2c2_fck",
1715 .parent = &func_12m_ck,
1716 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1717 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1718 .enable_bit = 20,
1719 .recalc = &omap2_followparent_recalc,
1720};
1721
1722static struct clk i2chs2_fck = {
1723 .name = "i2chs2_fck",
1724 .parent = &func_96m_ck,
1725 .flags = CLOCK_IN_OMAP243X,
1726 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1727 .enable_bit = 20,
1728 .recalc = &omap2_followparent_recalc,
1729};
1730
1731static struct clk i2c1_ick = {
1732 .name = "i2c1_ick",
1733 .parent = &l4_ck,
1734 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1735 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1736 .enable_bit = 19,
1737 .recalc = &omap2_followparent_recalc,
1738};
1739
1740static struct clk i2c1_fck = {
1741 .name = "i2c1_fck",
1742 .parent = &func_12m_ck,
1743 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1744 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1745 .enable_bit = 19,
1746 .recalc = &omap2_followparent_recalc,
1747};
1748
1749static struct clk i2chs1_fck = {
1750 .name = "i2chs1_fck",
1751 .parent = &func_96m_ck,
1752 .flags = CLOCK_IN_OMAP243X,
1753 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1754 .enable_bit = 19,
1755 .recalc = &omap2_followparent_recalc,
1756};
1757
1758static struct clk vlynq_ick = {
1759 .name = "vlynq_ick",
1760 .parent = &core_l3_ck,
1761 .flags = CLOCK_IN_OMAP242X,
1762 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
1763 .enable_bit = 3,
1764 .recalc = &omap2_followparent_recalc,
1765};
1766
1767static struct clk vlynq_fck = {
1768 .name = "vlynq_fck",
1769 .parent = &func_96m_ck,
1770 .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
1771 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
1772 .enable_bit = 3,
1773 .src_offset = 15,
1774 .recalc = &omap2_followparent_recalc,
1775};
1776
1777static struct clk sdrc_ick = {
1778 .name = "sdrc_ick",
1779 .parent = &l4_ck,
1780 .flags = CLOCK_IN_OMAP243X,
1781 .enable_reg = (void __iomem *)&CM_ICLKEN3_CORE,
1782 .enable_bit = 2,
1783 .recalc = &omap2_followparent_recalc,
1784};
1785
1786static struct clk des_ick = {
1787 .name = "des_ick",
1788 .parent = &l4_ck,
1789 .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
1790 .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
1791 .enable_bit = 0,
1792 .recalc = &omap2_followparent_recalc,
1793};
1794
1795static struct clk sha_ick = {
1796 .name = "sha_ick",
1797 .parent = &l4_ck,
1798 .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
1799 .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
1800 .enable_bit = 1,
1801 .recalc = &omap2_followparent_recalc,
1802};
1803
1804static struct clk rng_ick = {
1805 .name = "rng_ick",
1806 .parent = &l4_ck,
1807 .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
1808 .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
1809 .enable_bit = 2,
1810 .recalc = &omap2_followparent_recalc,
1811};
1812
1813static struct clk aes_ick = {
1814 .name = "aes_ick",
1815 .parent = &l4_ck,
1816 .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
1817 .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
1818 .enable_bit = 3,
1819 .recalc = &omap2_followparent_recalc,
1820};
1821
1822static struct clk pka_ick = {
1823 .name = "pka_ick",
1824 .parent = &l4_ck,
1825 .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
1826 .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE,
1827 .enable_bit = 4,
1828 .recalc = &omap2_followparent_recalc,
1829};
1830
1831static struct clk usb_fck = {
1832 .name = "usb_fck",
1833 .parent = &func_48m_ck,
1834 .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
1835 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1836 .enable_bit = 0,
1837 .recalc = &omap2_followparent_recalc,
1838};
1839
1840static struct clk usbhs_ick = {
1841 .name = "usbhs_ick",
1842 .parent = &l4_ck,
1843 .flags = CLOCK_IN_OMAP243X,
1844 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1845 .enable_bit = 6,
1846 .recalc = &omap2_followparent_recalc,
1847};
1848
1849static struct clk mmchs1_ick = {
1850 .name = "mmchs1_ick",
1851 .parent = &l4_ck,
1852 .flags = CLOCK_IN_OMAP243X,
1853 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1854 .enable_bit = 7,
1855 .recalc = &omap2_followparent_recalc,
1856};
1857
1858static struct clk mmchs1_fck = {
1859 .name = "mmchs1_fck",
1860 .parent = &func_96m_ck,
1861 .flags = CLOCK_IN_OMAP243X,
1862 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1863 .enable_bit = 7,
1864 .recalc = &omap2_followparent_recalc,
1865};
1866
1867static struct clk mmchs2_ick = {
1868 .name = "mmchs2_ick",
1869 .parent = &l4_ck,
1870 .flags = CLOCK_IN_OMAP243X,
1871 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1872 .enable_bit = 8,
1873 .recalc = &omap2_followparent_recalc,
1874};
1875
1876static struct clk mmchs2_fck = {
1877 .name = "mmchs2_fck",
1878 .parent = &func_96m_ck,
1879 .flags = CLOCK_IN_OMAP243X,
1880 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1881 .enable_bit = 8,
1882 .recalc = &omap2_followparent_recalc,
1883};
1884
1885static struct clk gpio5_ick = {
1886 .name = "gpio5_ick",
1887 .parent = &l4_ck,
1888 .flags = CLOCK_IN_OMAP243X,
1889 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1890 .enable_bit = 10,
1891 .recalc = &omap2_followparent_recalc,
1892};
1893
1894static struct clk gpio5_fck = {
1895 .name = "gpio5_fck",
1896 .parent = &func_32k_ck,
1897 .flags = CLOCK_IN_OMAP243X,
1898 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1899 .enable_bit = 10,
1900 .recalc = &omap2_followparent_recalc,
1901};
1902
1903static struct clk mdm_intc_ick = {
1904 .name = "mdm_intc_ick",
1905 .parent = &l4_ck,
1906 .flags = CLOCK_IN_OMAP243X,
1907 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1908 .enable_bit = 11,
1909 .recalc = &omap2_followparent_recalc,
1910};
1911
1912static struct clk mmchsdb1_fck = {
1913 .name = "mmchsdb1_fck",
1914 .parent = &func_32k_ck,
1915 .flags = CLOCK_IN_OMAP243X,
1916 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1917 .enable_bit = 16,
1918 .recalc = &omap2_followparent_recalc,
1919};
1920
1921static struct clk mmchsdb2_fck = {
1922 .name = "mmchsdb2_fck",
1923 .parent = &func_32k_ck,
1924 .flags = CLOCK_IN_OMAP243X,
1925 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
1926 .enable_bit = 17,
1927 .recalc = &omap2_followparent_recalc,
1928};
1929
1930/*
1931 * This clock is a composite clock which does entire set changes then
1932 * forces a rebalance. It keys on the MPU speed, but it really could
1933 * be any key speed part of a set in the rate table.
1934 *
1935 * to really change a set, you need memory table sets which get changed
1936 * in sram, pre-notifiers & post notifiers, changing the top set, without
1937 * having low level display recalc's won't work... this is why dpm notifiers
1938 * work, isr's off, walk a list of clocks already _off_ and not messing with
1939 * the bus.
1940 *
1941 * This clock should have no parent. It embodies the entire upper level
1942 * active set. A parent will mess up some of the init also.
1943 */
1944static struct clk virt_prcm_set = {
1945 .name = "virt_prcm_set",
1946 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1947 VIRTUAL_CLOCK | ALWAYS_ENABLED | DELAYED_APP,
1948 .parent = &mpu_ck, /* Indexed by mpu speed, no parent */
1949 .recalc = &omap2_mpu_recalc, /* sets are keyed on mpu rate */
1950 .set_rate = &omap2_select_table_rate,
1951 .round_rate = &omap2_round_to_table_rate,
1952};
1953
1954static struct clk *onchip_clks[] = {
1955 /* external root sources */
1956 &func_32k_ck,
1957 &osc_ck,
1958 &sys_ck,
1959 &alt_ck,
1960 /* internal analog sources */
1961 &dpll_ck,
1962 &apll96_ck,
1963 &apll54_ck,
1964 /* internal prcm root sources */
1965 &func_54m_ck,
1966 &core_ck,
1967 &sleep_ck,
1968 &func_96m_ck,
1969 &func_48m_ck,
1970 &func_12m_ck,
1971 &wdt1_osc_ck,
1972 &sys_clkout,
1973 &sys_clkout2,
1974 /* mpu domain clocks */
1975 &mpu_ck,
1976 /* dsp domain clocks */
1977 &iva2_1_fck, /* 2430 */
1978 &iva2_1_ick,
1979 &dsp_ick, /* 2420 */
1980 &dsp_fck,
1981 &iva1_ifck,
1982 &iva1_mpu_int_ifck,
1983 /* GFX domain clocks */
1984 &gfx_3d_fck,
1985 &gfx_2d_fck,
1986 &gfx_ick,
1987 /* Modem domain clocks */
1988 &mdm_ick,
1989 &mdm_osc_ck,
1990 /* DSS domain clocks */
1991 &dss_ick,
1992 &dss1_fck,
1993 &dss2_fck,
1994 &dss_54m_fck,
1995 /* L3 domain clocks */
1996 &core_l3_ck,
1997 &ssi_ssr_sst_fck,
1998 &usb_l4_ick,
1999 /* L4 domain clocks */
2000 &l4_ck, /* used as both core_l4 and wu_l4 */
2001 &ssi_l4_ick,
2002 /* virtual meta-group clock */
2003 &virt_prcm_set,
2004 /* general l4 interface ck, multi-parent functional clk */
2005 &gpt1_ick,
2006 &gpt1_fck,
2007 &gpt2_ick,
2008 &gpt2_fck,
2009 &gpt3_ick,
2010 &gpt3_fck,
2011 &gpt4_ick,
2012 &gpt4_fck,
2013 &gpt5_ick,
2014 &gpt5_fck,
2015 &gpt6_ick,
2016 &gpt6_fck,
2017 &gpt7_ick,
2018 &gpt7_fck,
2019 &gpt8_ick,
2020 &gpt8_fck,
2021 &gpt9_ick,
2022 &gpt9_fck,
2023 &gpt10_ick,
2024 &gpt10_fck,
2025 &gpt11_ick,
2026 &gpt11_fck,
2027 &gpt12_ick,
2028 &gpt12_fck,
2029 &mcbsp1_ick,
2030 &mcbsp1_fck,
2031 &mcbsp2_ick,
2032 &mcbsp2_fck,
2033 &mcbsp3_ick,
2034 &mcbsp3_fck,
2035 &mcbsp4_ick,
2036 &mcbsp4_fck,
2037 &mcbsp5_ick,
2038 &mcbsp5_fck,
2039 &mcspi1_ick,
2040 &mcspi1_fck,
2041 &mcspi2_ick,
2042 &mcspi2_fck,
2043 &mcspi3_ick,
2044 &mcspi3_fck,
2045 &uart1_ick,
2046 &uart1_fck,
2047 &uart2_ick,
2048 &uart2_fck,
2049 &uart3_ick,
2050 &uart3_fck,
2051 &gpios_ick,
2052 &gpios_fck,
2053 &mpu_wdt_ick,
2054 &mpu_wdt_fck,
2055 &sync_32k_ick,
2056 &wdt1_ick,
2057 &omapctrl_ick,
2058 &icr_ick,
2059 &cam_fck,
2060 &cam_ick,
2061 &mailboxes_ick,
2062 &wdt4_ick,
2063 &wdt4_fck,
2064 &wdt3_ick,
2065 &wdt3_fck,
2066 &mspro_ick,
2067 &mspro_fck,
2068 &mmc_ick,
2069 &mmc_fck,
2070 &fac_ick,
2071 &fac_fck,
2072 &eac_ick,
2073 &eac_fck,
2074 &hdq_ick,
2075 &hdq_fck,
2076 &i2c1_ick,
2077 &i2c1_fck,
2078 &i2chs1_fck,
2079 &i2c2_ick,
2080 &i2c2_fck,
2081 &i2chs2_fck,
2082 &vlynq_ick,
2083 &vlynq_fck,
2084 &sdrc_ick,
2085 &des_ick,
2086 &sha_ick,
2087 &rng_ick,
2088 &aes_ick,
2089 &pka_ick,
2090 &usb_fck,
2091 &usbhs_ick,
2092 &mmchs1_ick,
2093 &mmchs1_fck,
2094 &mmchs2_ick,
2095 &mmchs2_fck,
2096 &gpio5_ick,
2097 &gpio5_fck,
2098 &mdm_intc_ick,
2099 &mmchsdb1_fck,
2100 &mmchsdb2_fck,
2101};
2102
2103#endif
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
new file mode 100644
index 000000000000..7181edb89352
--- /dev/null
+++ b/arch/arm/mach-omap2/devices.c
@@ -0,0 +1,89 @@
1/*
2 * linux/arch/arm/mach-omap2/devices.c
3 *
4 * OMAP2 platform device setup/initialization
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17
18#include <asm/hardware.h>
19#include <asm/io.h>
20#include <asm/mach-types.h>
21#include <asm/mach/map.h>
22
23#include <asm/arch/tc.h>
24#include <asm/arch/board.h>
25#include <asm/arch/mux.h>
26#include <asm/arch/gpio.h>
27
28extern void omap_nop_release(struct device *dev);
29
30/*-------------------------------------------------------------------------*/
31
32#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
33
34#define OMAP2_I2C_BASE2 0x48072000
35#define OMAP2_I2C_INT2 57
36
37static struct resource i2c_resources2[] = {
38 {
39 .start = OMAP2_I2C_BASE2,
40 .end = OMAP2_I2C_BASE2 + 0x3f,
41 .flags = IORESOURCE_MEM,
42 },
43 {
44 .start = OMAP2_I2C_INT2,
45 .flags = IORESOURCE_IRQ,
46 },
47};
48
49static struct platform_device omap_i2c_device2 = {
50 .name = "i2c_omap",
51 .id = 2,
52 .dev = {
53 .release = omap_nop_release,
54 },
55 .num_resources = ARRAY_SIZE(i2c_resources2),
56 .resource = i2c_resources2,
57};
58
59/* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */
60static void omap_init_i2c(void)
61{
62 /* REVISIT: Second I2C not in use on H4? */
63 if (machine_is_omap_h4())
64 return;
65
66 omap_cfg_reg(J15_24XX_I2C2_SCL);
67 omap_cfg_reg(H19_24XX_I2C2_SDA);
68 (void) platform_device_register(&omap_i2c_device2);
69}
70
71#else
72
73static void omap_init_i2c(void) {}
74
75#endif
76
77/*-------------------------------------------------------------------------*/
78
79static int __init omap2_init_devices(void)
80{
81 /* please keep these calls, and their implementations above,
82 * in alphabetical order so they're easier to sort through.
83 */
84 omap_init_i2c();
85
86 return 0;
87}
88arch_initcall(omap2_init_devices);
89
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
new file mode 100644
index 000000000000..76187300f2b6
--- /dev/null
+++ b/arch/arm/mach-omap2/id.c
@@ -0,0 +1,124 @@
1/*
2 * linux/arch/arm/mach-omap2/id.c
3 *
4 * OMAP2 CPU identification code
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Written by Tony Lindgren <tony@atomide.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18
19#include <asm/io.h>
20
21#define OMAP24XX_TAP_BASE io_p2v(0x48014000)
22
23#define OMAP_TAP_IDCODE 0x0204
24#define OMAP_TAP_PROD_ID 0x0208
25
26#define OMAP_TAP_DIE_ID_0 0x0218
27#define OMAP_TAP_DIE_ID_1 0x021C
28#define OMAP_TAP_DIE_ID_2 0x0220
29#define OMAP_TAP_DIE_ID_3 0x0224
30
31/* system_rev fields for OMAP2 processors:
32 * CPU id bits [31:16],
33 * CPU device type [15:12], (unprg,normal,POP)
34 * CPU revision [11:08]
35 * CPU class bits [07:00]
36 */
37
38struct omap_id {
39 u16 hawkeye; /* Silicon type (Hawkeye id) */
40 u8 dev; /* Device type from production_id reg */
41 u32 type; /* combined type id copied to system_rev */
42};
43
44/* Register values to detect the OMAP version */
45static struct omap_id omap_ids[] __initdata = {
46 { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200000 },
47 { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201000 },
48 { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202000 },
49 { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220000 },
50 { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230000 },
51 { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 },
52};
53
54static u32 __init read_tap_reg(int reg)
55{
56 return __raw_readl(OMAP24XX_TAP_BASE + reg);
57}
58
59void __init omap2_check_revision(void)
60{
61 int i, j;
62 u32 idcode;
63 u32 prod_id;
64 u16 hawkeye;
65 u8 dev_type;
66 u8 rev;
67
68 idcode = read_tap_reg(OMAP_TAP_IDCODE);
69 prod_id = read_tap_reg(OMAP_TAP_PROD_ID);
70 hawkeye = (idcode >> 12) & 0xffff;
71 rev = (idcode >> 28) & 0x0f;
72 dev_type = (prod_id >> 16) & 0x0f;
73
74#ifdef DEBUG
75 printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
76 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
77 printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n",
78 read_tap_reg(OMAP_TAP_DIE_ID_0));
79 printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
80 read_tap_reg(OMAP_TAP_DIE_ID_1),
81 (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
82 printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n",
83 read_tap_reg(OMAP_TAP_DIE_ID_2));
84 printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n",
85 read_tap_reg(OMAP_TAP_DIE_ID_3));
86 printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
87 prod_id, dev_type);
88#endif
89
90 /* Check hawkeye ids */
91 for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
92 if (hawkeye == omap_ids[i].hawkeye)
93 break;
94 }
95
96 if (i == ARRAY_SIZE(omap_ids)) {
97 printk(KERN_ERR "Unknown OMAP CPU id\n");
98 return;
99 }
100
101 for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
102 if (dev_type == omap_ids[j].dev)
103 break;
104 }
105
106 if (j == ARRAY_SIZE(omap_ids)) {
107 printk(KERN_ERR "Unknown OMAP device type. "
108 "Handling it as OMAP%04x\n",
109 omap_ids[i].type >> 16);
110 j = i;
111 }
112 system_rev = omap_ids[j].type;
113
114 system_rev |= rev << 8;
115
116 /* Add the cpu class info (24xx) */
117 system_rev |= 0x24;
118
119 pr_info("OMAP%04x", system_rev >> 16);
120 if ((system_rev >> 8) & 0x0f)
121 printk("%x", (system_rev >> 8) & 0x0f);
122 printk("\n");
123}
124
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
new file mode 100644
index 000000000000..8ea67bf196a5
--- /dev/null
+++ b/arch/arm/mach-omap2/io.c
@@ -0,0 +1,53 @@
1/*
2 * linux/arch/arm/mach-omap2/io.c
3 *
4 * OMAP2 I/O mapping code
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18
19#include <asm/mach/map.h>
20#include <asm/io.h>
21#include <asm/arch/mux.h>
22
23extern void omap_sram_init(void);
24extern int omap2_clk_init(void);
25extern void omap2_check_revision(void);
26
27/*
28 * The machine specific code may provide the extra mapping besides the
29 * default mapping provided here.
30 */
31static struct map_desc omap2_io_desc[] __initdata = {
32 {
33 .virtual = L3_24XX_VIRT,
34 .pfn = __phys_to_pfn(L3_24XX_PHYS),
35 .length = L3_24XX_SIZE,
36 .type = MT_DEVICE
37 },
38 {
39 .virtual = L4_24XX_VIRT,
40 .pfn = __phys_to_pfn(L4_24XX_PHYS),
41 .length = L4_24XX_SIZE,
42 .type = MT_DEVICE
43 }
44};
45
46void __init omap_map_common_io(void)
47{
48 iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
49 omap2_check_revision();
50 omap_sram_init();
51 omap2_mux_init();
52 omap2_clk_init();
53}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
new file mode 100644
index 000000000000..d7baff675cfe
--- /dev/null
+++ b/arch/arm/mach-omap2/irq.c
@@ -0,0 +1,149 @@
1/*
2 * linux/arch/arm/mach-omap/omap2/irq.c
3 *
4 * Interrupt handler for OMAP2 boards.
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Paul Mundt <paul.mundt@nokia.com>
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/config.h>
16#include <linux/interrupt.h>
17#include <asm/hardware.h>
18#include <asm/mach/irq.h>
19#include <asm/irq.h>
20#include <asm/io.h>
21
22#define INTC_REVISION 0x0000
23#define INTC_SYSCONFIG 0x0010
24#define INTC_SYSSTATUS 0x0014
25#define INTC_CONTROL 0x0048
26#define INTC_MIR_CLEAR0 0x0088
27#define INTC_MIR_SET0 0x008c
28
29/*
30 * OMAP2 has a number of different interrupt controllers, each interrupt
31 * controller is identified as its own "bank". Register definitions are
32 * fairly consistent for each bank, but not all registers are implemented
33 * for each bank.. when in doubt, consult the TRM.
34 */
35static struct omap_irq_bank {
36 unsigned long base_reg;
37 unsigned int nr_irqs;
38} __attribute__ ((aligned(4))) irq_banks[] = {
39 {
40 /* MPU INTC */
41 .base_reg = OMAP24XX_IC_BASE,
42 .nr_irqs = 96,
43 }, {
44 /* XXX: DSP INTC */
45
46#if 0
47 /*
48 * Commented out for now until we fix the IVA clocking
49 */
50#ifdef CONFIG_ARCH_OMAP2420
51 }, {
52 /* IVA INTC (2420 only) */
53 .base_reg = OMAP24XX_IVA_INTC_BASE,
54 .nr_irqs = 16, /* Actually 32, but only 16 are used */
55#endif
56#endif
57 }
58};
59
60/* XXX: FIQ and additional INTC support (only MPU at the moment) */
61static void omap_ack_irq(unsigned int irq)
62{
63 omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
64}
65
66static void omap_mask_irq(unsigned int irq)
67{
68 int offset = (irq >> 5) << 5;
69
70 if (irq >= 64) {
71 irq %= 64;
72 } else if (irq >= 32) {
73 irq %= 32;
74 }
75
76 omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
77}
78
79static void omap_unmask_irq(unsigned int irq)
80{
81 int offset = (irq >> 5) << 5;
82
83 if (irq >= 64) {
84 irq %= 64;
85 } else if (irq >= 32) {
86 irq %= 32;
87 }
88
89 omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
90}
91
92static void omap_mask_ack_irq(unsigned int irq)
93{
94 omap_mask_irq(irq);
95 omap_ack_irq(irq);
96}
97
98static struct irqchip omap_irq_chip = {
99 .ack = omap_mask_ack_irq,
100 .mask = omap_mask_irq,
101 .unmask = omap_unmask_irq,
102};
103
104static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
105{
106 unsigned long tmp;
107
108 tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff;
109 printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
110 "(revision %ld.%ld) with %d interrupts\n",
111 bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
112
113 tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG);
114 tmp |= 1 << 1; /* soft reset */
115 omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
116
117 while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
118 /* Wait for reset to complete */;
119}
120
121void __init omap_init_irq(void)
122{
123 unsigned long nr_irqs = 0;
124 unsigned int nr_banks = 0;
125 int i;
126
127 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
128 struct omap_irq_bank *bank = irq_banks + i;
129
130 /* XXX */
131 if (!bank->base_reg)
132 continue;
133
134 omap_irq_bank_init_one(bank);
135
136 nr_irqs += bank->nr_irqs;
137 nr_banks++;
138 }
139
140 printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
141 nr_irqs, nr_banks, nr_banks > 1 ? "s" : "");
142
143 for (i = 0; i < nr_irqs; i++) {
144 set_irq_chip(i, &omap_irq_chip);
145 set_irq_handler(i, do_level_IRQ);
146 set_irq_flags(i, IRQF_VALID);
147 }
148}
149
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
new file mode 100644
index 000000000000..ea4654815dd1
--- /dev/null
+++ b/arch/arm/mach-omap2/mux.c
@@ -0,0 +1,65 @@
1/*
2 * linux/arch/arm/mach-omap2/mux.c
3 *
4 * OMAP1 pin multiplexing configurations
5 *
6 * Copyright (C) 2003 - 2005 Nokia Corporation
7 *
8 * Written by Tony Lindgren <tony.lindgren@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25#include <linux/config.h>
26#include <linux/module.h>
27#include <linux/init.h>
28#include <asm/system.h>
29#include <asm/io.h>
30#include <linux/spinlock.h>
31
32#include <asm/arch/mux.h>
33
34#ifdef CONFIG_OMAP_MUX
35
36/* NOTE: See mux.h for the enumeration */
37
38struct pin_config __initdata_or_module omap24xx_pins[] = {
39/*
40 * description mux mux pull pull debug
41 * offset mode ena type
42 */
43
44/* 24xx I2C */
45MUX_CFG_24XX("M19_24XX_I2C1_SCL", 0x111, 0, 0, 0, 1)
46MUX_CFG_24XX("L15_24XX_I2C1_SDA", 0x112, 0, 0, 0, 1)
47MUX_CFG_24XX("J15_24XX_I2C2_SCL", 0x113, 0, 0, 0, 1)
48MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1)
49
50/* Menelaus interrupt */
51MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
52
53/* 24xx GPIO */
54MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
55MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
56
57};
58
59int __init omap2_mux_init(void)
60{
61 omap_mux_register(omap24xx_pins, ARRAY_SIZE(omap24xx_pins));
62 return 0;
63}
64
65#endif
diff --git a/arch/arm/mach-omap2/prcm.h b/arch/arm/mach-omap2/prcm.h
new file mode 100644
index 000000000000..2eb89b936c83
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm.h
@@ -0,0 +1,419 @@
1/*
2 * prcm.h - Access definations for use in OMAP24XX clock and power management
3 *
4 * Copyright (C) 2005 Texas Instruments, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
22#define __ASM_ARM_ARCH_DPM_PRCM_H
23
24/* SET_PERFORMANCE_LEVEL PARAMETERS */
25#define PRCM_HALF_SPEED 1
26#define PRCM_FULL_SPEED 2
27
28#ifndef __ASSEMBLER__
29
30#define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset))
31
32#define PRCM_REVISION PRCM_REG32(0x000)
33#define PRCM_SYSCONFIG PRCM_REG32(0x010)
34#define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018)
35#define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C)
36#define PRCM_VOLTCTRL PRCM_REG32(0x050)
37#define PRCM_VOLTST PRCM_REG32(0x054)
38#define PRCM_CLKSRC_CTRL PRCM_REG32(0x060)
39#define PRCM_CLKOUT_CTRL PRCM_REG32(0x070)
40#define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078)
41#define PRCM_CLKCFG_CTRL PRCM_REG32(0x080)
42#define PRCM_CLKCFG_STATUS PRCM_REG32(0x084)
43#define PRCM_VOLTSETUP PRCM_REG32(0x090)
44#define PRCM_CLKSSETUP PRCM_REG32(0x094)
45#define PRCM_POLCTRL PRCM_REG32(0x098)
46
47/* GENERAL PURPOSE */
48#define GENERAL_PURPOSE1 PRCM_REG32(0x0B0)
49#define GENERAL_PURPOSE2 PRCM_REG32(0x0B4)
50#define GENERAL_PURPOSE3 PRCM_REG32(0x0B8)
51#define GENERAL_PURPOSE4 PRCM_REG32(0x0BC)
52#define GENERAL_PURPOSE5 PRCM_REG32(0x0C0)
53#define GENERAL_PURPOSE6 PRCM_REG32(0x0C4)
54#define GENERAL_PURPOSE7 PRCM_REG32(0x0C8)
55#define GENERAL_PURPOSE8 PRCM_REG32(0x0CC)
56#define GENERAL_PURPOSE9 PRCM_REG32(0x0D0)
57#define GENERAL_PURPOSE10 PRCM_REG32(0x0D4)
58#define GENERAL_PURPOSE11 PRCM_REG32(0x0D8)
59#define GENERAL_PURPOSE12 PRCM_REG32(0x0DC)
60#define GENERAL_PURPOSE13 PRCM_REG32(0x0E0)
61#define GENERAL_PURPOSE14 PRCM_REG32(0x0E4)
62#define GENERAL_PURPOSE15 PRCM_REG32(0x0E8)
63#define GENERAL_PURPOSE16 PRCM_REG32(0x0EC)
64#define GENERAL_PURPOSE17 PRCM_REG32(0x0F0)
65#define GENERAL_PURPOSE18 PRCM_REG32(0x0F4)
66#define GENERAL_PURPOSE19 PRCM_REG32(0x0F8)
67#define GENERAL_PURPOSE20 PRCM_REG32(0x0FC)
68
69/* MPU */
70#define CM_CLKSEL_MPU PRCM_REG32(0x140)
71#define CM_CLKSTCTRL_MPU PRCM_REG32(0x148)
72#define RM_RSTST_MPU PRCM_REG32(0x158)
73#define PM_WKDEP_MPU PRCM_REG32(0x1C8)
74#define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4)
75#define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8)
76#define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC)
77#define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0)
78#define PM_PWSTST_MPU PRCM_REG32(0x1E4)
79
80/* CORE */
81#define CM_FCLKEN1_CORE PRCM_REG32(0x200)
82#define CM_FCLKEN2_CORE PRCM_REG32(0x204)
83#define CM_FCLKEN3_CORE PRCM_REG32(0x208)
84#define CM_ICLKEN1_CORE PRCM_REG32(0x210)
85#define CM_ICLKEN2_CORE PRCM_REG32(0x214)
86#define CM_ICLKEN3_CORE PRCM_REG32(0x218)
87#define CM_ICLKEN4_CORE PRCM_REG32(0x21C)
88#define CM_IDLEST1_CORE PRCM_REG32(0x220)
89#define CM_IDLEST2_CORE PRCM_REG32(0x224)
90#define CM_IDLEST3_CORE PRCM_REG32(0x228)
91#define CM_IDLEST4_CORE PRCM_REG32(0x22C)
92#define CM_AUTOIDLE1_CORE PRCM_REG32(0x230)
93#define CM_AUTOIDLE2_CORE PRCM_REG32(0x234)
94#define CM_AUTOIDLE3_CORE PRCM_REG32(0x238)
95#define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C)
96#define CM_CLKSEL1_CORE PRCM_REG32(0x240)
97#define CM_CLKSEL2_CORE PRCM_REG32(0x244)
98#define CM_CLKSTCTRL_CORE PRCM_REG32(0x248)
99#define PM_WKEN1_CORE PRCM_REG32(0x2A0)
100#define PM_WKEN2_CORE PRCM_REG32(0x2A4)
101#define PM_WKST1_CORE PRCM_REG32(0x2B0)
102#define PM_WKST2_CORE PRCM_REG32(0x2B4)
103#define PM_WKDEP_CORE PRCM_REG32(0x2C8)
104#define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0)
105#define PM_PWSTST_CORE PRCM_REG32(0x2E4)
106
107/* GFX */
108#define CM_FCLKEN_GFX PRCM_REG32(0x300)
109#define CM_ICLKEN_GFX PRCM_REG32(0x310)
110#define CM_IDLEST_GFX PRCM_REG32(0x320)
111#define CM_CLKSEL_GFX PRCM_REG32(0x340)
112#define CM_CLKSTCTRL_GFX PRCM_REG32(0x348)
113#define RM_RSTCTRL_GFX PRCM_REG32(0x350)
114#define RM_RSTST_GFX PRCM_REG32(0x358)
115#define PM_WKDEP_GFX PRCM_REG32(0x3C8)
116#define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0)
117#define PM_PWSTST_GFX PRCM_REG32(0x3E4)
118
119/* WAKE-UP */
120#define CM_FCLKEN_WKUP PRCM_REG32(0x400)
121#define CM_ICLKEN_WKUP PRCM_REG32(0x410)
122#define CM_IDLEST_WKUP PRCM_REG32(0x420)
123#define CM_AUTOIDLE_WKUP PRCM_REG32(0x430)
124#define CM_CLKSEL_WKUP PRCM_REG32(0x440)
125#define RM_RSTCTRL_WKUP PRCM_REG32(0x450)
126#define RM_RSTTIME_WKUP PRCM_REG32(0x454)
127#define RM_RSTST_WKUP PRCM_REG32(0x458)
128#define PM_WKEN_WKUP PRCM_REG32(0x4A0)
129#define PM_WKST_WKUP PRCM_REG32(0x4B0)
130
131/* CLOCKS */
132#define CM_CLKEN_PLL PRCM_REG32(0x500)
133#define CM_IDLEST_CKGEN PRCM_REG32(0x520)
134#define CM_AUTOIDLE_PLL PRCM_REG32(0x530)
135#define CM_CLKSEL1_PLL PRCM_REG32(0x540)
136#define CM_CLKSEL2_PLL PRCM_REG32(0x544)
137
138/* DSP */
139#define CM_FCLKEN_DSP PRCM_REG32(0x800)
140#define CM_ICLKEN_DSP PRCM_REG32(0x810)
141#define CM_IDLEST_DSP PRCM_REG32(0x820)
142#define CM_AUTOIDLE_DSP PRCM_REG32(0x830)
143#define CM_CLKSEL_DSP PRCM_REG32(0x840)
144#define CM_CLKSTCTRL_DSP PRCM_REG32(0x848)
145#define RM_RSTCTRL_DSP PRCM_REG32(0x850)
146#define RM_RSTST_DSP PRCM_REG32(0x858)
147#define PM_WKEN_DSP PRCM_REG32(0x8A0)
148#define PM_WKDEP_DSP PRCM_REG32(0x8C8)
149#define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0)
150#define PM_PWSTST_DSP PRCM_REG32(0x8E4)
151#define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0)
152#define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4)
153
154/* IVA */
155#define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8)
156#define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC)
157
158/* Modem on 2430 */
159#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
160#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
161#define CM_IDLEST_MDM PRCM_REG32(0xC20)
162#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
163
164/* FIXME: Move to header for 2430 */
165#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
166#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
167
168#define GPMC_BASE (OMAP24XX_GPMC_BASE)
169#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
170
171#define GPT1_BASE (OMAP24XX_GPT1)
172#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
173
174/* Misc sysconfig */
175#define DISPC_SYSCONFIG DISP_REG32(0x410)
176#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
177#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
178#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
179
180//#define DSP_MMU_SYSCONFIG 0x5A000010
181#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
182//#define IVA_MMU_SYSCONFIG 0x5D000010
183//#define DSP_DMA_SYSCONFIG 0x00FCC02C
184#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
185#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
186#define GPMC_SYSCONFIG GPMC_REG32(0x010)
187#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
188#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
189#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
190#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
191//#define IVA_SYSCONFIG 0x5C060010
192#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
193#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
194#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
195//#define VLYNQ_SYSCONFIG 0x67FFFE10
196
197/* rkw - good cannidates for PM_ to start what nm was trying */
198#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
199#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
200#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
201#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
202#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
203#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
204#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
205#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
206#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
207#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
208#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
209
210#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
211#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
212#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
213#define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10)
214#define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10)
215#define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10)
216#define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10)
217#define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10)
218#define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10)
219#define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10)
220#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
221#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
222
223#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
224
225#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
226#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
227#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
228#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
229
230/* GP TIMER 1 */
231#define GPTIMER1_TISTAT GPT1_REG32(0x014)
232#define GPTIMER1_TISR GPT1_REG32(0x018)
233#define GPTIMER1_TIER GPT1_REG32(0x01C)
234#define GPTIMER1_TWER GPT1_REG32(0x020)
235#define GPTIMER1_TCLR GPT1_REG32(0x024)
236#define GPTIMER1_TCRR GPT1_REG32(0x028)
237#define GPTIMER1_TLDR GPT1_REG32(0x02C)
238#define GPTIMER1_TTGR GPT1_REG32(0x030)
239#define GPTIMER1_TWPS GPT1_REG32(0x034)
240#define GPTIMER1_TMAR GPT1_REG32(0x038)
241#define GPTIMER1_TCAR1 GPT1_REG32(0x03C)
242#define GPTIMER1_TSICR GPT1_REG32(0x040)
243#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
244
245/* rkw -- base fix up please... */
246#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
247
248/* SDRC */
249#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
250#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
251#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
252#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
253#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
254#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
255
256/* GPIO 1 */
257#define GPIO1_BASE GPIOX_BASE(1)
258#define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset))
259#define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C)
260#define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018)
261#define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C)
262#define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028)
263#define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020)
264#define GPIO1_RISINGDETECT GPIO1_REG32(0x048)
265#define GPIO1_DATAIN GPIO1_REG32(0x038)
266#define GPIO1_OE GPIO1_REG32(0x034)
267#define GPIO1_DATAOUT GPIO1_REG32(0x03C)
268
269/* GPIO2 */
270#define GPIO2_BASE GPIOX_BASE(2)
271#define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset))
272#define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C)
273#define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018)
274#define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C)
275#define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028)
276#define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020)
277#define GPIO2_RISINGDETECT GPIO2_REG32(0x048)
278#define GPIO2_DATAIN GPIO2_REG32(0x038)
279#define GPIO2_OE GPIO2_REG32(0x034)
280#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
281
282/* GPIO 3 */
283#define GPIO3_BASE GPIOX_BASE(3)
284#define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset))
285#define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C)
286#define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018)
287#define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C)
288#define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028)
289#define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020)
290#define GPIO3_RISINGDETECT GPIO3_REG32(0x048)
291#define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C)
292#define GPIO3_DATAIN GPIO3_REG32(0x038)
293#define GPIO3_OE GPIO3_REG32(0x034)
294#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
295#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
296#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
297
298/* GPIO 4 */
299#define GPIO4_BASE GPIOX_BASE(4)
300#define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset))
301#define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C)
302#define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018)
303#define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C)
304#define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028)
305#define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020)
306#define GPIO4_RISINGDETECT GPIO4_REG32(0x048)
307#define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C)
308#define GPIO4_DATAIN GPIO4_REG32(0x038)
309#define GPIO4_OE GPIO4_REG32(0x034)
310#define GPIO4_DATAOUT GPIO4_REG32(0x03C)
311#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
312#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
313
314
315/* IO CONFIG */
316#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
317#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
318
319#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
320#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
321#define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8)
322#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
323#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
324#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
325#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
326#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
327#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
328
329/* CONTROL */
330#define CONTROL_DEVCONF CONTROL_REG32(0x274)
331
332/* INTERRUPT CONTROLLER */
333#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
334#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
335
336#define INTC1_U_BASE INTC_REG32(0x000)
337#define INTC_MIR0 INTC_REG32(0x084)
338#define INTC_MIR_SET0 INTC_REG32(0x08C)
339#define INTC_MIR_CLEAR0 INTC_REG32(0x088)
340#define INTC_ISR_CLEAR0 INTC_REG32(0x094)
341#define INTC_MIR1 INTC_REG32(0x0A4)
342#define INTC_MIR_SET1 INTC_REG32(0x0AC)
343#define INTC_MIR_CLEAR1 INTC_REG32(0x0A8)
344#define INTC_ISR_CLEAR1 INTC_REG32(0x0B4)
345#define INTC_MIR2 INTC_REG32(0x0C4)
346#define INTC_MIR_SET2 INTC_REG32(0x0CC)
347#define INTC_MIR_CLEAR2 INTC_REG32(0x0C8)
348#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
349#define INTC_SIR_IRQ INTC_REG32(0x040)
350#define INTC_CONTROL INTC_REG32(0x048)
351#define INTC_ILR11 INTC_REG32(0x12C)
352#define INTC_ILR32 INTC_REG32(0x180)
353#define INTC_ILR37 INTC_REG32(0x194)
354#define INTC_SYSCONFIG INTC_REG32(0x010)
355
356/* RAM FIREWALL */
357#define RAMFW_BASE (0x68005000)
358#define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset))
359
360#define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048)
361#define RAMFW_READPERM0 RAMFW_REG32(0x050)
362#define RAMFW_WRITEPERM0 RAMFW_REG32(0x058)
363
364/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
365//#define DEBUG_BOARD_LED_REGISTER 0x04000014
366
367/* GPMC CS0 */
368#define GPMC_CONFIG1_0 GPMC_REG32(0x060)
369#define GPMC_CONFIG2_0 GPMC_REG32(0x064)
370#define GPMC_CONFIG3_0 GPMC_REG32(0x068)
371#define GPMC_CONFIG4_0 GPMC_REG32(0x06C)
372#define GPMC_CONFIG5_0 GPMC_REG32(0x070)
373#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
374#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
375
376/* DSS */
377#define DSS_CONTROL DISP_REG32(0x040)
378#define DISPC_CONTROL DISP_REG32(0x440)
379#define DISPC_SYSSTATUS DISP_REG32(0x414)
380#define DISPC_IRQSTATUS DISP_REG32(0x418)
381#define DISPC_IRQENABLE DISP_REG32(0x41C)
382#define DISPC_CONFIG DISP_REG32(0x444)
383#define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C)
384#define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450)
385#define DISPC_TRANS_COLOR0 DISP_REG32(0x454)
386#define DISPC_TRANS_COLOR1 DISP_REG32(0x458)
387#define DISPC_LINE_NUMBER DISP_REG32(0x460)
388#define DISPC_TIMING_H DISP_REG32(0x464)
389#define DISPC_TIMING_V DISP_REG32(0x468)
390#define DISPC_POL_FREQ DISP_REG32(0x46C)
391#define DISPC_DIVISOR DISP_REG32(0x470)
392#define DISPC_SIZE_DIG DISP_REG32(0x478)
393#define DISPC_SIZE_LCD DISP_REG32(0x47C)
394#define DISPC_GFX_BA0 DISP_REG32(0x480)
395#define DISPC_GFX_BA1 DISP_REG32(0x484)
396#define DISPC_GFX_POSITION DISP_REG32(0x488)
397#define DISPC_GFX_SIZE DISP_REG32(0x48C)
398#define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0)
399#define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4)
400#define DISPC_GFX_ROW_INC DISP_REG32(0x4AC)
401#define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0)
402#define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4)
403#define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8)
404#define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4)
405#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
406#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
407
408/* Wake up define for board */
409#define GPIO97 (1 << 1)
410#define GPIO88 (1 << 24)
411
412#endif /* __ASSEMBLER__ */
413
414#endif
415
416
417
418
419
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
new file mode 100644
index 000000000000..f4df04fe1dd8
--- /dev/null
+++ b/arch/arm/mach-omap2/serial.c
@@ -0,0 +1,180 @@
1/*
2 * arch/arm/mach-omap/omap2/serial.c
3 *
4 * OMAP2 serial support.
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Paul Mundt <paul.mundt@nokia.com>
8 *
9 * Based off of arch/arm/mach-omap/omap1/serial.c
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/serial_8250.h>
18#include <linux/serial_reg.h>
19
20#include <asm/io.h>
21#include <asm/hardware/clock.h>
22
23#include <asm/arch/common.h>
24#include <asm/arch/board.h>
25
26static struct clk * uart1_ick = NULL;
27static struct clk * uart1_fck = NULL;
28static struct clk * uart2_ick = NULL;
29static struct clk * uart2_fck = NULL;
30static struct clk * uart3_ick = NULL;
31static struct clk * uart3_fck = NULL;
32
33static struct plat_serial8250_port serial_platform_data[] = {
34 {
35 .membase = (char *)IO_ADDRESS(OMAP_UART1_BASE),
36 .mapbase = (unsigned long)OMAP_UART1_BASE,
37 .irq = 72,
38 .flags = UPF_BOOT_AUTOCONF,
39 .iotype = UPIO_MEM,
40 .regshift = 2,
41 .uartclk = OMAP16XX_BASE_BAUD * 16,
42 }, {
43 .membase = (char *)IO_ADDRESS(OMAP_UART2_BASE),
44 .mapbase = (unsigned long)OMAP_UART2_BASE,
45 .irq = 73,
46 .flags = UPF_BOOT_AUTOCONF,
47 .iotype = UPIO_MEM,
48 .regshift = 2,
49 .uartclk = OMAP16XX_BASE_BAUD * 16,
50 }, {
51 .membase = (char *)IO_ADDRESS(OMAP_UART3_BASE),
52 .mapbase = (unsigned long)OMAP_UART3_BASE,
53 .irq = 74,
54 .flags = UPF_BOOT_AUTOCONF,
55 .iotype = UPIO_MEM,
56 .regshift = 2,
57 .uartclk = OMAP16XX_BASE_BAUD * 16,
58 }, {
59 .flags = 0
60 }
61};
62
63static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
64 int offset)
65{
66 offset <<= up->regshift;
67 return (unsigned int)__raw_readb(up->membase + offset);
68}
69
70static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
71 int value)
72{
73 offset <<= p->regshift;
74 __raw_writeb(value, (unsigned long)(p->membase + offset));
75}
76
77/*
78 * Internal UARTs need to be initialized for the 8250 autoconfig to work
79 * properly. Note that the TX watermark initialization may not be needed
80 * once the 8250.c watermark handling code is merged.
81 */
82static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
83{
84 serial_write_reg(p, UART_OMAP_MDR1, 0x07);
85 serial_write_reg(p, UART_OMAP_SCR, 0x08);
86 serial_write_reg(p, UART_OMAP_MDR1, 0x00);
87 serial_write_reg(p, UART_OMAP_SYSC, 0x01);
88}
89
90void __init omap_serial_init()
91{
92 int i;
93 const struct omap_uart_config *info;
94
95 /*
96 * Make sure the serial ports are muxed on at this point.
97 * You have to mux them off in device drivers later on
98 * if not needed.
99 */
100
101 info = omap_get_config(OMAP_TAG_UART,
102 struct omap_uart_config);
103
104 if (info == NULL)
105 return;
106
107 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
108 struct plat_serial8250_port *p = serial_platform_data + i;
109
110 if (!(info->enabled_uarts & (1 << i))) {
111 p->membase = 0;
112 p->mapbase = 0;
113 continue;
114 }
115
116 switch (i) {
117 case 0:
118 uart1_ick = clk_get(NULL, "uart1_ick");
119 if (IS_ERR(uart1_ick))
120 printk("Could not get uart1_ick\n");
121 else {
122 clk_use(uart1_ick);
123 }
124
125 uart1_fck = clk_get(NULL, "uart1_fck");
126 if (IS_ERR(uart1_fck))
127 printk("Could not get uart1_fck\n");
128 else {
129 clk_use(uart1_fck);
130 }
131 break;
132 case 1:
133 uart2_ick = clk_get(NULL, "uart2_ick");
134 if (IS_ERR(uart2_ick))
135 printk("Could not get uart2_ick\n");
136 else {
137 clk_use(uart2_ick);
138 }
139
140 uart2_fck = clk_get(NULL, "uart2_fck");
141 if (IS_ERR(uart2_fck))
142 printk("Could not get uart2_fck\n");
143 else {
144 clk_use(uart2_fck);
145 }
146 break;
147 case 2:
148 uart3_ick = clk_get(NULL, "uart3_ick");
149 if (IS_ERR(uart3_ick))
150 printk("Could not get uart3_ick\n");
151 else {
152 clk_use(uart3_ick);
153 }
154
155 uart3_fck = clk_get(NULL, "uart3_fck");
156 if (IS_ERR(uart3_fck))
157 printk("Could not get uart3_fck\n");
158 else {
159 clk_use(uart3_fck);
160 }
161 break;
162 }
163
164 omap_serial_reset(p);
165 }
166}
167
168static struct platform_device serial_device = {
169 .name = "serial8250",
170 .id = 0,
171 .dev = {
172 .platform_data = serial_platform_data,
173 },
174};
175
176static int __init omap_init(void)
177{
178 return platform_device_register(&serial_device);
179}
180arch_initcall(omap_init);
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S
new file mode 100644
index 000000000000..2a869e203342
--- /dev/null
+++ b/arch/arm/mach-omap2/sram-fn.S
@@ -0,0 +1,333 @@
1/*
2 * linux/arch/arm/mach-omap1/sram.S
3 *
4 * Omap2 specific functions that need to be run in internal SRAM
5 *
6 * (C) Copyright 2004
7 * Texas Instruments, <www.ti.com>
8 * Richard Woodruff <r-woodruff2@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25#include <linux/config.h>
26#include <linux/linkage.h>
27#include <asm/assembler.h>
28#include <asm/arch/io.h>
29#include <asm/hardware.h>
30
31#include <asm/arch/prcm.h>
32
33#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
34
35#define CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x544)
36#define PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x050)
37#define PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x080)
38#define CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x500)
39#define CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x520)
40#define CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x540)
41
42#define SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x060)
43#define SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x0a4)
44
45 .text
46
47ENTRY(sram_ddr_init)
48 stmfd sp!, {r0 - r12, lr} @ save registers on stack
49
50 mov r12, r2 @ capture CS1 vs CS0
51 mov r8, r3 @ capture force parameter
52
53 /* frequency shift down */
54 ldr r2, cm_clksel2_pll @ get address of dpllout reg
55 mov r3, #0x1 @ value for 1x operation
56 str r3, [r2] @ go to L1-freq operation
57
58 /* voltage shift down */
59 mov r9, #0x1 @ set up for L1 voltage call
60 bl voltage_shift @ go drop voltage
61
62 /* dll lock mode */
63 ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl
64 ldr r10, [r11] @ get current val
65 cmp r12, #0x1 @ cs1 base (2422 es2.05/1)
66 addeq r11, r11, #0x8 @ if cs1 base, move to DLLB
67 mvn r9, #0x4 @ mask to get clear bit2
68 and r10, r10, r9 @ clear bit2 for lock mode.
69 orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
70 orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz
71 str r10, [r11] @ commit to DLLA_CTRL
72 bl i_dll_wait @ wait for dll to lock
73
74 /* get dll value */
75 add r11, r11, #0x4 @ get addr of status reg
76 ldr r10, [r11] @ get locked value
77
78 /* voltage shift up */
79 mov r9, #0x0 @ shift back to L0-voltage
80 bl voltage_shift @ go raise voltage
81
82 /* frequency shift up */
83 mov r3, #0x2 @ value for 2x operation
84 str r3, [r2] @ go to L0-freq operation
85
86 /* reset entry mode for dllctrl */
87 sub r11, r11, #0x4 @ move from status to ctrl
88 cmp r12, #0x1 @ normalize if cs1 based
89 subeq r11, r11, #0x8 @ possibly back to DLLA
90 cmp r8, #0x1 @ if forced unlock exit
91 orreq r1, r1, #0x4 @ make sure exit with unlocked value
92 str r1, [r11] @ restore DLLA_CTRL high value
93 add r11, r11, #0x8 @ move to DLLB_CTRL addr
94 str r1, [r11] @ set value DLLB_CTRL
95 bl i_dll_wait @ wait for possible lock
96
97 /* set up for return, DDR should be good */
98 str r10, [r0] @ write dll_status and return counter
99 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
100
101 /* ensure the DLL has relocked */
102i_dll_wait:
103 mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks
104i_dll_delay:
105 subs r4, r4, #0x1
106 bne i_dll_delay
107 mov pc, lr
108
109 /*
110 * shift up or down voltage, use R9 as input to tell level.
111 * wait for it to finish, use 32k sync counter, 1tick=31uS.
112 */
113voltage_shift:
114 ldr r4, prcm_voltctrl @ get addr of volt ctrl.
115 ldr r5, [r4] @ get value.
116 ldr r6, prcm_mask_val @ get value of mask
117 and r5, r5, r6 @ apply mask to clear bits
118 orr r5, r5, r9 @ bulld value for L0/L1-volt operation.
119 str r5, [r4] @ set up for change.
120 mov r3, #0x4000 @ get val for force
121 orr r5, r5, r3 @ build value for force
122 str r5, [r4] @ Force transition to L1
123
124 ldr r3, timer_32ksynct_cr @ get addr of counter
125 ldr r5, [r3] @ get value
126 add r5, r5, #0x3 @ give it at most 93uS
127volt_delay:
128 ldr r7, [r3] @ get timer value
129 cmp r5, r7 @ time up?
130 bhi volt_delay @ not yet->branch
131 mov pc, lr @ back to caller.
132
133/* relative load constants */
134cm_clksel2_pll:
135 .word CM_CLKSEL2_PLL_V
136sdrc_dlla_ctrl:
137 .word SDRC_DLLA_CTRL_V
138prcm_voltctrl:
139 .word PRCM_VOLTCTRL_V
140prcm_mask_val:
141 .word 0xFFFF3FFC
142timer_32ksynct_cr:
143 .word TIMER_32KSYNCT_CR_V
144ENTRY(sram_ddr_init_sz)
145 .word . - sram_ddr_init
146
147/*
148 * Reprograms memory timings.
149 * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
150 * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
151 */
152ENTRY(sram_reprogram_sdrc)
153 stmfd sp!, {r0 - r10, lr} @ save registers on stack
154 mov r3, #0x0 @ clear for mrc call
155 mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR
156 nop
157 nop
158 ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg
159 ldr r5, [r6] @ get value
160 mov r5, r5, lsr #8 @ isolate rfr field and drop burst
161
162 cmp r0, #0x1 @ going to half speed?
163 movne r9, #0x0 @ if up set flag up for pre up, hi volt
164
165 blne voltage_shift_c @ adjust voltage
166
167 cmp r0, #0x1 @ going to half speed (post branch link)
168 moveq r5, r5, lsr #1 @ divide by 2 if to half
169 movne r5, r5, lsl #1 @ mult by 2 if to full
170 mov r5, r5, lsl #8 @ put rfr field back into place
171 add r5, r5, #0x1 @ turn on burst of 1
172 ldr r4, ddr_cm_clksel2_pll @ get address of out reg
173 ldr r3, [r4] @ get curr value
174 orr r3, r3, #0x3
175 bic r3, r3, #0x3 @ clear lower bits
176 orr r3, r3, r0 @ new state value
177 str r3, [r4] @ set new state (pll/x, x=1 or 2)
178 nop
179 nop
180
181 moveq r9, #0x1 @ if speed down, post down, drop volt
182 bleq voltage_shift_c
183
184 mcr p15, 0, r3, c7, c10, 4 @ memory barrier
185 str r5, [r6] @ set new RFR_1 value
186 add r6, r6, #0x30 @ get RFR_2 addr
187 str r5, [r6] @ set RFR_2
188 nop
189 cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL
190 bne freq_out @ leave if SDR, no DLL function
191
192 /* With DDR, we need to take care of the DLL for the frequency change */
193 ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl
194 str r1, [r2] @ write out new SDRC_DLLA_CTRL
195 add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL
196 str r1, [r2] @ commit to SDRC_DLLB_CTRL
197 mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks
198dll_wait:
199 subs r1, r1, #0x1
200 bne dll_wait
201freq_out:
202 ldmfd sp!, {r0 - r10, pc} @ restore regs and return
203
204 /*
205 * shift up or down voltage, use R9 as input to tell level.
206 * wait for it to finish, use 32k sync counter, 1tick=31uS.
207 */
208voltage_shift_c:
209 ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl
210 ldr r8, [r10] @ get value
211 ldr r7, ddr_prcm_mask_val @ get value of mask
212 and r8, r8, r7 @ apply mask to clear bits
213 orr r8, r8, r9 @ bulld value for L0/L1-volt operation.
214 str r8, [r10] @ set up for change.
215 mov r7, #0x4000 @ get val for force
216 orr r8, r8, r7 @ build value for force
217 str r8, [r10] @ Force transition to L1
218
219 ldr r10, ddr_timer_32ksynct @ get addr of counter
220 ldr r8, [r10] @ get value
221 add r8, r8, #0x2 @ give it at most 62uS (min 31+)
222volt_delay_c:
223 ldr r7, [r10] @ get timer value
224 cmp r8, r7 @ time up?
225 bhi volt_delay_c @ not yet->branch
226 mov pc, lr @ back to caller
227
228ddr_cm_clksel2_pll:
229 .word CM_CLKSEL2_PLL_V
230ddr_sdrc_dlla_ctrl:
231 .word SDRC_DLLA_CTRL_V
232ddr_sdrc_rfr_ctrl:
233 .word SDRC_RFR_CTRL_V
234ddr_prcm_voltctrl:
235 .word PRCM_VOLTCTRL_V
236ddr_prcm_mask_val:
237 .word 0xFFFF3FFC
238ddr_timer_32ksynct:
239 .word TIMER_32KSYNCT_CR_V
240
241ENTRY(sram_reprogram_sdrc_sz)
242 .word . - sram_reprogram_sdrc
243
244/*
245 * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
246 */
247ENTRY(sram_set_prcm)
248 stmfd sp!, {r0-r12, lr} @ regs to stack
249 adr r4, pbegin @ addr of preload start
250 adr r8, pend @ addr of preload end
251 mcrr p15, 1, r8, r4, c12 @ preload into icache
252pbegin:
253 /* move into fast relock bypass */
254 ldr r8, pll_ctl @ get addr
255 ldr r5, [r8] @ get val
256 mvn r6, #0x3 @ clear mask
257 and r5, r5, r6 @ clear field
258 orr r7, r5, #0x2 @ fast relock val
259 str r7, [r8] @ go to fast relock
260 ldr r4, pll_stat @ addr of stat
261block:
262 /* wait for bypass */
263 ldr r8, [r4] @ stat value
264 and r8, r8, #0x3 @ mask for stat
265 cmp r8, #0x1 @ there yet
266 bne block @ loop if not
267
268 /* set new dpll dividers _after_ in bypass */
269 ldr r4, pll_div @ get addr
270 str r0, [r4] @ set dpll ctrl val
271
272 ldr r4, set_config @ get addr
273 mov r8, #1 @ valid cfg msk
274 str r8, [r4] @ make dividers take
275
276 mov r4, #100 @ dead spin a bit
277wait_a_bit:
278 subs r4, r4, #1 @ dec loop
279 bne wait_a_bit @ delay done?
280
281 /* check if staying in bypass */
282 cmp r2, #0x1 @ stay in bypass?
283 beq pend @ jump over dpll relock
284
285 /* relock DPLL with new vals */
286 ldr r5, pll_stat @ get addr
287 ldr r4, pll_ctl @ get addr
288 orr r8, r7, #0x3 @ val for lock dpll
289 str r8, [r4] @ set val
290 mov r0, #1000 @ dead spin a bit
291wait_more:
292 subs r0, r0, #1 @ dec loop
293 bne wait_more @ delay done?
294wait_lock:
295 ldr r8, [r5] @ get lock val
296 and r8, r8, #3 @ isolate field
297 cmp r8, #2 @ locked?
298 bne wait_lock @ wait if not
299pend:
300 /* update memory timings & briefly lock dll */
301 ldr r4, sdrc_rfr @ get addr
302 str r1, [r4] @ update refresh timing
303 ldr r11, dlla_ctrl @ get addr of DLLA ctrl
304 ldr r10, [r11] @ get current val
305 mvn r9, #0x4 @ mask to get clear bit2
306 and r10, r10, r9 @ clear bit2 for lock mode
307 orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
308 str r10, [r11] @ commit to DLLA_CTRL
309 add r11, r11, #0x8 @ move to dllb
310 str r10, [r11] @ hit DLLB also
311
312 mov r4, #0x800 @ relock time (min 0x400 L3 clocks)
313wait_dll_lock:
314 subs r4, r4, #0x1
315 bne wait_dll_lock
316 nop
317 ldmfd sp!, {r0-r12, pc} @ restore regs and return
318
319set_config:
320 .word PRCM_CLKCFG_CTRL_V
321pll_ctl:
322 .word CM_CLKEN_PLL_V
323pll_stat:
324 .word CM_IDLEST_CKGEN_V
325pll_div:
326 .word CM_CLKSEL1_PLL_V
327sdrc_rfr:
328 .word SDRC_RFR_CTRL_V
329dlla_ctrl:
330 .word SDRC_DLLA_CTRL_V
331
332ENTRY(sram_set_prcm_sz)
333 .word . - sram_set_prcm
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
new file mode 100644
index 000000000000..9ec11443200f
--- /dev/null
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -0,0 +1,126 @@
1/*
2 * linux/arch/arm/mach-omap2/timer-gp.c
3 *
4 * OMAP2 GP timer support.
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Paul Mundt <paul.mundt@nokia.com>
8 * Juha Yrjölä <juha.yrjola@nokia.com>
9 *
10 * Some parts based off of TI's 24xx code:
11 *
12 * Copyright (C) 2004 Texas Instruments, Inc.
13 *
14 * Roughly modelled after the OMAP1 MPU timer code.
15 *
16 * This file is subject to the terms and conditions of the GNU General Public
17 * License. See the file "COPYING" in the main directory of this archive
18 * for more details.
19 */
20#include <linux/init.h>
21#include <linux/time.h>
22#include <linux/interrupt.h>
23#include <linux/err.h>
24#include <asm/mach/time.h>
25#include <asm/delay.h>
26#include <asm/io.h>
27#include <asm/hardware/clock.h>
28
29#define OMAP2_GP_TIMER1_BASE 0x48028000
30#define OMAP2_GP_TIMER2_BASE 0x4802a000
31#define OMAP2_GP_TIMER3_BASE 0x48078000
32#define OMAP2_GP_TIMER4_BASE 0x4807a000
33
34#define GP_TIMER_TIDR 0x00
35#define GP_TIMER_TISR 0x18
36#define GP_TIMER_TIER 0x1c
37#define GP_TIMER_TCLR 0x24
38#define GP_TIMER_TCRR 0x28
39#define GP_TIMER_TLDR 0x2c
40#define GP_TIMER_TSICR 0x40
41
42#define OS_TIMER_NR 1 /* GP timer 2 */
43
44static unsigned long timer_base[] = {
45 IO_ADDRESS(OMAP2_GP_TIMER1_BASE),
46 IO_ADDRESS(OMAP2_GP_TIMER2_BASE),
47 IO_ADDRESS(OMAP2_GP_TIMER3_BASE),
48 IO_ADDRESS(OMAP2_GP_TIMER4_BASE),
49};
50
51static inline unsigned int timer_read_reg(int nr, unsigned int reg)
52{
53 return __raw_readl(timer_base[nr] + reg);
54}
55
56static inline void timer_write_reg(int nr, unsigned int reg, unsigned int val)
57{
58 __raw_writel(val, timer_base[nr] + reg);
59}
60
61/* Note that we always enable the clock prescale divider bit */
62static inline void omap2_gp_timer_start(int nr, unsigned long load_val)
63{
64 unsigned int tmp;
65
66 tmp = 0xffffffff - load_val;
67
68 timer_write_reg(nr, GP_TIMER_TLDR, tmp);
69 timer_write_reg(nr, GP_TIMER_TCRR, tmp);
70 timer_write_reg(nr, GP_TIMER_TIER, 1 << 1);
71 timer_write_reg(nr, GP_TIMER_TCLR, (1 << 5) | (1 << 1) | 1);
72}
73
74static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
75 struct pt_regs *regs)
76{
77 write_seqlock(&xtime_lock);
78
79 timer_write_reg(OS_TIMER_NR, GP_TIMER_TISR, 1 << 1);
80 timer_tick(regs);
81
82 write_sequnlock(&xtime_lock);
83
84 return IRQ_HANDLED;
85}
86
87static struct irqaction omap2_gp_timer_irq = {
88 .name = "gp timer",
89 .flags = SA_INTERRUPT,
90 .handler = omap2_gp_timer_interrupt,
91};
92
93static void __init omap2_gp_timer_init(void)
94{
95 struct clk * sys_ck;
96 u32 tick_period = 120000;
97 u32 l;
98
99 /* Reset clock and prescale value */
100 timer_write_reg(OS_TIMER_NR, GP_TIMER_TCLR, 0);
101
102 sys_ck = clk_get(NULL, "sys_ck");
103 if (IS_ERR(sys_ck))
104 printk(KERN_ERR "Could not get sys_ck\n");
105 else {
106 clk_use(sys_ck);
107 tick_period = clk_get_rate(sys_ck) / 100;
108 clk_put(sys_ck);
109 }
110
111 tick_period /= 2; /* Minimum prescale divider is 2 */
112 tick_period -= 1;
113
114 l = timer_read_reg(OS_TIMER_NR, GP_TIMER_TIDR);
115 printk(KERN_INFO "OMAP2 GP timer (HW version %d.%d)\n",
116 (l >> 4) & 0x0f, l & 0x0f);
117
118 setup_irq(38, &omap2_gp_timer_irq);
119
120 omap2_gp_timer_start(OS_TIMER_NR, tick_period);
121}
122
123struct sys_timer omap_timer = {
124 .init = omap2_gp_timer_init,
125};
126
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index b380a438e68f..e201aa9765b9 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -60,6 +60,7 @@ config MACH_CORGI
60 bool "Enable Sharp SL-C700 (Corgi) Support" 60 bool "Enable Sharp SL-C700 (Corgi) Support"
61 depends PXA_SHARPSL_25x 61 depends PXA_SHARPSL_25x
62 select PXA_SHARP_C7xx 62 select PXA_SHARP_C7xx
63 select PXA_SSP
63 64
64config MACH_SHEPHERD 65config MACH_SHEPHERD
65 bool "Enable Sharp SL-C750 (Shepherd) Support" 66 bool "Enable Sharp SL-C750 (Shepherd) Support"
@@ -102,12 +103,18 @@ config IWMMXT
102 103
103config PXA_SHARP_C7xx 104config PXA_SHARP_C7xx
104 bool 105 bool
106 select PXA_SSP
105 help 107 help
106 Enable support for all Sharp C7xx models 108 Enable support for all Sharp C7xx models
107 109
108config PXA_SHARP_Cxx00 110config PXA_SHARP_Cxx00
109 bool 111 bool
112 select PXA_SSP
110 help 113 help
111 Enable common support for Sharp Cxx00 models 114 Enable common support for Sharp Cxx00 models
112 115
116config PXA_SSP
117 tristate
118 help
119 Enable support for PXA2xx SSP ports
113endif 120endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 8bc72d07cea8..d210bd5032ce 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -11,8 +11,8 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o 11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o 12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o 14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o
15obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o 15obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o
16obj-$(CONFIG_MACH_POODLE) += poodle.o 16obj-$(CONFIG_MACH_POODLE) += poodle.o
17obj-$(CONFIG_MACH_TOSA) += tosa.o 17obj-$(CONFIG_MACH_TOSA) += tosa.o
18 18
@@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS) += $(led-y)
26 26
27# Misc features 27# Misc features
28obj-$(CONFIG_PM) += pm.o sleep.o 28obj-$(CONFIG_PM) += pm.o sleep.o
29obj-$(CONFIG_PXA_SSP) += ssp.o
29 30
30ifeq ($(CONFIG_PXA27x),y) 31ifeq ($(CONFIG_PXA27x),y)
31obj-$(CONFIG_PM) += standby.o 32obj-$(CONFIG_PM) += standby.o
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 9f835f32b938..b371d723635f 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -203,7 +203,7 @@ static int __init corgi_ssp_probe(struct platform_device *dev)
203 GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ 203 GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */
204 GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ 204 GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
205 205
206 ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port); 206 ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
207 207
208 if (ret) 208 if (ret)
209 printk(KERN_ERR "Unable to register SSP handler!\n"); 209 printk(KERN_ERR "Unable to register SSP handler!\n");
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index 3977a77aacdd..4879c0f7da72 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -32,3 +32,90 @@ void corgi_put_hsync(void);
32void spitz_put_hsync(void); 32void spitz_put_hsync(void);
33void corgi_wait_hsync(void); 33void corgi_wait_hsync(void);
34void spitz_wait_hsync(void); 34void spitz_wait_hsync(void);
35
36/*
37 * SharpSL Battery/PM Driver
38 */
39
40struct sharpsl_charger_machinfo {
41 void (*init)(void);
42 int gpio_acin;
43 int gpio_batfull;
44 int gpio_batlock;
45 int gpio_fatal;
46 int (*status_acin)(void);
47 void (*discharge)(int);
48 void (*discharge1)(int);
49 void (*charge)(int);
50 void (*chargeled)(int);
51 void (*measure_temp)(int);
52 void (*presuspend)(void);
53 void (*postsuspend)(void);
54 unsigned long (*charger_wakeup)(void);
55 int (*should_wakeup)(unsigned int resume_on_alarm);
56 int bat_levels;
57 struct battery_thresh *bat_levels_noac;
58 struct battery_thresh *bat_levels_acin;
59 int status_high_acin;
60 int status_low_acin;
61 int status_high_noac;
62 int status_low_noac;
63};
64
65struct battery_thresh {
66 int voltage;
67 int percentage;
68};
69
70struct battery_stat {
71 int ac_status; /* APM AC Present/Not Present */
72 int mainbat_status; /* APM Main Battery Status */
73 int mainbat_percent; /* Main Battery Percentage Charge */
74 int mainbat_voltage; /* Main Battery Voltage */
75};
76
77struct sharpsl_pm_status {
78 struct device *dev;
79 struct timer_list ac_timer;
80 struct timer_list chrg_full_timer;
81
82 int charge_mode;
83#define CHRG_ERROR (-1)
84#define CHRG_OFF (0)
85#define CHRG_ON (1)
86#define CHRG_DONE (2)
87
88 unsigned int flags;
89#define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */
90#define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */
91#define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */
92#define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */
93#define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */
94
95 int full_count;
96 unsigned long charge_start_time;
97 struct sharpsl_charger_machinfo *machinfo;
98 struct battery_stat battstat;
99};
100
101extern struct sharpsl_pm_status sharpsl_pm;
102extern struct battery_thresh spitz_battery_levels_acin[];
103extern struct battery_thresh spitz_battery_levels_noac[];
104
105#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
106
107#define SHARPSL_LED_ERROR 2
108#define SHARPSL_LED_ON 1
109#define SHARPSL_LED_OFF 0
110
111#define CHARGE_ON() sharpsl_pm.machinfo->charge(1)
112#define CHARGE_OFF() sharpsl_pm.machinfo->charge(0)
113#define CHARGE_LED_ON() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON)
114#define CHARGE_LED_OFF() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF)
115#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
116#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1)
117#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0)
118#define STATUS_AC_IN sharpsl_pm.machinfo->status_acin()
119#define STATUS_BATT_LOCKED READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
120#define STATUS_CHRG_FULL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
121#define STATUS_FATAL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
new file mode 100644
index 000000000000..6c9e871c53d8
--- /dev/null
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -0,0 +1,992 @@
1/*
2 * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
3 * series of PDAs
4 *
5 * Copyright (c) 2004-2005 Richard Purdie
6 *
7 * Based on code written by Sharp for 2.4 kernels
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#undef DEBUG
16
17#include <linux/module.h>
18#include <linux/timer.h>
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/apm_bios.h>
22#include <linux/delay.h>
23#include <linux/interrupt.h>
24#include <linux/device.h>
25
26#include <asm/hardware.h>
27#include <asm/hardware/scoop.h>
28#include <asm/mach-types.h>
29#include <asm/irq.h>
30#include <asm/apm.h>
31
32#include <asm/arch/pm.h>
33#include <asm/arch/pxa-regs.h>
34#include <asm/arch/sharpsl.h>
35#include "sharpsl.h"
36
37/*
38 * Constants
39 */
40#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */
41#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */
42#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */
43#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */
44#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */
45#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
46#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
47#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
48#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD 10 /* 10 msec */
49#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
50#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
51#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
52
53#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */
54#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */
55#define SHARPSL_CHARGE_ON_JKVAD_HIGH 0x9b /* 6V */
56#define SHARPSL_CHARGE_ON_JKVAD_LOW 0x34 /* 2V */
57#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */
58#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */
59
60struct battery_thresh spitz_battery_levels_acin[] = {
61 { 213, 100},
62 { 212, 98},
63 { 211, 95},
64 { 210, 93},
65 { 209, 90},
66 { 208, 88},
67 { 207, 85},
68 { 206, 83},
69 { 205, 80},
70 { 204, 78},
71 { 203, 75},
72 { 202, 73},
73 { 201, 70},
74 { 200, 68},
75 { 199, 65},
76 { 198, 63},
77 { 197, 60},
78 { 196, 58},
79 { 195, 55},
80 { 194, 53},
81 { 193, 50},
82 { 192, 48},
83 { 192, 45},
84 { 191, 43},
85 { 191, 40},
86 { 190, 38},
87 { 190, 35},
88 { 189, 33},
89 { 188, 30},
90 { 187, 28},
91 { 186, 25},
92 { 185, 23},
93 { 184, 20},
94 { 183, 18},
95 { 182, 15},
96 { 181, 13},
97 { 180, 10},
98 { 179, 8},
99 { 178, 5},
100 { 0, 0},
101};
102
103struct battery_thresh spitz_battery_levels_noac[] = {
104 { 213, 100},
105 { 212, 98},
106 { 211, 95},
107 { 210, 93},
108 { 209, 90},
109 { 208, 88},
110 { 207, 85},
111 { 206, 83},
112 { 205, 80},
113 { 204, 78},
114 { 203, 75},
115 { 202, 73},
116 { 201, 70},
117 { 200, 68},
118 { 199, 65},
119 { 198, 63},
120 { 197, 60},
121 { 196, 58},
122 { 195, 55},
123 { 194, 53},
124 { 193, 50},
125 { 192, 48},
126 { 191, 45},
127 { 190, 43},
128 { 189, 40},
129 { 188, 38},
130 { 187, 35},
131 { 186, 33},
132 { 185, 30},
133 { 184, 28},
134 { 183, 25},
135 { 182, 23},
136 { 181, 20},
137 { 180, 18},
138 { 179, 15},
139 { 178, 13},
140 { 177, 10},
141 { 176, 8},
142 { 175, 5},
143 { 0, 0},
144};
145
146/* MAX1111 Commands */
147#define MAXCTRL_PD0 1u << 0
148#define MAXCTRL_PD1 1u << 1
149#define MAXCTRL_SGL 1u << 2
150#define MAXCTRL_UNI 1u << 3
151#define MAXCTRL_SEL_SH 4
152#define MAXCTRL_STR 1u << 7
153
154/* MAX1111 Channel Definitions */
155#define BATT_AD 4u
156#define BATT_THM 2u
157#define JK_VAD 6u
158
159
160/*
161 * Prototypes
162 */
163static int sharpsl_read_MainBattery(void);
164static int sharpsl_off_charge_battery(void);
165static int sharpsl_check_battery(int mode);
166static int sharpsl_ac_check(void);
167static int sharpsl_fatal_check(void);
168static int sharpsl_average_value(int ad);
169static void sharpsl_average_clear(void);
170static void sharpsl_charge_toggle(void *private_);
171static void sharpsl_battery_thread(void *private_);
172
173
174/*
175 * Variables
176 */
177struct sharpsl_pm_status sharpsl_pm;
178DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
179DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
180
181
182static int get_percentage(int voltage)
183{
184 int i = sharpsl_pm.machinfo->bat_levels - 1;
185 struct battery_thresh *thresh;
186
187 if (sharpsl_pm.charge_mode == CHRG_ON)
188 thresh=sharpsl_pm.machinfo->bat_levels_acin;
189 else
190 thresh=sharpsl_pm.machinfo->bat_levels_noac;
191
192 while (i > 0 && (voltage > thresh[i].voltage))
193 i--;
194
195 return thresh[i].percentage;
196}
197
198static int get_apm_status(int voltage)
199{
200 int low_thresh, high_thresh;
201
202 if (sharpsl_pm.charge_mode == CHRG_ON) {
203 high_thresh = sharpsl_pm.machinfo->status_high_acin;
204 low_thresh = sharpsl_pm.machinfo->status_low_acin;
205 } else {
206 high_thresh = sharpsl_pm.machinfo->status_high_noac;
207 low_thresh = sharpsl_pm.machinfo->status_low_noac;
208 }
209
210 if (voltage >= high_thresh)
211 return APM_BATTERY_STATUS_HIGH;
212 if (voltage >= low_thresh)
213 return APM_BATTERY_STATUS_LOW;
214 return APM_BATTERY_STATUS_CRITICAL;
215}
216
217void sharpsl_battery_kick(void)
218{
219 schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
220}
221EXPORT_SYMBOL(sharpsl_battery_kick);
222
223
224static void sharpsl_battery_thread(void *private_)
225{
226 int voltage, percent, apm_status, i = 0;
227
228 if (!sharpsl_pm.machinfo)
229 return;
230
231 sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE);
232
233 /* Corgi cannot confirm when battery fully charged so periodically kick! */
234 if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
235 && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL))
236 schedule_work(&toggle_charger);
237
238 while(1) {
239 voltage = sharpsl_read_MainBattery();
240 if (voltage > 0) break;
241 if (i++ > 5) {
242 voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
243 dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
244 break;
245 }
246 }
247
248 voltage = sharpsl_average_value(voltage);
249 apm_status = get_apm_status(voltage);
250 percent = get_percentage(voltage);
251
252 /* At low battery voltages, the voltage has a tendency to start
253 creeping back up so we try to avoid this here */
254 if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) {
255 sharpsl_pm.battstat.mainbat_voltage = voltage;
256 sharpsl_pm.battstat.mainbat_status = apm_status;
257 sharpsl_pm.battstat.mainbat_percent = percent;
258 }
259
260 dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage,
261 sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
262
263 /* If battery is low. limit backlight intensity to save power. */
264 if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
265 && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
266 (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
267 if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
268 corgibl_limit_intensity(1);
269 sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
270 }
271 } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
272 corgibl_limit_intensity(0);
273 sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
274 }
275
276 /* Suspend if critical battery level */
277 if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
278 && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
279 && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
280 sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
281 dev_err(sharpsl_pm.dev, "Fatal Off\n");
282 apm_queue_event(APM_CRITICAL_SUSPEND);
283 }
284
285 schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
286}
287
288static void sharpsl_charge_on(void)
289{
290 dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
291
292 sharpsl_pm.full_count = 0;
293 sharpsl_pm.charge_mode = CHRG_ON;
294 schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
295 schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
296}
297
298static void sharpsl_charge_off(void)
299{
300 dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
301
302 CHARGE_OFF();
303 CHARGE_LED_OFF();
304 sharpsl_pm.charge_mode = CHRG_OFF;
305
306 schedule_work(&sharpsl_bat);
307}
308
309static void sharpsl_charge_error(void)
310{
311 CHARGE_LED_ERR();
312 CHARGE_OFF();
313 sharpsl_pm.charge_mode = CHRG_ERROR;
314}
315
316static void sharpsl_charge_toggle(void *private_)
317{
318 dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
319
320 if (STATUS_AC_IN == 0) {
321 sharpsl_charge_off();
322 return;
323 } else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) {
324 sharpsl_charge_error();
325 return;
326 }
327
328 CHARGE_LED_ON();
329 CHARGE_OFF();
330 mdelay(SHARPSL_CHARGE_WAIT_TIME);
331 CHARGE_ON();
332
333 sharpsl_pm.charge_start_time = jiffies;
334}
335
336static void sharpsl_ac_timer(unsigned long data)
337{
338 int acin = STATUS_AC_IN;
339
340 dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
341
342 sharpsl_average_clear();
343 if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
344 sharpsl_charge_on();
345 else if (sharpsl_pm.charge_mode == CHRG_ON)
346 sharpsl_charge_off();
347
348 schedule_work(&sharpsl_bat);
349}
350
351
352static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
353{
354 /* Delay the event slightly to debounce */
355 /* Must be a smaller delay than the chrg_full_isr below */
356 mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
357
358 return IRQ_HANDLED;
359}
360
361static void sharpsl_chrg_full_timer(unsigned long data)
362{
363 dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
364
365 sharpsl_pm.full_count++;
366
367 if (STATUS_AC_IN == 0) {
368 dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
369 if (sharpsl_pm.charge_mode == CHRG_ON)
370 sharpsl_charge_off();
371 } else if (sharpsl_pm.full_count < 2) {
372 dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
373 schedule_work(&toggle_charger);
374 } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
375 dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
376 schedule_work(&toggle_charger);
377 } else {
378 sharpsl_charge_off();
379 sharpsl_pm.charge_mode = CHRG_DONE;
380 dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
381 }
382}
383
384/* Charging Finished Interrupt (Not present on Corgi) */
385/* Can trigger at the same time as an AC staus change so
386 delay until after that has been processed */
387static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
388{
389 if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
390 return IRQ_HANDLED;
391
392 /* delay until after any ac interrupt */
393 mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
394
395 return IRQ_HANDLED;
396}
397
398static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
399{
400 int is_fatal = 0;
401
402 if (STATUS_BATT_LOCKED == 0) {
403 dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
404 is_fatal = 1;
405 }
406
407 if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) {
408 dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
409 is_fatal = 1;
410 }
411
412 if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
413 sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
414 apm_queue_event(APM_CRITICAL_SUSPEND);
415 }
416
417 return IRQ_HANDLED;
418}
419
420/*
421 * Maintain an average of the last 10 readings
422 */
423#define SHARPSL_CNV_VALUE_NUM 10
424static int sharpsl_ad_index;
425
426static void sharpsl_average_clear(void)
427{
428 sharpsl_ad_index = 0;
429}
430
431static int sharpsl_average_value(int ad)
432{
433 int i, ad_val = 0;
434 static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
435
436 if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
437 sharpsl_ad_index = 0;
438 return ad;
439 }
440
441 sharpsl_ad[sharpsl_ad_index] = ad;
442 sharpsl_ad_index++;
443 if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
444 for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
445 sharpsl_ad[i] = sharpsl_ad[i+1];
446 sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
447 }
448 for (i=0; i < sharpsl_ad_index; i++)
449 ad_val += sharpsl_ad[i];
450
451 return (ad_val / sharpsl_ad_index);
452}
453
454
455/*
456 * Read MAX1111 ADC
457 */
458static int read_max1111(int channel)
459{
460 return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
461 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
462}
463
464static int sharpsl_read_MainBattery(void)
465{
466 return read_max1111(BATT_AD);
467}
468
469static int sharpsl_read_Temp(void)
470{
471 int temp;
472
473 sharpsl_pm.machinfo->measure_temp(1);
474
475 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
476 temp = read_max1111(BATT_THM);
477
478 sharpsl_pm.machinfo->measure_temp(0);
479
480 return temp;
481}
482
483static int sharpsl_read_jkvad(void)
484{
485 return read_max1111(JK_VAD);
486}
487
488/*
489 * Take an array of 5 integers, remove the maximum and minimum values
490 * and return the average.
491 */
492static int get_select_val(int *val)
493{
494 int i, j, k, temp, sum = 0;
495
496 /* Find MAX val */
497 temp = val[0];
498 j=0;
499 for (i=1; i<5; i++) {
500 if (temp < val[i]) {
501 temp = val[i];
502 j = i;
503 }
504 }
505
506 /* Find MIN val */
507 temp = val[4];
508 k=4;
509 for (i=3; i>=0; i--) {
510 if (temp > val[i]) {
511 temp = val[i];
512 k = i;
513 }
514 }
515
516 for (i=0; i<5; i++)
517 if (i != j && i != k )
518 sum += val[i];
519
520 dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
521
522 return (sum/3);
523}
524
525/* mode 0 - Check temperature and voltage
526 * 1 - Check temperature only */
527static int sharpsl_check_battery(int mode)
528{
529 int val, i, buff[5];
530
531 /* Check battery temperature */
532 for (i=0; i<5; i++) {
533 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
534 buff[i] = sharpsl_read_Temp();
535 }
536
537 val = get_select_val(buff);
538
539 dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
540 if (val > SHARPSL_CHARGE_ON_TEMP)
541 return -1;
542 if (mode == 1)
543 return 0;
544
545 /* disable charge, enable discharge */
546 CHARGE_OFF();
547 DISCHARGE_ON();
548 mdelay(SHARPSL_WAIT_DISCHARGE_ON);
549
550 if (sharpsl_pm.machinfo->discharge1)
551 sharpsl_pm.machinfo->discharge1(1);
552
553 /* Check battery voltage */
554 for (i=0; i<5; i++) {
555 buff[i] = sharpsl_read_MainBattery();
556 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
557 }
558
559 if (sharpsl_pm.machinfo->discharge1)
560 sharpsl_pm.machinfo->discharge1(0);
561
562 DISCHARGE_OFF();
563
564 val = get_select_val(buff);
565 dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
566
567 if (val < SHARPSL_CHARGE_ON_VOLT)
568 return -1;
569
570 return 0;
571}
572
573static int sharpsl_ac_check(void)
574{
575 int temp, i, buff[5];
576
577 for (i=0; i<5; i++) {
578 buff[i] = sharpsl_read_jkvad();
579 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD);
580 }
581
582 temp = get_select_val(buff);
583 dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
584
585 if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) {
586 dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
587 return -1;
588 }
589
590 return 0;
591}
592
593#ifdef CONFIG_PM
594static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
595{
596 sharpsl_pm.flags |= SHARPSL_SUSPENDED;
597 flush_scheduled_work();
598
599 if (sharpsl_pm.charge_mode == CHRG_ON)
600 sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
601 else
602 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
603
604 return 0;
605}
606
607static int sharpsl_pm_resume(struct device *dev)
608{
609 /* Clear the reset source indicators as they break the bootloader upon reboot */
610 RCSR = 0x0f;
611 sharpsl_average_clear();
612 sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
613 sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
614
615 return 0;
616}
617
618static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
619{
620 dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
621
622 dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
623 /* not charging and AC-IN! */
624
625 if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) {
626 dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
627 sharpsl_pm.charge_mode = CHRG_OFF;
628 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
629 sharpsl_off_charge_battery();
630 }
631
632 sharpsl_pm.machinfo->presuspend();
633
634 PEDR = 0xffffffff; /* clear it */
635
636 sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
637 if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
638 RTSR &= RTSR_ALE;
639 RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
640 dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
641 sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
642 } else if (alarm_enable) {
643 RTSR &= RTSR_ALE;
644 RTAR = alarm_time;
645 dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
646 } else {
647 dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
648 }
649
650 pxa_pm_enter(state);
651
652 sharpsl_pm.machinfo->postsuspend();
653
654 dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
655}
656
657static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
658{
659 if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
660 {
661 if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
662 dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
663 corgi_goto_sleep(alarm_time, alarm_enable, state);
664 return 1;
665 }
666 if(sharpsl_off_charge_battery()) {
667 dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
668 corgi_goto_sleep(alarm_time, alarm_enable, state);
669 return 1;
670 }
671 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
672 }
673
674 if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) )
675 {
676 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
677 corgi_goto_sleep(alarm_time, alarm_enable, state);
678 return 1;
679 }
680
681 return 0;
682}
683
684static int corgi_pxa_pm_enter(suspend_state_t state)
685{
686 unsigned long alarm_time = RTAR;
687 unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
688
689 dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
690
691 corgi_goto_sleep(alarm_time, alarm_status, state);
692
693 while (corgi_enter_suspend(alarm_time,alarm_status,state))
694 {}
695
696 dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
697
698 return 0;
699}
700#endif
701
702
703/*
704 * Check for fatal battery errors
705 * Fatal returns -1
706 */
707static int sharpsl_fatal_check(void)
708{
709 int buff[5], temp, i, acin;
710
711 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
712
713 /* Check AC-Adapter */
714 acin = STATUS_AC_IN;
715
716 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
717 CHARGE_OFF();
718 udelay(100);
719 DISCHARGE_ON(); /* enable discharge */
720 mdelay(SHARPSL_WAIT_DISCHARGE_ON);
721 }
722
723 if (sharpsl_pm.machinfo->discharge1)
724 sharpsl_pm.machinfo->discharge1(1);
725
726 /* Check battery : check inserting battery ? */
727 for (i=0; i<5; i++) {
728 buff[i] = sharpsl_read_MainBattery();
729 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
730 }
731
732 if (sharpsl_pm.machinfo->discharge1)
733 sharpsl_pm.machinfo->discharge1(0);
734
735 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
736 udelay(100);
737 CHARGE_ON();
738 DISCHARGE_OFF();
739 }
740
741 temp = get_select_val(buff);
742 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery());
743
744 if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
745 (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
746 return -1;
747 return 0;
748}
749
750static int sharpsl_off_charge_error(void)
751{
752 dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");
753 CHARGE_OFF();
754 CHARGE_LED_ERR();
755 sharpsl_pm.charge_mode = CHRG_ERROR;
756 return 1;
757}
758
759/*
760 * Charging Control while suspended
761 * Return 1 - go straight to sleep
762 * Return 0 - sleep or wakeup depending on other factors
763 */
764static int sharpsl_off_charge_battery(void)
765{
766 int time;
767
768 dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
769
770 if (sharpsl_pm.charge_mode == CHRG_OFF) {
771 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
772
773 /* AC Check */
774 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0))
775 return sharpsl_off_charge_error();
776
777 /* Start Charging */
778 CHARGE_LED_ON();
779 CHARGE_OFF();
780 mdelay(SHARPSL_CHARGE_WAIT_TIME);
781 CHARGE_ON();
782
783 sharpsl_pm.charge_mode = CHRG_ON;
784 sharpsl_pm.full_count = 0;
785
786 return 1;
787 } else if (sharpsl_pm.charge_mode != CHRG_ON) {
788 return 1;
789 }
790
791 if (sharpsl_pm.full_count == 0) {
792 int time;
793
794 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
795
796 if (sharpsl_check_battery(0) < 0)
797 return sharpsl_off_charge_error();
798
799 CHARGE_OFF();
800 mdelay(SHARPSL_CHARGE_WAIT_TIME);
801 CHARGE_ON();
802 sharpsl_pm.charge_mode = CHRG_ON;
803
804 mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
805
806 time = RCNR;
807 while(1) {
808 /* Check if any wakeup event had occured */
809 if (sharpsl_pm.machinfo->charger_wakeup() != 0)
810 return 0;
811 /* Check for timeout */
812 if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
813 return 1;
814 if (STATUS_CHRG_FULL) {
815 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
816 sharpsl_pm.full_count++;
817 CHARGE_OFF();
818 mdelay(SHARPSL_CHARGE_WAIT_TIME);
819 CHARGE_ON();
820 return 1;
821 }
822 }
823 }
824
825 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
826
827 mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
828
829 time = RCNR;
830 while(1) {
831 /* Check if any wakeup event had occured */
832 if (sharpsl_pm.machinfo->charger_wakeup() != 0)
833 return 0;
834 /* Check for timeout */
835 if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
836 if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
837 dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
838 sharpsl_pm.full_count = 0;
839 }
840 sharpsl_pm.full_count++;
841 return 1;
842 }
843 if (STATUS_CHRG_FULL) {
844 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
845 CHARGE_LED_OFF();
846 CHARGE_OFF();
847 sharpsl_pm.charge_mode = CHRG_DONE;
848 return 1;
849 }
850 }
851}
852
853
854static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
855{
856 return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
857}
858
859static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
860{
861 return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
862}
863
864static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
865static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
866
867extern void (*apm_get_power_status)(struct apm_power_info *);
868
869static void sharpsl_apm_get_power_status(struct apm_power_info *info)
870{
871 info->ac_line_status = sharpsl_pm.battstat.ac_status;
872
873 if (sharpsl_pm.charge_mode == CHRG_ON)
874 info->battery_status = APM_BATTERY_STATUS_CHARGING;
875 else
876 info->battery_status = sharpsl_pm.battstat.mainbat_status;
877
878 info->battery_flag = (1 << info->battery_status);
879 info->battery_life = sharpsl_pm.battstat.mainbat_percent;
880}
881
882static struct pm_ops sharpsl_pm_ops = {
883 .pm_disk_mode = PM_DISK_FIRMWARE,
884 .prepare = pxa_pm_prepare,
885 .enter = corgi_pxa_pm_enter,
886 .finish = pxa_pm_finish,
887};
888
889static int __init sharpsl_pm_probe(struct device *dev)
890{
891 if (!dev->platform_data)
892 return -EINVAL;
893
894 sharpsl_pm.dev = dev;
895 sharpsl_pm.machinfo = dev->platform_data;
896 sharpsl_pm.charge_mode = CHRG_OFF;
897 sharpsl_pm.flags = 0;
898
899 sharpsl_pm.machinfo->init();
900
901 init_timer(&sharpsl_pm.ac_timer);
902 sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
903
904 init_timer(&sharpsl_pm.chrg_full_timer);
905 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
906
907 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
908 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
909 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
910
911 /* Register interrupt handlers */
912 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) {
913 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
914 }
915 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
916
917 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) {
918 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
919 }
920 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
921
922 if (sharpsl_pm.machinfo->gpio_fatal) {
923 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) {
924 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
925 }
926 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
927 }
928
929 if (!machine_is_corgi())
930 {
931 /* Register interrupt handler. */
932 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
933 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
934 }
935 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
936 }
937
938 device_create_file(dev, &dev_attr_battery_percentage);
939 device_create_file(dev, &dev_attr_battery_voltage);
940
941 apm_get_power_status = sharpsl_apm_get_power_status;
942
943 pm_set_ops(&sharpsl_pm_ops);
944
945 mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
946
947 return 0;
948}
949
950static int sharpsl_pm_remove(struct device *dev)
951{
952 pm_set_ops(NULL);
953
954 device_remove_file(dev, &dev_attr_battery_percentage);
955 device_remove_file(dev, &dev_attr_battery_voltage);
956
957 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
958 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
959
960 if (sharpsl_pm.machinfo->gpio_fatal)
961 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
962
963 if (!machine_is_corgi())
964 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
965
966 del_timer_sync(&sharpsl_pm.chrg_full_timer);
967 del_timer_sync(&sharpsl_pm.ac_timer);
968
969 return 0;
970}
971
972static struct device_driver sharpsl_pm_driver = {
973 .name = "sharpsl-pm",
974 .bus = &platform_bus_type,
975 .probe = sharpsl_pm_probe,
976 .remove = sharpsl_pm_remove,
977 .suspend = sharpsl_pm_suspend,
978 .resume = sharpsl_pm_resume,
979};
980
981static int __devinit sharpsl_pm_init(void)
982{
983 return driver_register(&sharpsl_pm_driver);
984}
985
986static void sharpsl_pm_exit(void)
987{
988 driver_unregister(&sharpsl_pm_driver);
989}
990
991late_initcall(sharpsl_pm_init);
992module_exit(sharpsl_pm_exit);
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 4d826c021315..a68b30eff4d2 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -19,6 +19,8 @@
19 * 22nd Aug 2003 Initial version. 19 * 22nd Aug 2003 Initial version.
20 * 20th Dec 2004 Added ssp_config for changing port config without 20 * 20th Dec 2004 Added ssp_config for changing port config without
21 * closing the port. 21 * closing the port.
22 * 4th Aug 2005 Added option to disable irq handler registration and
23 * cleaned up irq and clock detection.
22 */ 24 */
23 25
24#include <linux/module.h> 26#include <linux/module.h>
@@ -37,6 +39,26 @@
37 39
38#define PXA_SSP_PORTS 3 40#define PXA_SSP_PORTS 3
39 41
42struct ssp_info_ {
43 int irq;
44 u32 clock;
45};
46
47/*
48 * SSP port clock and IRQ settings
49 */
50static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
51#if defined (CONFIG_PXA27x)
52 {IRQ_SSP, CKEN23_SSP1},
53 {IRQ_SSP2, CKEN3_SSP2},
54 {IRQ_SSP3, CKEN4_SSP3},
55#else
56 {IRQ_SSP, CKEN3_SSP},
57 {IRQ_NSSP, CKEN9_NSSP},
58 {IRQ_ASSP, CKEN10_ASSP},
59#endif
60};
61
40static DECLARE_MUTEX(sem); 62static DECLARE_MUTEX(sem);
41static int use_count[PXA_SSP_PORTS] = {0, 0, 0}; 63static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
42 64
@@ -210,9 +232,9 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee
210 * %-EBUSY if the resources are already in use 232 * %-EBUSY if the resources are already in use
211 * %0 on success 233 * %0 on success
212 */ 234 */
213int ssp_init(struct ssp_dev *dev, u32 port) 235int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
214{ 236{
215 int ret, irq; 237 int ret;
216 238
217 if (port > PXA_SSP_PORTS || port == 0) 239 if (port > PXA_SSP_PORTS || port == 0)
218 return -ENODEV; 240 return -ENODEV;
@@ -229,61 +251,20 @@ int ssp_init(struct ssp_dev *dev, u32 port)
229 up(&sem); 251 up(&sem);
230 return -EBUSY; 252 return -EBUSY;
231 } 253 }
232
233 switch (port) {
234 case 1:
235 irq = IRQ_SSP;
236 break;
237#if defined (CONFIG_PXA27x)
238 case 2:
239 irq = IRQ_SSP2;
240 break;
241 case 3:
242 irq = IRQ_SSP3;
243 break;
244#else
245 case 2:
246 irq = IRQ_NSSP;
247 break;
248 case 3:
249 irq = IRQ_ASSP;
250 break;
251#endif
252 default:
253 return -ENODEV;
254 }
255
256 dev->port = port; 254 dev->port = port;
257 255
258 ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev); 256 /* do we need to get irq */
259 if (ret) 257 if (!(init_flags & SSP_NO_IRQ)) {
260 goto out_region; 258 ret = request_irq(ssp_info[port-1].irq, ssp_interrupt,
259 0, "SSP", dev);
260 if (ret)
261 goto out_region;
262 dev->irq = ssp_info[port-1].irq;
263 } else
264 dev->irq = 0;
261 265
262 /* turn on SSP port clock */ 266 /* turn on SSP port clock */
263 switch (dev->port) { 267 pxa_set_cken(ssp_info[port-1].clock, 1);
264#if defined (CONFIG_PXA27x)
265 case 1:
266 pxa_set_cken(CKEN23_SSP1, 1);
267 break;
268 case 2:
269 pxa_set_cken(CKEN3_SSP2, 1);
270 break;
271 case 3:
272 pxa_set_cken(CKEN4_SSP3, 1);
273 break;
274#else
275 case 1:
276 pxa_set_cken(CKEN3_SSP, 1);
277 break;
278 case 2:
279 pxa_set_cken(CKEN9_NSSP, 1);
280 break;
281 case 3:
282 pxa_set_cken(CKEN10_ASSP, 1);
283 break;
284#endif
285 }
286
287 up(&sem); 268 up(&sem);
288 return 0; 269 return 0;
289 270
@@ -301,46 +282,17 @@ out_region:
301 */ 282 */
302void ssp_exit(struct ssp_dev *dev) 283void ssp_exit(struct ssp_dev *dev)
303{ 284{
304 int irq;
305
306 down(&sem); 285 down(&sem);
307 SSCR0_P(dev->port) &= ~SSCR0_SSE; 286 SSCR0_P(dev->port) &= ~SSCR0_SSE;
308 287
309 /* find irq, save power and turn off SSP port clock */ 288 if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
310 switch (dev->port) { 289 printk(KERN_WARNING "SSP: tried to close invalid port\n");
311#if defined (CONFIG_PXA27x) 290 return;
312 case 1:
313 irq = IRQ_SSP;
314 pxa_set_cken(CKEN23_SSP1, 0);
315 break;
316 case 2:
317 irq = IRQ_SSP2;
318 pxa_set_cken(CKEN3_SSP2, 0);
319 break;
320 case 3:
321 irq = IRQ_SSP3;
322 pxa_set_cken(CKEN4_SSP3, 0);
323 break;
324#else
325 case 1:
326 irq = IRQ_SSP;
327 pxa_set_cken(CKEN3_SSP, 0);
328 break;
329 case 2:
330 irq = IRQ_NSSP;
331 pxa_set_cken(CKEN9_NSSP, 0);
332 break;
333 case 3:
334 irq = IRQ_ASSP;
335 pxa_set_cken(CKEN10_ASSP, 0);
336 break;
337#endif
338 default:
339 printk(KERN_WARNING "SSP: tried to close invalid port\n");
340 return;
341 } 291 }
342 292
343 free_irq(irq, dev); 293 pxa_set_cken(ssp_info[dev->port-1].clock, 0);
294 if (dev->irq)
295 free_irq(dev->irq, dev);
344 release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c); 296 release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
345 use_count[dev->port - 1]--; 297 use_count[dev->port - 1]--;
346 up(&sem); 298 up(&sem);
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index 011a85c10627..36e76ba937fc 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -5,3 +5,5 @@
5obj-y := core.o clock.o 5obj-y := core.o clock.o
6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o 6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
7obj-$(CONFIG_SMP) += platsmp.o headsmp.o 7obj-$(CONFIG_SMP) += platsmp.o headsmp.o
8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
9obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 4ea60d8b6e36..e2c6fa23d3cd 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -550,7 +550,7 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg
550 550
551 timer_tick(regs); 551 timer_tick(regs);
552 552
553#ifdef CONFIG_SMP 553#if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS)
554 smp_send_timer(); 554 smp_send_timer();
555 update_process_times(user_mode(regs)); 555 update_process_times(user_mode(regs));
556#endif 556#endif
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
new file mode 100644
index 000000000000..09748cbcd10e
--- /dev/null
+++ b/arch/arm/mach-realview/hotplug.c
@@ -0,0 +1,138 @@
1/*
2 * linux/arch/arm/mach-realview/hotplug.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/smp.h>
14#include <linux/completion.h>
15
16extern volatile int pen_release;
17
18static DECLARE_COMPLETION(cpu_killed);
19
20static inline void cpu_enter_lowpower(void)
21{
22 unsigned int v;
23
24 asm volatile( "mcr p15, 0, %1, c7, c14, 0\n"
25 " mcr p15, 0, %1, c7, c5, 0\n"
26 " mcr p15, 0, %1, c7, c10, 4\n"
27 /*
28 * Turn off coherency
29 */
30 " mrc p15, 0, %0, c1, c0, 1\n"
31 " bic %0, %0, #0x20\n"
32 " mcr p15, 0, %0, c1, c0, 1\n"
33 " mrc p15, 0, %0, c1, c0, 0\n"
34 " bic %0, %0, #0x04\n"
35 " mcr p15, 0, %0, c1, c0, 0\n"
36 : "=&r" (v)
37 : "r" (0)
38 : "cc");
39}
40
41static inline void cpu_leave_lowpower(void)
42{
43 unsigned int v;
44
45 asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
46 " orr %0, %0, #0x04\n"
47 " mcr p15, 0, %0, c1, c0, 0\n"
48 " mrc p15, 0, %0, c1, c0, 1\n"
49 " orr %0, %0, #0x20\n"
50 " mcr p15, 0, %0, c1, c0, 1\n"
51 : "=&r" (v)
52 :
53 : "cc");
54}
55
56static inline void platform_do_lowpower(unsigned int cpu)
57{
58 /*
59 * there is no power-control hardware on this platform, so all
60 * we can do is put the core into WFI; this is safe as the calling
61 * code will have already disabled interrupts
62 */
63 for (;;) {
64 /*
65 * here's the WFI
66 */
67 asm(".word 0xe320f003\n"
68 :
69 :
70 : "memory", "cc");
71
72 if (pen_release == cpu) {
73 /*
74 * OK, proper wakeup, we're done
75 */
76 break;
77 }
78
79 /*
80 * getting here, means that we have come out of WFI without
81 * having been woken up - this shouldn't happen
82 *
83 * The trouble is, letting people know about this is not really
84 * possible, since we are currently running incoherently, and
85 * therefore cannot safely call printk() or anything else
86 */
87#ifdef DEBUG
88 printk("CPU%u: spurious wakeup call\n", cpu);
89#endif
90 }
91}
92
93int platform_cpu_kill(unsigned int cpu)
94{
95 return wait_for_completion_timeout(&cpu_killed, 5000);
96}
97
98/*
99 * platform-specific code to shutdown a CPU
100 *
101 * Called with IRQs disabled
102 */
103void platform_cpu_die(unsigned int cpu)
104{
105#ifdef DEBUG
106 unsigned int this_cpu = hard_smp_processor_id();
107
108 if (cpu != this_cpu) {
109 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
110 this_cpu, cpu);
111 BUG();
112 }
113#endif
114
115 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
116 complete(&cpu_killed);
117
118 /*
119 * we're ready for shutdown now, so do it
120 */
121 cpu_enter_lowpower();
122 platform_do_lowpower(cpu);
123
124 /*
125 * bring this CPU back into the world of cache
126 * coherency, and then restore interrupts
127 */
128 cpu_leave_lowpower();
129}
130
131int mach_cpu_disable(unsigned int cpu)
132{
133 /*
134 * we don't allow CPU 0 to be shutdown (it is still too special
135 * e.g. clock tick interrupts)
136 */
137 return cpu == 0 ? -EPERM : 0;
138}
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
new file mode 100644
index 000000000000..5e917e37d095
--- /dev/null
+++ b/arch/arm/mach-realview/localtimer.c
@@ -0,0 +1,130 @@
1/*
2 * linux/arch/arm/mach-realview/localtimer.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/smp.h>
16
17#include <asm/mach/time.h>
18#include <asm/hardware/arm_twd.h>
19#include <asm/hardware/gic.h>
20#include <asm/hardware.h>
21#include <asm/io.h>
22#include <asm/irq.h>
23
24#include "core.h"
25
26#define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \
27 ((cpu) * REALVIEW_TWD_SIZE))
28
29static unsigned long mpcore_timer_rate;
30
31/*
32 * local_timer_ack: checks for a local timer interrupt.
33 *
34 * If a local timer interrupt has occured, acknowledge and return 1.
35 * Otherwise, return 0.
36 */
37int local_timer_ack(void)
38{
39 void __iomem *base = TWD_BASE(smp_processor_id());
40
41 if (__raw_readl(base + TWD_TIMER_INTSTAT)) {
42 __raw_writel(1, base + TWD_TIMER_INTSTAT);
43 return 1;
44 }
45
46 return 0;
47}
48
49void __cpuinit local_timer_setup(unsigned int cpu)
50{
51 void __iomem *base = TWD_BASE(cpu);
52 unsigned int load, offset;
53 u64 waitjiffies;
54 unsigned int count;
55
56 /*
57 * If this is the first time round, we need to work out how fast
58 * the timer ticks
59 */
60 if (mpcore_timer_rate == 0) {
61 printk("Calibrating local timer... ");
62
63 /* Wait for a tick to start */
64 waitjiffies = get_jiffies_64() + 1;
65
66 while (get_jiffies_64() < waitjiffies)
67 udelay(10);
68
69 /* OK, now the tick has started, let's get the timer going */
70 waitjiffies += 5;
71
72 /* enable, no interrupt or reload */
73 __raw_writel(0x1, base + TWD_TIMER_CONTROL);
74
75 /* maximum value */
76 __raw_writel(0xFFFFFFFFU, base + TWD_TIMER_COUNTER);
77
78 while (get_jiffies_64() < waitjiffies)
79 udelay(10);
80
81 count = __raw_readl(base + TWD_TIMER_COUNTER);
82
83 mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
84
85 printk("%lu.%02luMHz.\n", mpcore_timer_rate / 1000000,
86 (mpcore_timer_rate / 100000) % 100);
87 }
88
89 load = mpcore_timer_rate / HZ;
90
91 __raw_writel(load, base + TWD_TIMER_LOAD);
92 __raw_writel(0x7, base + TWD_TIMER_CONTROL);
93
94 /*
95 * Now maneuver our local tick into the right part of the jiffy.
96 * Start by working out where within the tick our local timer
97 * interrupt should go.
98 */
99 offset = ((mpcore_timer_rate / HZ) / (NR_CPUS + 1)) * (cpu + 1);
100
101 /*
102 * gettimeoffset() will return a number of us since the last tick.
103 * Convert this number of us to a local timer tick count.
104 * Be careful of integer overflow whilst keeping maximum precision.
105 *
106 * with HZ=100 and 1MHz (fpga) ~ 1GHz processor:
107 * load = 1 ~ 10,000
108 * mpcore_timer_rate/10000 = 100 ~ 100,000
109 *
110 * so the multiply value will be less than 10^9 always.
111 */
112 load = (system_timer->offset() * (mpcore_timer_rate / 10000)) / 100;
113
114 /* Add on our offset to get the load value */
115 load = (load + offset) % (mpcore_timer_rate / HZ);
116
117 __raw_writel(load, base + TWD_TIMER_COUNTER);
118
119 /* Make sure our local interrupt controller has this enabled */
120 __raw_writel(1 << IRQ_LOCALTIMER,
121 __io_address(REALVIEW_GIC_DIST_BASE) + GIC_DIST_ENABLE_SET);
122}
123
124/*
125 * take a local timer down
126 */
127void __cpuexit local_timer_stop(unsigned int cpu)
128{
129 __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL);
130}
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 09b35f62247a..0c7d4ac9a7b3 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -175,6 +175,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
175 max_cpus = ncores; 175 max_cpus = ncores;
176 176
177 /* 177 /*
178 * Enable the local timer for primary CPU
179 */
180 local_timer_setup(cpu);
181
182 /*
178 * Initialise the possible/present maps. 183 * Initialise the possible/present maps.
179 * cpu_possible_map describes the set of CPUs which may be present 184 * cpu_possible_map describes the set of CPUs which may be present
180 * cpu_present_map describes the set of CPUs populated 185 * cpu_present_map describes the set of CPUs populated
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 8390b685c2b6..0f81fc0c2f7f 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -56,8 +56,16 @@
56static struct map_desc anubis_iodesc[] __initdata = { 56static struct map_desc anubis_iodesc[] __initdata = {
57 /* ISA IO areas */ 57 /* ISA IO areas */
58 58
59 { (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE }, 59 {
60 { (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE }, 60 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
61 .pfn = __phys_to_pfn(0x0),
62 .length = SZ_4M,
63 .type = MT_DEVICE
64 }, {
65 .virtual = (u32)S3C24XX_VA_ISA_WORD,
66 .pfn = __phys_to_pfn(0x0),
67 .length = SZ_4M, MT_DEVICE
68 },
61 69
62 /* we could possibly compress the next set down into a set of smaller tables 70 /* we could possibly compress the next set down into a set of smaller tables
63 * pagetables, but that would mean using an L2 section, and it still means 71 * pagetables, but that would mean using an L2 section, and it still means
@@ -66,16 +74,41 @@ static struct map_desc anubis_iodesc[] __initdata = {
66 74
67 /* CPLD control registers */ 75 /* CPLD control registers */
68 76
69 { (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE }, 77 {
70 { (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE }, 78 .virtual = (u32)ANUBIS_VA_CTRL1,
79 .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1),
80 .length = SZ_4K,
81 .type = MT_DEVICE
82 }, {
83 .virtual = (u32)ANUBIS_VA_CTRL2,
84 .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2),
85 .length = SZ_4K,
86 .type =MT_DEVICE
87 },
71 88
72 /* IDE drives */ 89 /* IDE drives */
73 90
74 { (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE }, 91 {
75 { (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE }, 92 .virtual = (u32)ANUBIS_IDEPRI,
76 93 .pfn = __phys_to_pfn(S3C2410_CS3),
77 { (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE }, 94 .length = SZ_1M,
78 { (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE }, 95 .type = MT_DEVICE
96 }, {
97 .virtual = (u32)ANUBIS_IDEPRIAUX,
98 .pfn = __phys_to_pfn(S3C2410_CS3+(1<<26)),
99 .length = SZ_1M,
100 .type = MT_DEVICE
101 }, {
102 .virtual = (u32)ANUBIS_IDESEC,
103 .pfn = __phys_to_pfn(S3C2410_CS4),
104 .length = SZ_1M,
105 .type = MT_DEVICE
106 }, {
107 .virtual = (u32)ANUBIS_IDESECAUX,
108 .pfn = __phys_to_pfn(S3C2410_CS4+(1<<26)),
109 .length = SZ_1M,
110 .type = MT_DEVICE
111 },
79}; 112};
80 113
81#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK 114#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index 24d69019a843..f8d86d1e16b6 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -56,8 +56,17 @@
56static struct map_desc rx3715_iodesc[] __initdata = { 56static struct map_desc rx3715_iodesc[] __initdata = {
57 /* dump ISA space somewhere unused */ 57 /* dump ISA space somewhere unused */
58 58
59 { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE }, 59 {
60 { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE }, 60 .virtual = (u32)S3C24XX_VA_ISA_WORD,
61 .pfn = __phys_to_pfn(S3C2410_CS3),
62 .length = SZ_1M,
63 .type = MT_DEVICE,
64 }, {
65 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
66 .pfn = __phys_to_pfn(S3C2410_CS3),
67 .length = SZ_1M,
68 .type = MT_DEVICE,
69 },
61}; 70};
62 71
63 72
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index d666c621ad06..4e31118533e6 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -58,8 +58,27 @@
58static struct map_desc smdk2440_iodesc[] __initdata = { 58static struct map_desc smdk2440_iodesc[] __initdata = {
59 /* ISA IO Space map (memory space selected by A24) */ 59 /* ISA IO Space map (memory space selected by A24) */
60 60
61 { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE }, 61 {
62 { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE }, 62 .virtual = (u32)S3C24XX_VA_ISA_WORD,
63 .pfn = __phys_to_pfn(S3C2410_CS2),
64 .length = 0x10000,
65 .type = MT_DEVICE,
66 }, {
67 .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
68 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
69 .length = SZ_4M,
70 .type = MT_DEVICE,
71 }, {
72 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
73 .pfn = __phys_to_pfn(S3C2410_CS2),
74 .length = 0x10000,
75 .type = MT_DEVICE,
76 }, {
77 .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
78 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
79 .length = SZ_4M,
80 .type = MT_DEVICE,
81 }
63}; 82};
64 83
65#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK 84#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e3c14d6b4328..e84fdde6edf8 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -102,8 +102,8 @@ config CPU_ARM922T
102# ARM925T 102# ARM925T
103config CPU_ARM925T 103config CPU_ARM925T
104 bool "Support ARM925T processor" if ARCH_OMAP1 104 bool "Support ARM925T processor" if ARCH_OMAP1
105 depends on ARCH_OMAP1510 105 depends on ARCH_OMAP15XX
106 default y if ARCH_OMAP1510 106 default y if ARCH_OMAP15XX
107 select CPU_32v4 107 select CPU_32v4
108 select CPU_ABRT_EV4T 108 select CPU_ABRT_EV4T
109 select CPU_CACHE_V4WT 109 select CPU_CACHE_V4WT
@@ -242,7 +242,7 @@ config CPU_XSCALE
242# ARMv6 242# ARMv6
243config CPU_V6 243config CPU_V6
244 bool "Support ARM V6 processor" 244 bool "Support ARM V6 processor"
245 depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB 245 depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2
246 select CPU_32v6 246 select CPU_32v6
247 select CPU_ABRT_EV6 247 select CPU_ABRT_EV6
248 select CPU_CACHE_V6 248 select CPU_CACHE_V6
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 7e144f9cad1c..9ccf1943fc94 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o 6obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o
7obj-m := 7obj-m :=
8obj-n := 8obj-n :=
9obj- := 9obj- :=
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index a020fe16428f..7ce39b986e23 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -1,15 +1,20 @@
1/* 1/*
2 * linux/arch/arm/plat-omap/clock.c 2 * linux/arch/arm/plat-omap/clock.c
3 * 3 *
4 * Copyright (C) 2004 Nokia corporation 4 * Copyright (C) 2004 - 2005 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> 5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * 6 *
7 * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
8 *
7 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
10 */ 12 */
11#include <linux/module.h> 13#include <linux/version.h>
14#include <linux/config.h>
12#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/module.h>
13#include <linux/list.h> 18#include <linux/list.h>
14#include <linux/errno.h> 19#include <linux/errno.h>
15#include <linux/err.h> 20#include <linux/err.h>
@@ -18,562 +23,20 @@
18#include <asm/io.h> 23#include <asm/io.h>
19#include <asm/semaphore.h> 24#include <asm/semaphore.h>
20#include <asm/hardware/clock.h> 25#include <asm/hardware/clock.h>
21#include <asm/arch/board.h>
22#include <asm/arch/usb.h>
23 26
24#include "clock.h" 27#include <asm/arch/clock.h>
25#include "sram.h"
26 28
27static LIST_HEAD(clocks); 29LIST_HEAD(clocks);
28static DECLARE_MUTEX(clocks_sem); 30static DECLARE_MUTEX(clocks_sem);
29static DEFINE_SPINLOCK(clockfw_lock); 31DEFINE_SPINLOCK(clockfw_lock);
30static void propagate_rate(struct clk * clk);
31/* UART clock function */
32static int set_uart_rate(struct clk * clk, unsigned long rate);
33/* External clock (MCLK & BCLK) functions */
34static int set_ext_clk_rate(struct clk * clk, unsigned long rate);
35static long round_ext_clk_rate(struct clk * clk, unsigned long rate);
36static void init_ext_clk(struct clk * clk);
37/* MPU virtual clock functions */
38static int select_table_rate(struct clk * clk, unsigned long rate);
39static long round_to_table_rate(struct clk * clk, unsigned long rate);
40void clk_setdpll(__u16, __u16);
41
42static struct mpu_rate rate_table[] = {
43 /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
44 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
45 */
46#if defined(CONFIG_OMAP_ARM_216MHZ)
47 { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
48#endif
49#if defined(CONFIG_OMAP_ARM_195MHZ)
50 { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
51#endif
52#if defined(CONFIG_OMAP_ARM_192MHZ)
53 { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
54 { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
55 { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
56 { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/8/4/4/8/8 */
57 { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
58#endif
59#if defined(CONFIG_OMAP_ARM_182MHZ)
60 { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
61#endif
62#if defined(CONFIG_OMAP_ARM_168MHZ)
63 { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
64#endif
65#if defined(CONFIG_OMAP_ARM_150MHZ)
66 { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
67#endif
68#if defined(CONFIG_OMAP_ARM_120MHZ)
69 { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
70#endif
71#if defined(CONFIG_OMAP_ARM_96MHZ)
72 { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
73#endif
74#if defined(CONFIG_OMAP_ARM_60MHZ)
75 { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
76#endif
77#if defined(CONFIG_OMAP_ARM_30MHZ)
78 { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
79#endif
80 { 0, 0, 0, 0, 0 },
81};
82
83
84static void ckctl_recalc(struct clk * clk);
85int __clk_enable(struct clk *clk);
86void __clk_disable(struct clk *clk);
87void __clk_unuse(struct clk *clk);
88int __clk_use(struct clk *clk);
89
90
91static void followparent_recalc(struct clk * clk)
92{
93 clk->rate = clk->parent->rate;
94}
95
96
97static void watchdog_recalc(struct clk * clk)
98{
99 clk->rate = clk->parent->rate / 14;
100}
101
102static void uart_recalc(struct clk * clk)
103{
104 unsigned int val = omap_readl(clk->enable_reg);
105 if (val & clk->enable_bit)
106 clk->rate = 48000000;
107 else
108 clk->rate = 12000000;
109}
110
111static struct clk ck_ref = {
112 .name = "ck_ref",
113 .rate = 12000000,
114 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
115 ALWAYS_ENABLED,
116};
117
118static struct clk ck_dpll1 = {
119 .name = "ck_dpll1",
120 .parent = &ck_ref,
121 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
122 RATE_PROPAGATES | ALWAYS_ENABLED,
123};
124
125static struct clk ck_dpll1out = {
126 .name = "ck_dpll1out",
127 .parent = &ck_dpll1,
128 .flags = CLOCK_IN_OMAP16XX,
129 .enable_reg = ARM_IDLECT2,
130 .enable_bit = EN_CKOUT_ARM,
131 .recalc = &followparent_recalc,
132};
133
134static struct clk arm_ck = {
135 .name = "arm_ck",
136 .parent = &ck_dpll1,
137 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
138 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
139 .rate_offset = CKCTL_ARMDIV_OFFSET,
140 .recalc = &ckctl_recalc,
141};
142
143static struct clk armper_ck = {
144 .name = "armper_ck",
145 .parent = &ck_dpll1,
146 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
147 RATE_CKCTL,
148 .enable_reg = ARM_IDLECT2,
149 .enable_bit = EN_PERCK,
150 .rate_offset = CKCTL_PERDIV_OFFSET,
151 .recalc = &ckctl_recalc,
152};
153
154static struct clk arm_gpio_ck = {
155 .name = "arm_gpio_ck",
156 .parent = &ck_dpll1,
157 .flags = CLOCK_IN_OMAP1510,
158 .enable_reg = ARM_IDLECT2,
159 .enable_bit = EN_GPIOCK,
160 .recalc = &followparent_recalc,
161};
162
163static struct clk armxor_ck = {
164 .name = "armxor_ck",
165 .parent = &ck_ref,
166 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
167 .enable_reg = ARM_IDLECT2,
168 .enable_bit = EN_XORPCK,
169 .recalc = &followparent_recalc,
170};
171
172static struct clk armtim_ck = {
173 .name = "armtim_ck",
174 .parent = &ck_ref,
175 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
176 .enable_reg = ARM_IDLECT2,
177 .enable_bit = EN_TIMCK,
178 .recalc = &followparent_recalc,
179};
180
181static struct clk armwdt_ck = {
182 .name = "armwdt_ck",
183 .parent = &ck_ref,
184 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
185 .enable_reg = ARM_IDLECT2,
186 .enable_bit = EN_WDTCK,
187 .recalc = &watchdog_recalc,
188};
189
190static struct clk arminth_ck16xx = {
191 .name = "arminth_ck",
192 .parent = &arm_ck,
193 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
194 .recalc = &followparent_recalc,
195 /* Note: On 16xx the frequency can be divided by 2 by programming
196 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
197 *
198 * 1510 version is in TC clocks.
199 */
200};
201
202static struct clk dsp_ck = {
203 .name = "dsp_ck",
204 .parent = &ck_dpll1,
205 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
206 RATE_CKCTL,
207 .enable_reg = ARM_CKCTL,
208 .enable_bit = EN_DSPCK,
209 .rate_offset = CKCTL_DSPDIV_OFFSET,
210 .recalc = &ckctl_recalc,
211};
212
213static struct clk dspmmu_ck = {
214 .name = "dspmmu_ck",
215 .parent = &ck_dpll1,
216 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
217 RATE_CKCTL | ALWAYS_ENABLED,
218 .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
219 .recalc = &ckctl_recalc,
220};
221
222static struct clk dspper_ck = {
223 .name = "dspper_ck",
224 .parent = &ck_dpll1,
225 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
226 RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
227 .enable_reg = DSP_IDLECT2,
228 .enable_bit = EN_PERCK,
229 .rate_offset = CKCTL_PERDIV_OFFSET,
230 .recalc = &followparent_recalc,
231 //.recalc = &ckctl_recalc,
232};
233
234static struct clk dspxor_ck = {
235 .name = "dspxor_ck",
236 .parent = &ck_ref,
237 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
238 DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
239 .enable_reg = DSP_IDLECT2,
240 .enable_bit = EN_XORPCK,
241 .recalc = &followparent_recalc,
242};
243
244static struct clk dsptim_ck = {
245 .name = "dsptim_ck",
246 .parent = &ck_ref,
247 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
248 DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
249 .enable_reg = DSP_IDLECT2,
250 .enable_bit = EN_DSPTIMCK,
251 .recalc = &followparent_recalc,
252};
253
254static struct clk tc_ck = {
255 .name = "tc_ck",
256 .parent = &ck_dpll1,
257 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
258 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
259 .rate_offset = CKCTL_TCDIV_OFFSET,
260 .recalc = &ckctl_recalc,
261};
262
263static struct clk arminth_ck1510 = {
264 .name = "arminth_ck",
265 .parent = &tc_ck,
266 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
267 .recalc = &followparent_recalc,
268 /* Note: On 1510 the frequency follows TC_CK
269 *
270 * 16xx version is in MPU clocks.
271 */
272};
273
274static struct clk tipb_ck = {
275 .name = "tibp_ck",
276 .parent = &tc_ck,
277 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
278 .recalc = &followparent_recalc,
279};
280
281static struct clk l3_ocpi_ck = {
282 .name = "l3_ocpi_ck",
283 .parent = &tc_ck,
284 .flags = CLOCK_IN_OMAP16XX,
285 .enable_reg = ARM_IDLECT3,
286 .enable_bit = EN_OCPI_CK,
287 .recalc = &followparent_recalc,
288};
289 32
290static struct clk tc1_ck = { 33static struct clk_functions *arch_clock;
291 .name = "tc1_ck",
292 .parent = &tc_ck,
293 .flags = CLOCK_IN_OMAP16XX,
294 .enable_reg = ARM_IDLECT3,
295 .enable_bit = EN_TC1_CK,
296 .recalc = &followparent_recalc,
297};
298 34
299static struct clk tc2_ck = { 35/*-------------------------------------------------------------------------
300 .name = "tc2_ck", 36 * Standard clock functions defined in asm/hardware/clock.h
301 .parent = &tc_ck, 37 *-------------------------------------------------------------------------*/
302 .flags = CLOCK_IN_OMAP16XX,
303 .enable_reg = ARM_IDLECT3,
304 .enable_bit = EN_TC2_CK,
305 .recalc = &followparent_recalc,
306};
307 38
308static struct clk dma_ck = { 39struct clk * clk_get(struct device *dev, const char *id)
309 .name = "dma_ck",
310 .parent = &tc_ck,
311 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
312 ALWAYS_ENABLED,
313 .recalc = &followparent_recalc,
314};
315
316static struct clk dma_lcdfree_ck = {
317 .name = "dma_lcdfree_ck",
318 .parent = &tc_ck,
319 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
320 .recalc = &followparent_recalc,
321};
322
323static struct clk api_ck = {
324 .name = "api_ck",
325 .parent = &tc_ck,
326 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
327 .enable_reg = ARM_IDLECT2,
328 .enable_bit = EN_APICK,
329 .recalc = &followparent_recalc,
330};
331
332static struct clk lb_ck = {
333 .name = "lb_ck",
334 .parent = &tc_ck,
335 .flags = CLOCK_IN_OMAP1510,
336 .enable_reg = ARM_IDLECT2,
337 .enable_bit = EN_LBCK,
338 .recalc = &followparent_recalc,
339};
340
341static struct clk rhea1_ck = {
342 .name = "rhea1_ck",
343 .parent = &tc_ck,
344 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
345 .recalc = &followparent_recalc,
346};
347
348static struct clk rhea2_ck = {
349 .name = "rhea2_ck",
350 .parent = &tc_ck,
351 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
352 .recalc = &followparent_recalc,
353};
354
355static struct clk lcd_ck = {
356 .name = "lcd_ck",
357 .parent = &ck_dpll1,
358 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
359 RATE_CKCTL,
360 .enable_reg = ARM_IDLECT2,
361 .enable_bit = EN_LCDCK,
362 .rate_offset = CKCTL_LCDDIV_OFFSET,
363 .recalc = &ckctl_recalc,
364};
365
366static struct clk uart1_1510 = {
367 .name = "uart1_ck",
368 /* Direct from ULPD, no parent */
369 .rate = 12000000,
370 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
371 .enable_reg = MOD_CONF_CTRL_0,
372 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
373 .set_rate = &set_uart_rate,
374 .recalc = &uart_recalc,
375};
376
377static struct clk uart1_16xx = {
378 .name = "uart1_ck",
379 /* Direct from ULPD, no parent */
380 .rate = 48000000,
381 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
382 .enable_reg = MOD_CONF_CTRL_0,
383 .enable_bit = 29,
384};
385
386static struct clk uart2_ck = {
387 .name = "uart2_ck",
388 /* Direct from ULPD, no parent */
389 .rate = 12000000,
390 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT |
391 ALWAYS_ENABLED,
392 .enable_reg = MOD_CONF_CTRL_0,
393 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
394 .set_rate = &set_uart_rate,
395 .recalc = &uart_recalc,
396};
397
398static struct clk uart3_1510 = {
399 .name = "uart3_ck",
400 /* Direct from ULPD, no parent */
401 .rate = 12000000,
402 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
403 .enable_reg = MOD_CONF_CTRL_0,
404 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
405 .set_rate = &set_uart_rate,
406 .recalc = &uart_recalc,
407};
408
409static struct clk uart3_16xx = {
410 .name = "uart3_ck",
411 /* Direct from ULPD, no parent */
412 .rate = 48000000,
413 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
414 .enable_reg = MOD_CONF_CTRL_0,
415 .enable_bit = 31,
416};
417
418static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
419 .name = "usb_clko",
420 /* Direct from ULPD, no parent */
421 .rate = 6000000,
422 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
423 RATE_FIXED | ENABLE_REG_32BIT,
424 .enable_reg = ULPD_CLOCK_CTRL,
425 .enable_bit = USB_MCLK_EN_BIT,
426};
427
428static struct clk usb_hhc_ck1510 = {
429 .name = "usb_hhc_ck",
430 /* Direct from ULPD, no parent */
431 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
432 .flags = CLOCK_IN_OMAP1510 |
433 RATE_FIXED | ENABLE_REG_32BIT,
434 .enable_reg = MOD_CONF_CTRL_0,
435 .enable_bit = USB_HOST_HHC_UHOST_EN,
436};
437
438static struct clk usb_hhc_ck16xx = {
439 .name = "usb_hhc_ck",
440 /* Direct from ULPD, no parent */
441 .rate = 48000000,
442 /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
443 .flags = CLOCK_IN_OMAP16XX |
444 RATE_FIXED | ENABLE_REG_32BIT,
445 .enable_reg = OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
446 .enable_bit = 8 /* UHOST_EN */,
447};
448
449static struct clk usb_dc_ck = {
450 .name = "usb_dc_ck",
451 /* Direct from ULPD, no parent */
452 .rate = 48000000,
453 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
454 .enable_reg = SOFT_REQ_REG,
455 .enable_bit = 4,
456};
457
458static struct clk mclk_1510 = {
459 .name = "mclk",
460 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
461 .rate = 12000000,
462 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
463};
464
465static struct clk mclk_16xx = {
466 .name = "mclk",
467 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
468 .flags = CLOCK_IN_OMAP16XX,
469 .enable_reg = COM_CLK_DIV_CTRL_SEL,
470 .enable_bit = COM_ULPD_PLL_CLK_REQ,
471 .set_rate = &set_ext_clk_rate,
472 .round_rate = &round_ext_clk_rate,
473 .init = &init_ext_clk,
474};
475
476static struct clk bclk_1510 = {
477 .name = "bclk",
478 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
479 .rate = 12000000,
480 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
481};
482
483static struct clk bclk_16xx = {
484 .name = "bclk",
485 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
486 .flags = CLOCK_IN_OMAP16XX,
487 .enable_reg = SWD_CLK_DIV_CTRL_SEL,
488 .enable_bit = SWD_ULPD_PLL_CLK_REQ,
489 .set_rate = &set_ext_clk_rate,
490 .round_rate = &round_ext_clk_rate,
491 .init = &init_ext_clk,
492};
493
494static struct clk mmc1_ck = {
495 .name = "mmc1_ck",
496 /* Functional clock is direct from ULPD, interface clock is ARMPER */
497 .parent = &armper_ck,
498 .rate = 48000000,
499 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
500 RATE_FIXED | ENABLE_REG_32BIT,
501 .enable_reg = MOD_CONF_CTRL_0,
502 .enable_bit = 23,
503};
504
505static struct clk mmc2_ck = {
506 .name = "mmc2_ck",
507 /* Functional clock is direct from ULPD, interface clock is ARMPER */
508 .parent = &armper_ck,
509 .rate = 48000000,
510 .flags = CLOCK_IN_OMAP16XX |
511 RATE_FIXED | ENABLE_REG_32BIT,
512 .enable_reg = MOD_CONF_CTRL_0,
513 .enable_bit = 20,
514};
515
516static struct clk virtual_ck_mpu = {
517 .name = "mpu",
518 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
519 VIRTUAL_CLOCK | ALWAYS_ENABLED,
520 .parent = &arm_ck, /* Is smarter alias for */
521 .recalc = &followparent_recalc,
522 .set_rate = &select_table_rate,
523 .round_rate = &round_to_table_rate,
524};
525
526
527static struct clk * onchip_clks[] = {
528 /* non-ULPD clocks */
529 &ck_ref,
530 &ck_dpll1,
531 /* CK_GEN1 clocks */
532 &ck_dpll1out,
533 &arm_ck,
534 &armper_ck,
535 &arm_gpio_ck,
536 &armxor_ck,
537 &armtim_ck,
538 &armwdt_ck,
539 &arminth_ck1510, &arminth_ck16xx,
540 /* CK_GEN2 clocks */
541 &dsp_ck,
542 &dspmmu_ck,
543 &dspper_ck,
544 &dspxor_ck,
545 &dsptim_ck,
546 /* CK_GEN3 clocks */
547 &tc_ck,
548 &tipb_ck,
549 &l3_ocpi_ck,
550 &tc1_ck,
551 &tc2_ck,
552 &dma_ck,
553 &dma_lcdfree_ck,
554 &api_ck,
555 &lb_ck,
556 &rhea1_ck,
557 &rhea2_ck,
558 &lcd_ck,
559 /* ULPD clocks */
560 &uart1_1510,
561 &uart1_16xx,
562 &uart2_ck,
563 &uart3_1510,
564 &uart3_16xx,
565 &usb_clko,
566 &usb_hhc_ck1510, &usb_hhc_ck16xx,
567 &usb_dc_ck,
568 &mclk_1510, &mclk_16xx,
569 &bclk_1510, &bclk_16xx,
570 &mmc1_ck,
571 &mmc2_ck,
572 /* Virtual clocks */
573 &virtual_ck_mpu,
574};
575
576struct clk *clk_get(struct device *dev, const char *id)
577{ 40{
578 struct clk *p, *clk = ERR_PTR(-ENOENT); 41 struct clk *p, *clk = ERR_PTR(-ENOENT);
579 42
@@ -590,534 +53,200 @@ struct clk *clk_get(struct device *dev, const char *id)
590} 53}
591EXPORT_SYMBOL(clk_get); 54EXPORT_SYMBOL(clk_get);
592 55
593
594void clk_put(struct clk *clk)
595{
596 if (clk && !IS_ERR(clk))
597 module_put(clk->owner);
598}
599EXPORT_SYMBOL(clk_put);
600
601
602int __clk_enable(struct clk *clk)
603{
604 __u16 regval16;
605 __u32 regval32;
606
607 if (clk->flags & ALWAYS_ENABLED)
608 return 0;
609
610 if (unlikely(clk->enable_reg == 0)) {
611 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
612 clk->name);
613 return 0;
614 }
615
616 if (clk->flags & DSP_DOMAIN_CLOCK) {
617 __clk_use(&api_ck);
618 }
619
620 if (clk->flags & ENABLE_REG_32BIT) {
621 if (clk->flags & VIRTUAL_IO_ADDRESS) {
622 regval32 = __raw_readl(clk->enable_reg);
623 regval32 |= (1 << clk->enable_bit);
624 __raw_writel(regval32, clk->enable_reg);
625 } else {
626 regval32 = omap_readl(clk->enable_reg);
627 regval32 |= (1 << clk->enable_bit);
628 omap_writel(regval32, clk->enable_reg);
629 }
630 } else {
631 if (clk->flags & VIRTUAL_IO_ADDRESS) {
632 regval16 = __raw_readw(clk->enable_reg);
633 regval16 |= (1 << clk->enable_bit);
634 __raw_writew(regval16, clk->enable_reg);
635 } else {
636 regval16 = omap_readw(clk->enable_reg);
637 regval16 |= (1 << clk->enable_bit);
638 omap_writew(regval16, clk->enable_reg);
639 }
640 }
641
642 if (clk->flags & DSP_DOMAIN_CLOCK) {
643 __clk_unuse(&api_ck);
644 }
645
646 return 0;
647}
648
649
650void __clk_disable(struct clk *clk)
651{
652 __u16 regval16;
653 __u32 regval32;
654
655 if (clk->enable_reg == 0)
656 return;
657
658 if (clk->flags & DSP_DOMAIN_CLOCK) {
659 __clk_use(&api_ck);
660 }
661
662 if (clk->flags & ENABLE_REG_32BIT) {
663 if (clk->flags & VIRTUAL_IO_ADDRESS) {
664 regval32 = __raw_readl(clk->enable_reg);
665 regval32 &= ~(1 << clk->enable_bit);
666 __raw_writel(regval32, clk->enable_reg);
667 } else {
668 regval32 = omap_readl(clk->enable_reg);
669 regval32 &= ~(1 << clk->enable_bit);
670 omap_writel(regval32, clk->enable_reg);
671 }
672 } else {
673 if (clk->flags & VIRTUAL_IO_ADDRESS) {
674 regval16 = __raw_readw(clk->enable_reg);
675 regval16 &= ~(1 << clk->enable_bit);
676 __raw_writew(regval16, clk->enable_reg);
677 } else {
678 regval16 = omap_readw(clk->enable_reg);
679 regval16 &= ~(1 << clk->enable_bit);
680 omap_writew(regval16, clk->enable_reg);
681 }
682 }
683
684 if (clk->flags & DSP_DOMAIN_CLOCK) {
685 __clk_unuse(&api_ck);
686 }
687}
688
689
690void __clk_unuse(struct clk *clk)
691{
692 if (clk->usecount > 0 && !(--clk->usecount)) {
693 __clk_disable(clk);
694 if (likely(clk->parent))
695 __clk_unuse(clk->parent);
696 }
697}
698
699
700int __clk_use(struct clk *clk)
701{
702 int ret = 0;
703 if (clk->usecount++ == 0) {
704 if (likely(clk->parent))
705 ret = __clk_use(clk->parent);
706
707 if (unlikely(ret != 0)) {
708 clk->usecount--;
709 return ret;
710 }
711
712 ret = __clk_enable(clk);
713
714 if (unlikely(ret != 0) && clk->parent) {
715 __clk_unuse(clk->parent);
716 clk->usecount--;
717 }
718 }
719
720 return ret;
721}
722
723
724int clk_enable(struct clk *clk) 56int clk_enable(struct clk *clk)
725{ 57{
726 unsigned long flags; 58 unsigned long flags;
727 int ret; 59 int ret = 0;
728 60
729 spin_lock_irqsave(&clockfw_lock, flags); 61 spin_lock_irqsave(&clockfw_lock, flags);
730 ret = __clk_enable(clk); 62 if (clk->enable)
63 ret = clk->enable(clk);
64 else if (arch_clock->clk_enable)
65 ret = arch_clock->clk_enable(clk);
66 else
67 printk(KERN_ERR "Could not enable clock %s\n", clk->name);
731 spin_unlock_irqrestore(&clockfw_lock, flags); 68 spin_unlock_irqrestore(&clockfw_lock, flags);
69
732 return ret; 70 return ret;
733} 71}
734EXPORT_SYMBOL(clk_enable); 72EXPORT_SYMBOL(clk_enable);
735 73
736
737void clk_disable(struct clk *clk) 74void clk_disable(struct clk *clk)
738{ 75{
739 unsigned long flags; 76 unsigned long flags;
740 77
741 spin_lock_irqsave(&clockfw_lock, flags); 78 spin_lock_irqsave(&clockfw_lock, flags);
742 __clk_disable(clk); 79 if (clk->disable)
80 clk->disable(clk);
81 else if (arch_clock->clk_disable)
82 arch_clock->clk_disable(clk);
83 else
84 printk(KERN_ERR "Could not disable clock %s\n", clk->name);
743 spin_unlock_irqrestore(&clockfw_lock, flags); 85 spin_unlock_irqrestore(&clockfw_lock, flags);
744} 86}
745EXPORT_SYMBOL(clk_disable); 87EXPORT_SYMBOL(clk_disable);
746 88
747
748int clk_use(struct clk *clk) 89int clk_use(struct clk *clk)
749{ 90{
750 unsigned long flags; 91 unsigned long flags;
751 int ret = 0; 92 int ret = 0;
752 93
753 spin_lock_irqsave(&clockfw_lock, flags); 94 spin_lock_irqsave(&clockfw_lock, flags);
754 ret = __clk_use(clk); 95 if (arch_clock->clk_use)
96 ret = arch_clock->clk_use(clk);
755 spin_unlock_irqrestore(&clockfw_lock, flags); 97 spin_unlock_irqrestore(&clockfw_lock, flags);
98
756 return ret; 99 return ret;
757} 100}
758EXPORT_SYMBOL(clk_use); 101EXPORT_SYMBOL(clk_use);
759 102
760
761void clk_unuse(struct clk *clk) 103void clk_unuse(struct clk *clk)
762{ 104{
763 unsigned long flags; 105 unsigned long flags;
764 106
765 spin_lock_irqsave(&clockfw_lock, flags); 107 spin_lock_irqsave(&clockfw_lock, flags);
766 __clk_unuse(clk); 108 if (arch_clock->clk_unuse)
109 arch_clock->clk_unuse(clk);
767 spin_unlock_irqrestore(&clockfw_lock, flags); 110 spin_unlock_irqrestore(&clockfw_lock, flags);
768} 111}
769EXPORT_SYMBOL(clk_unuse); 112EXPORT_SYMBOL(clk_unuse);
770 113
771
772int clk_get_usecount(struct clk *clk) 114int clk_get_usecount(struct clk *clk)
773{ 115{
774 return clk->usecount; 116 unsigned long flags;
775} 117 int ret = 0;
776EXPORT_SYMBOL(clk_get_usecount);
777
778
779unsigned long clk_get_rate(struct clk *clk)
780{
781 return clk->rate;
782}
783EXPORT_SYMBOL(clk_get_rate);
784
785
786static __u16 verify_ckctl_value(__u16 newval)
787{
788 /* This function checks for following limitations set
789 * by the hardware (all conditions must be true):
790 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
791 * ARM_CK >= TC_CK
792 * DSP_CK >= TC_CK
793 * DSPMMU_CK >= TC_CK
794 *
795 * In addition following rules are enforced:
796 * LCD_CK <= TC_CK
797 * ARMPER_CK <= TC_CK
798 *
799 * However, maximum frequencies are not checked for!
800 */
801 __u8 per_exp;
802 __u8 lcd_exp;
803 __u8 arm_exp;
804 __u8 dsp_exp;
805 __u8 tc_exp;
806 __u8 dspmmu_exp;
807
808 per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
809 lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
810 arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
811 dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
812 tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
813 dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
814
815 if (dspmmu_exp < dsp_exp)
816 dspmmu_exp = dsp_exp;
817 if (dspmmu_exp > dsp_exp+1)
818 dspmmu_exp = dsp_exp+1;
819 if (tc_exp < arm_exp)
820 tc_exp = arm_exp;
821 if (tc_exp < dspmmu_exp)
822 tc_exp = dspmmu_exp;
823 if (tc_exp > lcd_exp)
824 lcd_exp = tc_exp;
825 if (tc_exp > per_exp)
826 per_exp = tc_exp;
827 118
828 newval &= 0xf000; 119 spin_lock_irqsave(&clockfw_lock, flags);
829 newval |= per_exp << CKCTL_PERDIV_OFFSET; 120 ret = clk->usecount;
830 newval |= lcd_exp << CKCTL_LCDDIV_OFFSET; 121 spin_unlock_irqrestore(&clockfw_lock, flags);
831 newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
832 newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
833 newval |= tc_exp << CKCTL_TCDIV_OFFSET;
834 newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
835 122
836 return newval; 123 return ret;
837} 124}
125EXPORT_SYMBOL(clk_get_usecount);
838 126
839 127unsigned long clk_get_rate(struct clk *clk)
840static int calc_dsor_exp(struct clk *clk, unsigned long rate)
841{ 128{
842 /* Note: If target frequency is too low, this function will return 4, 129 unsigned long flags;
843 * which is invalid value. Caller must check for this value and act 130 unsigned long ret = 0;
844 * accordingly.
845 *
846 * Note: This function does not check for following limitations set
847 * by the hardware (all conditions must be true):
848 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
849 * ARM_CK >= TC_CK
850 * DSP_CK >= TC_CK
851 * DSPMMU_CK >= TC_CK
852 */
853 unsigned long realrate;
854 struct clk * parent;
855 unsigned dsor_exp;
856
857 if (unlikely(!(clk->flags & RATE_CKCTL)))
858 return -EINVAL;
859
860 parent = clk->parent;
861 if (unlikely(parent == 0))
862 return -EIO;
863
864 realrate = parent->rate;
865 for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
866 if (realrate <= rate)
867 break;
868 131
869 realrate /= 2; 132 spin_lock_irqsave(&clockfw_lock, flags);
870 } 133 ret = clk->rate;
134 spin_unlock_irqrestore(&clockfw_lock, flags);
871 135
872 return dsor_exp; 136 return ret;
873} 137}
138EXPORT_SYMBOL(clk_get_rate);
874 139
875 140void clk_put(struct clk *clk)
876static void ckctl_recalc(struct clk * clk)
877{ 141{
878 int dsor; 142 if (clk && !IS_ERR(clk))
879 143 module_put(clk->owner);
880 /* Calculate divisor encoded as 2-bit exponent */
881 if (clk->flags & DSP_DOMAIN_CLOCK) {
882 /* The clock control bits are in DSP domain,
883 * so api_ck is needed for access.
884 * Note that DSP_CKCTL virt addr = phys addr, so
885 * we must use __raw_readw() instead of omap_readw().
886 */
887 __clk_use(&api_ck);
888 dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
889 __clk_unuse(&api_ck);
890 } else {
891 dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
892 }
893 if (unlikely(clk->rate == clk->parent->rate / dsor))
894 return; /* No change, quick exit */
895 clk->rate = clk->parent->rate / dsor;
896
897 if (unlikely(clk->flags & RATE_PROPAGATES))
898 propagate_rate(clk);
899} 144}
145EXPORT_SYMBOL(clk_put);
900 146
147/*-------------------------------------------------------------------------
148 * Optional clock functions defined in asm/hardware/clock.h
149 *-------------------------------------------------------------------------*/
901 150
902long clk_round_rate(struct clk *clk, unsigned long rate) 151long clk_round_rate(struct clk *clk, unsigned long rate)
903{ 152{
904 int dsor_exp; 153 unsigned long flags;
905 154 long ret = 0;
906 if (clk->flags & RATE_FIXED)
907 return clk->rate;
908
909 if (clk->flags & RATE_CKCTL) {
910 dsor_exp = calc_dsor_exp(clk, rate);
911 if (dsor_exp < 0)
912 return dsor_exp;
913 if (dsor_exp > 3)
914 dsor_exp = 3;
915 return clk->parent->rate / (1 << dsor_exp);
916 }
917 155
918 if(clk->round_rate != 0) 156 spin_lock_irqsave(&clockfw_lock, flags);
919 return clk->round_rate(clk, rate); 157 if (arch_clock->clk_round_rate)
158 ret = arch_clock->clk_round_rate(clk, rate);
159 spin_unlock_irqrestore(&clockfw_lock, flags);
920 160
921 return clk->rate; 161 return ret;
922} 162}
923EXPORT_SYMBOL(clk_round_rate); 163EXPORT_SYMBOL(clk_round_rate);
924 164
925 165int clk_set_rate(struct clk *clk, unsigned long rate)
926static void propagate_rate(struct clk * clk)
927{
928 struct clk ** clkp;
929
930 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
931 if (likely((*clkp)->parent != clk)) continue;
932 if (likely((*clkp)->recalc))
933 (*clkp)->recalc(*clkp);
934 }
935}
936
937
938static int select_table_rate(struct clk * clk, unsigned long rate)
939{ 166{
940 /* Find the highest supported frequency <= rate and switch to it */ 167 unsigned long flags;
941 struct mpu_rate * ptr; 168 int ret = 0;
942
943 if (clk != &virtual_ck_mpu)
944 return -EINVAL;
945
946 for (ptr = rate_table; ptr->rate; ptr++) {
947 if (ptr->xtal != ck_ref.rate)
948 continue;
949
950 /* DPLL1 cannot be reprogrammed without risking system crash */
951 if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
952 continue;
953
954 /* Can check only after xtal frequency check */
955 if (ptr->rate <= rate)
956 break;
957 }
958
959 if (!ptr->rate)
960 return -EINVAL;
961 169
962 /* 170 spin_lock_irqsave(&clockfw_lock, flags);
963 * In most cases we should not need to reprogram DPLL. 171 if (arch_clock->clk_set_rate)
964 * Reprogramming the DPLL is tricky, it must be done from SRAM. 172 ret = arch_clock->clk_set_rate(clk, rate);
965 */ 173 spin_unlock_irqrestore(&clockfw_lock, flags);
966 omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
967 174
968 ck_dpll1.rate = ptr->pll_rate; 175 return ret;
969 propagate_rate(&ck_dpll1);
970 return 0;
971} 176}
177EXPORT_SYMBOL(clk_set_rate);
972 178
973 179int clk_set_parent(struct clk *clk, struct clk *parent)
974static long round_to_table_rate(struct clk * clk, unsigned long rate)
975{ 180{
976 /* Find the highest supported frequency <= rate */ 181 unsigned long flags;
977 struct mpu_rate * ptr; 182 int ret = 0;
978 long highest_rate;
979
980 if (clk != &virtual_ck_mpu)
981 return -EINVAL;
982
983 highest_rate = -EINVAL;
984
985 for (ptr = rate_table; ptr->rate; ptr++) {
986 if (ptr->xtal != ck_ref.rate)
987 continue;
988
989 highest_rate = ptr->rate;
990 183
991 /* Can check only after xtal frequency check */ 184 spin_lock_irqsave(&clockfw_lock, flags);
992 if (ptr->rate <= rate) 185 if (arch_clock->clk_set_parent)
993 break; 186 ret = arch_clock->clk_set_parent(clk, parent);
994 } 187 spin_unlock_irqrestore(&clockfw_lock, flags);
995 188
996 return highest_rate; 189 return ret;
997} 190}
191EXPORT_SYMBOL(clk_set_parent);
998 192
999 193struct clk *clk_get_parent(struct clk *clk)
1000int clk_set_rate(struct clk *clk, unsigned long rate)
1001{ 194{
1002 int ret = -EINVAL; 195 unsigned long flags;
1003 int dsor_exp; 196 struct clk * ret = NULL;
1004 __u16 regval;
1005 unsigned long flags;
1006
1007 if (clk->flags & RATE_CKCTL) {
1008 dsor_exp = calc_dsor_exp(clk, rate);
1009 if (dsor_exp > 3)
1010 dsor_exp = -EINVAL;
1011 if (dsor_exp < 0)
1012 return dsor_exp;
1013
1014 spin_lock_irqsave(&clockfw_lock, flags);
1015 regval = omap_readw(ARM_CKCTL);
1016 regval &= ~(3 << clk->rate_offset);
1017 regval |= dsor_exp << clk->rate_offset;
1018 regval = verify_ckctl_value(regval);
1019 omap_writew(regval, ARM_CKCTL);
1020 clk->rate = clk->parent->rate / (1 << dsor_exp);
1021 spin_unlock_irqrestore(&clockfw_lock, flags);
1022 ret = 0;
1023 } else if(clk->set_rate != 0) {
1024 spin_lock_irqsave(&clockfw_lock, flags);
1025 ret = clk->set_rate(clk, rate);
1026 spin_unlock_irqrestore(&clockfw_lock, flags);
1027 }
1028 197
1029 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) 198 spin_lock_irqsave(&clockfw_lock, flags);
1030 propagate_rate(clk); 199 if (arch_clock->clk_get_parent)
200 ret = arch_clock->clk_get_parent(clk);
201 spin_unlock_irqrestore(&clockfw_lock, flags);
1031 202
1032 return ret; 203 return ret;
1033} 204}
1034EXPORT_SYMBOL(clk_set_rate); 205EXPORT_SYMBOL(clk_get_parent);
1035 206
207/*-------------------------------------------------------------------------
208 * OMAP specific clock functions shared between omap1 and omap2
209 *-------------------------------------------------------------------------*/
1036 210
1037static unsigned calc_ext_dsor(unsigned long rate) 211unsigned int __initdata mpurate;
1038{
1039 unsigned dsor;
1040 212
1041 /* MCLK and BCLK divisor selection is not linear: 213/*
1042 * freq = 96MHz / dsor 214 * By default we use the rate set by the bootloader.
1043 * 215 * You can override this with mpurate= cmdline option.
1044 * RATIO_SEL range: dsor <-> RATIO_SEL 216 */
1045 * 0..6: (RATIO_SEL+2) <-> (dsor-2) 217static int __init omap_clk_setup(char *str)
1046 * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
1047 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
1048 * can not be used.
1049 */
1050 for (dsor = 2; dsor < 96; ++dsor) {
1051 if ((dsor & 1) && dsor > 8)
1052 continue;
1053 if (rate >= 96000000 / dsor)
1054 break;
1055 }
1056 return dsor;
1057}
1058
1059/* Only needed on 1510 */
1060static int set_uart_rate(struct clk * clk, unsigned long rate)
1061{
1062 unsigned int val;
1063
1064 val = omap_readl(clk->enable_reg);
1065 if (rate == 12000000)
1066 val &= ~(1 << clk->enable_bit);
1067 else if (rate == 48000000)
1068 val |= (1 << clk->enable_bit);
1069 else
1070 return -EINVAL;
1071 omap_writel(val, clk->enable_reg);
1072 clk->rate = rate;
1073
1074 return 0;
1075}
1076
1077static int set_ext_clk_rate(struct clk * clk, unsigned long rate)
1078{ 218{
1079 unsigned dsor; 219 get_option(&str, &mpurate);
1080 __u16 ratio_bits;
1081 220
1082 dsor = calc_ext_dsor(rate); 221 if (!mpurate)
1083 clk->rate = 96000000 / dsor; 222 return 1;
1084 if (dsor > 8)
1085 ratio_bits = ((dsor - 8) / 2 + 6) << 2;
1086 else
1087 ratio_bits = (dsor - 2) << 2;
1088 223
1089 ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd; 224 if (mpurate < 1000)
1090 omap_writew(ratio_bits, clk->enable_reg); 225 mpurate *= 1000000;
1091 226
1092 return 0; 227 return 1;
1093} 228}
229__setup("mpurate=", omap_clk_setup);
1094 230
1095 231/* Used for clocks that always have same value as the parent clock */
1096static long round_ext_clk_rate(struct clk * clk, unsigned long rate) 232void followparent_recalc(struct clk *clk)
1097{ 233{
1098 return 96000000 / calc_ext_dsor(rate); 234 clk->rate = clk->parent->rate;
1099} 235}
1100 236
1101 237/* Propagate rate to children */
1102static void init_ext_clk(struct clk * clk) 238void propagate_rate(struct clk * tclk)
1103{ 239{
1104 unsigned dsor; 240 struct clk *clkp;
1105 __u16 ratio_bits;
1106 241
1107 /* Determine current rate and ensure clock is based on 96MHz APLL */ 242 list_for_each_entry(clkp, &clocks, node) {
1108 ratio_bits = omap_readw(clk->enable_reg) & ~1; 243 if (likely(clkp->parent != tclk))
1109 omap_writew(ratio_bits, clk->enable_reg); 244 continue;
1110 245 if (likely((u32)clkp->recalc))
1111 ratio_bits = (ratio_bits & 0xfc) >> 2; 246 clkp->recalc(clkp);
1112 if (ratio_bits > 6) 247 }
1113 dsor = (ratio_bits - 6) * 2 + 8;
1114 else
1115 dsor = ratio_bits + 2;
1116
1117 clk-> rate = 96000000 / dsor;
1118} 248}
1119 249
1120
1121int clk_register(struct clk *clk) 250int clk_register(struct clk *clk)
1122{ 251{
1123 down(&clocks_sem); 252 down(&clocks_sem);
@@ -1125,6 +254,7 @@ int clk_register(struct clk *clk)
1125 if (clk->init) 254 if (clk->init)
1126 clk->init(clk); 255 clk->init(clk);
1127 up(&clocks_sem); 256 up(&clocks_sem);
257
1128 return 0; 258 return 0;
1129} 259}
1130EXPORT_SYMBOL(clk_register); 260EXPORT_SYMBOL(clk_register);
@@ -1137,203 +267,38 @@ void clk_unregister(struct clk *clk)
1137} 267}
1138EXPORT_SYMBOL(clk_unregister); 268EXPORT_SYMBOL(clk_unregister);
1139 269
1140#ifdef CONFIG_OMAP_RESET_CLOCKS 270void clk_deny_idle(struct clk *clk)
1141/*
1142 * Resets some clocks that may be left on from bootloader,
1143 * but leaves serial clocks on. See also omap_late_clk_reset().
1144 */
1145static inline void omap_early_clk_reset(void)
1146{ 271{
1147 //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); 272 unsigned long flags;
273
274 spin_lock_irqsave(&clockfw_lock, flags);
275 if (arch_clock->clk_deny_idle)
276 arch_clock->clk_deny_idle(clk);
277 spin_unlock_irqrestore(&clockfw_lock, flags);
1148} 278}
1149#else 279EXPORT_SYMBOL(clk_deny_idle);
1150#define omap_early_clk_reset() {}
1151#endif
1152 280
1153int __init clk_init(void) 281void clk_allow_idle(struct clk *clk)
1154{ 282{
1155 struct clk ** clkp; 283 unsigned long flags;
1156 const struct omap_clock_config *info;
1157 int crystal_type = 0; /* Default 12 MHz */
1158
1159 omap_early_clk_reset();
1160
1161 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
1162 if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
1163 clk_register(*clkp);
1164 continue;
1165 }
1166
1167 if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
1168 clk_register(*clkp);
1169 continue;
1170 }
1171
1172 if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
1173 clk_register(*clkp);
1174 continue;
1175 }
1176 }
1177
1178 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
1179 if (info != NULL) {
1180 if (!cpu_is_omap1510())
1181 crystal_type = info->system_clock_type;
1182 }
1183
1184#if defined(CONFIG_ARCH_OMAP730)
1185 ck_ref.rate = 13000000;
1186#elif defined(CONFIG_ARCH_OMAP16XX)
1187 if (crystal_type == 2)
1188 ck_ref.rate = 19200000;
1189#endif
1190
1191 printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
1192 omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
1193 omap_readw(ARM_CKCTL));
1194
1195 /* We want to be in syncronous scalable mode */
1196 omap_writew(0x1000, ARM_SYSST);
1197
1198#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
1199 /* Use values set by bootloader. Determine PLL rate and recalculate
1200 * dependent clocks as if kernel had changed PLL or divisors.
1201 */
1202 {
1203 unsigned pll_ctl_val = omap_readw(DPLL_CTL);
1204
1205 ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
1206 if (pll_ctl_val & 0x10) {
1207 /* PLL enabled, apply multiplier and divisor */
1208 if (pll_ctl_val & 0xf80)
1209 ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
1210 ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
1211 } else {
1212 /* PLL disabled, apply bypass divisor */
1213 switch (pll_ctl_val & 0xc) {
1214 case 0:
1215 break;
1216 case 0x4:
1217 ck_dpll1.rate /= 2;
1218 break;
1219 default:
1220 ck_dpll1.rate /= 4;
1221 break;
1222 }
1223 }
1224 }
1225 propagate_rate(&ck_dpll1);
1226#else
1227 /* Find the highest supported frequency and enable it */
1228 if (select_table_rate(&virtual_ck_mpu, ~0)) {
1229 printk(KERN_ERR "System frequencies not set. Check your config.\n");
1230 /* Guess sane values (60MHz) */
1231 omap_writew(0x2290, DPLL_CTL);
1232 omap_writew(0x1005, ARM_CKCTL);
1233 ck_dpll1.rate = 60000000;
1234 propagate_rate(&ck_dpll1);
1235 }
1236#endif
1237 /* Cache rates for clocks connected to ck_ref (not dpll1) */
1238 propagate_rate(&ck_ref);
1239 printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
1240 "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
1241 ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
1242 ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
1243 arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
1244
1245#ifdef CONFIG_MACH_OMAP_PERSEUS2
1246 /* Select slicer output as OMAP input clock */
1247 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
1248#endif
1249
1250 /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
1251 omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
1252
1253 /* Put DSP/MPUI into reset until needed */
1254 omap_writew(0, ARM_RSTCT1);
1255 omap_writew(1, ARM_RSTCT2);
1256 omap_writew(0x400, ARM_IDLECT1);
1257
1258 /*
1259 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
1260 * of the ARM_IDLECT2 register must be set to zero. The power-on
1261 * default value of this bit is one.
1262 */
1263 omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
1264
1265 /*
1266 * Only enable those clocks we will need, let the drivers
1267 * enable other clocks as necessary
1268 */
1269 clk_use(&armper_ck);
1270 clk_use(&armxor_ck);
1271 clk_use(&armtim_ck);
1272
1273 if (cpu_is_omap1510())
1274 clk_enable(&arm_gpio_ck);
1275 284
1276 return 0; 285 spin_lock_irqsave(&clockfw_lock, flags);
286 if (arch_clock->clk_allow_idle)
287 arch_clock->clk_allow_idle(clk);
288 spin_unlock_irqrestore(&clockfw_lock, flags);
1277} 289}
290EXPORT_SYMBOL(clk_allow_idle);
1278 291
292/*-------------------------------------------------------------------------*/
1279 293
1280#ifdef CONFIG_OMAP_RESET_CLOCKS 294int __init clk_init(struct clk_functions * custom_clocks)
1281
1282static int __init omap_late_clk_reset(void)
1283{ 295{
1284 /* Turn off all unused clocks */ 296 if (!custom_clocks) {
1285 struct clk *p; 297 printk(KERN_ERR "No custom clock functions registered\n");
1286 __u32 regval32; 298 BUG();
1287
1288 /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
1289 regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
1290 omap_writew(regval32, SOFT_REQ_REG);
1291 omap_writew(0, SOFT_REQ_REG2);
1292
1293 list_for_each_entry(p, &clocks, node) {
1294 if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
1295 p->enable_reg == 0)
1296 continue;
1297
1298 /* Assume no DSP clocks have been activated by bootloader */
1299 if (p->flags & DSP_DOMAIN_CLOCK)
1300 continue;
1301
1302 /* Is the clock already disabled? */
1303 if (p->flags & ENABLE_REG_32BIT) {
1304 if (p->flags & VIRTUAL_IO_ADDRESS)
1305 regval32 = __raw_readl(p->enable_reg);
1306 else
1307 regval32 = omap_readl(p->enable_reg);
1308 } else {
1309 if (p->flags & VIRTUAL_IO_ADDRESS)
1310 regval32 = __raw_readw(p->enable_reg);
1311 else
1312 regval32 = omap_readw(p->enable_reg);
1313 }
1314
1315 if ((regval32 & (1 << p->enable_bit)) == 0)
1316 continue;
1317
1318 /* FIXME: This clock seems to be necessary but no-one
1319 * has asked for its activation. */
1320 if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
1321 || p == &ck_dpll1out // FIX: SoSSI, SSR
1322 || p == &arm_gpio_ck // FIX: GPIO code for 1510
1323 ) {
1324 printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
1325 p->name);
1326 continue;
1327 }
1328
1329 printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
1330 __clk_disable(p);
1331 printk(" done\n");
1332 } 299 }
1333 300
301 arch_clock = custom_clocks;
302
1334 return 0; 303 return 0;
1335} 304}
1336
1337late_initcall(omap_late_clk_reset);
1338
1339#endif
diff --git a/arch/arm/plat-omap/clock.h b/arch/arm/plat-omap/clock.h
deleted file mode 100644
index a89e1e8c2519..000000000000
--- a/arch/arm/plat-omap/clock.h
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * linux/arch/arm/plat-omap/clock.h
3 *
4 * Copyright (C) 2004 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ARCH_ARM_OMAP_CLOCK_H
14#define __ARCH_ARM_OMAP_CLOCK_H
15
16struct module;
17
18struct clk {
19 struct list_head node;
20 struct module *owner;
21 const char *name;
22 struct clk *parent;
23 unsigned long rate;
24 __s8 usecount;
25 __u16 flags;
26 __u32 enable_reg;
27 __u8 enable_bit;
28 __u8 rate_offset;
29 void (*recalc)(struct clk *);
30 int (*set_rate)(struct clk *, unsigned long);
31 long (*round_rate)(struct clk *, unsigned long);
32 void (*init)(struct clk *);
33};
34
35
36struct mpu_rate {
37 unsigned long rate;
38 unsigned long xtal;
39 unsigned long pll_rate;
40 __u16 ckctl_val;
41 __u16 dpllctl_val;
42};
43
44
45/* Clock flags */
46#define RATE_CKCTL 1
47#define RATE_FIXED 2
48#define RATE_PROPAGATES 4
49#define VIRTUAL_CLOCK 8
50#define ALWAYS_ENABLED 16
51#define ENABLE_REG_32BIT 32
52#define CLOCK_IN_OMAP16XX 64
53#define CLOCK_IN_OMAP1510 128
54#define CLOCK_IN_OMAP730 256
55#define DSP_DOMAIN_CLOCK 512
56#define VIRTUAL_IO_ADDRESS 1024
57
58/* ARM_CKCTL bit shifts */
59#define CKCTL_PERDIV_OFFSET 0
60#define CKCTL_LCDDIV_OFFSET 2
61#define CKCTL_ARMDIV_OFFSET 4
62#define CKCTL_DSPDIV_OFFSET 6
63#define CKCTL_TCDIV_OFFSET 8
64#define CKCTL_DSPMMUDIV_OFFSET 10
65/*#define ARM_TIMXO 12*/
66#define EN_DSPCK 13
67/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
68/* DSP_CKCTL bit shifts */
69#define CKCTL_DSPPERDIV_OFFSET 0
70
71/* ARM_IDLECT1 bit shifts */
72/*#define IDLWDT_ARM 0*/
73/*#define IDLXORP_ARM 1*/
74/*#define IDLPER_ARM 2*/
75/*#define IDLLCD_ARM 3*/
76/*#define IDLLB_ARM 4*/
77/*#define IDLHSAB_ARM 5*/
78/*#define IDLIF_ARM 6*/
79/*#define IDLDPLL_ARM 7*/
80/*#define IDLAPI_ARM 8*/
81/*#define IDLTIM_ARM 9*/
82/*#define SETARM_IDLE 11*/
83
84/* ARM_IDLECT2 bit shifts */
85#define EN_WDTCK 0
86#define EN_XORPCK 1
87#define EN_PERCK 2
88#define EN_LCDCK 3
89#define EN_LBCK 4 /* Not on 1610/1710 */
90/*#define EN_HSABCK 5*/
91#define EN_APICK 6
92#define EN_TIMCK 7
93#define DMACK_REQ 8
94#define EN_GPIOCK 9 /* Not on 1610/1710 */
95/*#define EN_LBFREECK 10*/
96#define EN_CKOUT_ARM 11
97
98/* ARM_IDLECT3 bit shifts */
99#define EN_OCPI_CK 0
100#define EN_TC1_CK 2
101#define EN_TC2_CK 4
102
103/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
104#define EN_DSPTIMCK 5
105
106/* Various register defines for clock controls scattered around OMAP chip */
107#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
108#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
109#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
110#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
111#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
112#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
113#define SOFT_REQ_REG 0xfffe0834
114#define SOFT_REQ_REG2 0xfffe0880
115
116int clk_register(struct clk *clk);
117void clk_unregister(struct clk *clk);
118int clk_init(void);
119
120#endif
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 02bcc6c1cd1b..ccdb452630cf 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -31,7 +31,7 @@
31#include <asm/arch/mux.h> 31#include <asm/arch/mux.h>
32#include <asm/arch/fpga.h> 32#include <asm/arch/fpga.h>
33 33
34#include "clock.h" 34#include <asm/arch/clock.h>
35 35
36#define NO_LENGTH_CHECK 0xffffffff 36#define NO_LENGTH_CHECK 0xffffffff
37 37
@@ -117,19 +117,43 @@ EXPORT_SYMBOL(omap_get_var_config);
117 117
118static int __init omap_add_serial_console(void) 118static int __init omap_add_serial_console(void)
119{ 119{
120 const struct omap_serial_console_config *info; 120 const struct omap_serial_console_config *con_info;
121 121 const struct omap_uart_config *uart_info;
122 info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, 122 static char speed[11], *opt = NULL;
123 struct omap_serial_console_config); 123 int line, i, uart_idx;
124 if (info != NULL && info->console_uart) { 124
125 static char speed[11], *opt = NULL; 125 uart_info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
126 con_info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
127 struct omap_serial_console_config);
128 if (uart_info == NULL || con_info == NULL)
129 return 0;
130
131 if (con_info->console_uart == 0)
132 return 0;
133
134 if (con_info->console_speed) {
135 snprintf(speed, sizeof(speed), "%u", con_info->console_speed);
136 opt = speed;
137 }
126 138
127 if (info->console_speed) { 139 uart_idx = con_info->console_uart - 1;
128 snprintf(speed, sizeof(speed), "%u", info->console_speed); 140 if (uart_idx >= OMAP_MAX_NR_PORTS) {
129 opt = speed; 141 printk(KERN_INFO "Console: external UART#%d. "
130 } 142 "Not adding it as console this time.\n",
131 return add_preferred_console("ttyS", info->console_uart - 1, opt); 143 uart_idx + 1);
144 return 0;
145 }
146 if (!(uart_info->enabled_uarts & (1 << uart_idx))) {
147 printk(KERN_ERR "Console: Selected UART#%d is "
148 "not enabled for this platform\n",
149 uart_idx + 1);
150 return -1;
151 }
152 line = 0;
153 for (i = 0; i < uart_idx; i++) {
154 if (uart_info->enabled_uarts & (1 << i))
155 line++;
132 } 156 }
133 return 0; 157 return add_preferred_console("ttyS", line, opt);
134} 158}
135console_initcall(omap_add_serial_console); 159console_initcall(omap_add_serial_console);
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
new file mode 100644
index 000000000000..9dcce904b608
--- /dev/null
+++ b/arch/arm/plat-omap/devices.c
@@ -0,0 +1,381 @@
1/*
2 * linux/arch/arm/plat-omap/devices.c
3 *
4 * Common platform device setup/initialization for OMAP1 and OMAP2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17
18#include <asm/hardware.h>
19#include <asm/io.h>
20#include <asm/mach-types.h>
21#include <asm/mach/map.h>
22
23#include <asm/arch/tc.h>
24#include <asm/arch/board.h>
25#include <asm/arch/mux.h>
26#include <asm/arch/gpio.h>
27
28
29void omap_nop_release(struct device *dev)
30{
31 /* Nothing */
32}
33
34/*-------------------------------------------------------------------------*/
35
36#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
37
38#define OMAP1_I2C_BASE 0xfffb3800
39#define OMAP2_I2C_BASE1 0x48070000
40#define OMAP_I2C_SIZE 0x3f
41#define OMAP1_I2C_INT INT_I2C
42#define OMAP2_I2C_INT1 56
43
44static struct resource i2c_resources1[] = {
45 {
46 .start = 0,
47 .end = 0,
48 .flags = IORESOURCE_MEM,
49 },
50 {
51 .start = 0,
52 .flags = IORESOURCE_IRQ,
53 },
54};
55
56/* DMA not used; works around erratum writing to non-empty i2c fifo */
57
58static struct platform_device omap_i2c_device1 = {
59 .name = "i2c_omap",
60 .id = 1,
61 .dev = {
62 .release = omap_nop_release,
63 },
64 .num_resources = ARRAY_SIZE(i2c_resources1),
65 .resource = i2c_resources1,
66};
67
68/* See also arch/arm/mach-omap2/devices.c for second I2C on 24xx */
69static void omap_init_i2c(void)
70{
71 if (cpu_is_omap24xx()) {
72 i2c_resources1[0].start = OMAP2_I2C_BASE1;
73 i2c_resources1[0].end = OMAP2_I2C_BASE1 + OMAP_I2C_SIZE;
74 i2c_resources1[1].start = OMAP2_I2C_INT1;
75 } else {
76 i2c_resources1[0].start = OMAP1_I2C_BASE;
77 i2c_resources1[0].end = OMAP1_I2C_BASE + OMAP_I2C_SIZE;
78 i2c_resources1[1].start = OMAP1_I2C_INT;
79 }
80
81 /* FIXME define and use a boot tag, in case of boards that
82 * either don't wire up I2C, or chips that mux it differently...
83 * it can include clocking and address info, maybe more.
84 */
85 if (cpu_is_omap24xx()) {
86 omap_cfg_reg(M19_24XX_I2C1_SCL);
87 omap_cfg_reg(L15_24XX_I2C1_SDA);
88 } else {
89 omap_cfg_reg(I2C_SCL);
90 omap_cfg_reg(I2C_SDA);
91 }
92
93 (void) platform_device_register(&omap_i2c_device1);
94}
95
96#else
97static inline void omap_init_i2c(void) {}
98#endif
99
100/*-------------------------------------------------------------------------*/
101
102#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
103
104#ifdef CONFIG_ARCH_OMAP24XX
105#define OMAP_MMC1_BASE 0x4809c000
106#define OMAP_MMC1_INT 83
107#else
108#define OMAP_MMC1_BASE 0xfffb7800
109#define OMAP_MMC1_INT INT_MMC
110#endif
111#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
112
113static struct omap_mmc_conf mmc1_conf;
114
115static u64 mmc1_dmamask = 0xffffffff;
116
117static struct resource mmc1_resources[] = {
118 {
119 .start = IO_ADDRESS(OMAP_MMC1_BASE),
120 .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
121 .flags = IORESOURCE_MEM,
122 },
123 {
124 .start = OMAP_MMC1_INT,
125 .flags = IORESOURCE_IRQ,
126 },
127};
128
129static struct platform_device mmc_omap_device1 = {
130 .name = "mmci-omap",
131 .id = 1,
132 .dev = {
133 .release = omap_nop_release,
134 .dma_mask = &mmc1_dmamask,
135 .platform_data = &mmc1_conf,
136 },
137 .num_resources = ARRAY_SIZE(mmc1_resources),
138 .resource = mmc1_resources,
139};
140
141#ifdef CONFIG_ARCH_OMAP16XX
142
143static struct omap_mmc_conf mmc2_conf;
144
145static u64 mmc2_dmamask = 0xffffffff;
146
147static struct resource mmc2_resources[] = {
148 {
149 .start = IO_ADDRESS(OMAP_MMC2_BASE),
150 .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
151 .flags = IORESOURCE_MEM,
152 },
153 {
154 .start = INT_1610_MMC2,
155 .flags = IORESOURCE_IRQ,
156 },
157};
158
159static struct platform_device mmc_omap_device2 = {
160 .name = "mmci-omap",
161 .id = 2,
162 .dev = {
163 .release = omap_nop_release,
164 .dma_mask = &mmc2_dmamask,
165 .platform_data = &mmc2_conf,
166 },
167 .num_resources = ARRAY_SIZE(mmc2_resources),
168 .resource = mmc2_resources,
169};
170#endif
171
172static void __init omap_init_mmc(void)
173{
174 const struct omap_mmc_config *mmc_conf;
175 const struct omap_mmc_conf *mmc;
176
177 /* NOTE: assumes MMC was never (wrongly) enabled */
178 mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
179 if (!mmc_conf)
180 return;
181
182 /* block 1 is always available and has just one pinout option */
183 mmc = &mmc_conf->mmc[0];
184 if (mmc->enabled) {
185 if (!cpu_is_omap24xx()) {
186 omap_cfg_reg(MMC_CMD);
187 omap_cfg_reg(MMC_CLK);
188 omap_cfg_reg(MMC_DAT0);
189 if (cpu_is_omap1710()) {
190 omap_cfg_reg(M15_1710_MMC_CLKI);
191 omap_cfg_reg(P19_1710_MMC_CMDDIR);
192 omap_cfg_reg(P20_1710_MMC_DATDIR0);
193 }
194 }
195 if (mmc->wire4) {
196 if (!cpu_is_omap24xx()) {
197 omap_cfg_reg(MMC_DAT1);
198 /* NOTE: DAT2 can be on W10 (here) or M15 */
199 if (!mmc->nomux)
200 omap_cfg_reg(MMC_DAT2);
201 omap_cfg_reg(MMC_DAT3);
202 }
203 }
204 mmc1_conf = *mmc;
205 (void) platform_device_register(&mmc_omap_device1);
206 }
207
208#ifdef CONFIG_ARCH_OMAP16XX
209 /* block 2 is on newer chips, and has many pinout options */
210 mmc = &mmc_conf->mmc[1];
211 if (mmc->enabled) {
212 if (!mmc->nomux) {
213 omap_cfg_reg(Y8_1610_MMC2_CMD);
214 omap_cfg_reg(Y10_1610_MMC2_CLK);
215 omap_cfg_reg(R18_1610_MMC2_CLKIN);
216 omap_cfg_reg(W8_1610_MMC2_DAT0);
217 if (mmc->wire4) {
218 omap_cfg_reg(V8_1610_MMC2_DAT1);
219 omap_cfg_reg(W15_1610_MMC2_DAT2);
220 omap_cfg_reg(R10_1610_MMC2_DAT3);
221 }
222
223 /* These are needed for the level shifter */
224 omap_cfg_reg(V9_1610_MMC2_CMDDIR);
225 omap_cfg_reg(V5_1610_MMC2_DATDIR0);
226 omap_cfg_reg(W19_1610_MMC2_DATDIR1);
227 }
228
229 /* Feedback clock must be set on OMAP-1710 MMC2 */
230 if (cpu_is_omap1710())
231 omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
232 MOD_CONF_CTRL_1);
233 mmc2_conf = *mmc;
234 (void) platform_device_register(&mmc_omap_device2);
235 }
236#endif
237 return;
238}
239#else
240static inline void omap_init_mmc(void) {}
241#endif
242
243#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
244
245#ifdef CONFIG_ARCH_OMAP24XX
246#define OMAP_WDT_BASE 0x48022000
247#else
248#define OMAP_WDT_BASE 0xfffeb000
249#endif
250
251static struct resource wdt_resources[] = {
252 {
253 .start = OMAP_WDT_BASE,
254 .end = OMAP_WDT_BASE + 0x4f,
255 .flags = IORESOURCE_MEM,
256 },
257};
258
259static struct platform_device omap_wdt_device = {
260 .name = "omap_wdt",
261 .id = -1,
262 .dev = {
263 .release = omap_nop_release,
264 },
265 .num_resources = ARRAY_SIZE(wdt_resources),
266 .resource = wdt_resources,
267};
268
269static void omap_init_wdt(void)
270{
271 (void) platform_device_register(&omap_wdt_device);
272}
273#else
274static inline void omap_init_wdt(void) {}
275#endif
276
277/*-------------------------------------------------------------------------*/
278
279#if defined(CONFIG_OMAP_RNG) || defined(CONFIG_OMAP_RNG_MODULE)
280
281#ifdef CONFIG_ARCH_OMAP24XX
282#define OMAP_RNG_BASE 0x480A0000
283#else
284#define OMAP_RNG_BASE 0xfffe5000
285#endif
286
287static struct resource rng_resources[] = {
288 {
289 .start = OMAP_RNG_BASE,
290 .end = OMAP_RNG_BASE + 0x4f,
291 .flags = IORESOURCE_MEM,
292 },
293};
294
295static struct platform_device omap_rng_device = {
296 .name = "omap_rng",
297 .id = -1,
298 .dev = {
299 .release = omap_nop_release,
300 },
301 .num_resources = ARRAY_SIZE(rng_resources),
302 .resource = rng_resources,
303};
304
305static void omap_init_rng(void)
306{
307 (void) platform_device_register(&omap_rng_device);
308}
309#else
310static inline void omap_init_rng(void) {}
311#endif
312
313#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
314
315static struct omap_lcd_config omap_fb_conf;
316
317static u64 omap_fb_dma_mask = ~(u32)0;
318
319static struct platform_device omap_fb_device = {
320 .name = "omapfb",
321 .id = -1,
322 .dev = {
323 .release = omap_nop_release,
324 .dma_mask = &omap_fb_dma_mask,
325 .coherent_dma_mask = ~(u32)0,
326 .platform_data = &omap_fb_conf,
327 },
328 .num_resources = 0,
329};
330
331static inline void omap_init_fb(void)
332{
333 const struct omap_lcd_config *conf;
334
335 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
336 if (conf != NULL)
337 omap_fb_conf = *conf;
338 platform_device_register(&omap_fb_device);
339}
340
341#else
342
343static inline void omap_init_fb(void) {}
344
345#endif
346
347/*
348 * This gets called after board-specific INIT_MACHINE, and initializes most
349 * on-chip peripherals accessible on this board (except for few like USB):
350 *
351 * (a) Does any "standard config" pin muxing needed. Board-specific
352 * code will have muxed GPIO pins and done "nonstandard" setup;
353 * that code could live in the boot loader.
354 * (b) Populating board-specific platform_data with the data drivers
355 * rely on to handle wiring variations.
356 * (c) Creating platform devices as meaningful on this board and
357 * with this kernel configuration.
358 *
359 * Claiming GPIOs, and setting their direction and initial values, is the
360 * responsibility of the device drivers. So is responding to probe().
361 *
362 * Board-specific knowlege like creating devices or pin setup is to be
363 * kept out of drivers as much as possible. In particular, pin setup
364 * may be handled by the boot loader, and drivers should expect it will
365 * normally have been done by the time they're probed.
366 */
367static int __init omap_init_devices(void)
368{
369 /* please keep these calls, and their implementations above,
370 * in alphabetical order so they're easier to sort through.
371 */
372 omap_init_fb();
373 omap_init_i2c();
374 omap_init_mmc();
375 omap_init_wdt();
376 omap_init_rng();
377
378 return 0;
379}
380arch_initcall(omap_init_devices);
381
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index da7b65145658..f5cc21ad0956 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -6,6 +6,8 @@
6 * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> 6 * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
7 * Graphics DMA and LCD DMA graphics tranformations 7 * Graphics DMA and LCD DMA graphics tranformations
8 * by Imre Deak <imre.deak@nokia.com> 8 * by Imre Deak <imre.deak@nokia.com>
9 * OMAP2 support Copyright (C) 2004-2005 Texas Instruments, Inc.
10 * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
9 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. 11 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
10 * 12 *
11 * Support functions for the OMAP internal DMA channels. 13 * Support functions for the OMAP internal DMA channels.
@@ -31,8 +33,15 @@
31 33
32#include <asm/arch/tc.h> 34#include <asm/arch/tc.h>
33 35
34#define OMAP_DMA_ACTIVE 0x01 36#define DEBUG_PRINTS
37#undef DEBUG_PRINTS
38#ifdef DEBUG_PRINTS
39#define debug_printk(x) printk x
40#else
41#define debug_printk(x)
42#endif
35 43
44#define OMAP_DMA_ACTIVE 0x01
36#define OMAP_DMA_CCR_EN (1 << 7) 45#define OMAP_DMA_CCR_EN (1 << 7)
37 46
38#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) 47#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
@@ -55,7 +64,7 @@ static int dma_chan_count;
55static spinlock_t dma_chan_lock; 64static spinlock_t dma_chan_lock;
56static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; 65static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
57 66
58const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { 67const static u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
59 INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, 68 INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
60 INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, 69 INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
61 INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, 70 INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
@@ -63,6 +72,20 @@ const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
63 INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD 72 INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
64}; 73};
65 74
75#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
76 __FUNCTION__);
77
78#ifdef CONFIG_ARCH_OMAP15XX
79/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
80int omap_dma_in_1510_mode(void)
81{
82 return enable_1510_mode;
83}
84#else
85#define omap_dma_in_1510_mode() 0
86#endif
87
88#ifdef CONFIG_ARCH_OMAP1
66static inline int get_gdma_dev(int req) 89static inline int get_gdma_dev(int req)
67{ 90{
68 u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4; 91 u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
@@ -82,6 +105,9 @@ static inline void set_gdma_dev(int req, int dev)
82 l |= (dev - 1) << shift; 105 l |= (dev - 1) << shift;
83 omap_writel(l, reg); 106 omap_writel(l, reg);
84} 107}
108#else
109#define set_gdma_dev(req, dev) do {} while (0)
110#endif
85 111
86static void clear_lch_regs(int lch) 112static void clear_lch_regs(int lch)
87{ 113{
@@ -121,38 +147,62 @@ void omap_set_dma_priority(int dst_port, int priority)
121} 147}
122 148
123void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, 149void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
124 int frame_count, int sync_mode) 150 int frame_count, int sync_mode,
151 int dma_trigger, int src_or_dst_synch)
125{ 152{
126 u16 w; 153 OMAP_DMA_CSDP_REG(lch) &= ~0x03;
154 OMAP_DMA_CSDP_REG(lch) |= data_type;
127 155
128 w = omap_readw(OMAP_DMA_CSDP(lch)); 156 if (cpu_class_is_omap1()) {
129 w &= ~0x03; 157 OMAP_DMA_CCR_REG(lch) &= ~(1 << 5);
130 w |= data_type; 158 if (sync_mode == OMAP_DMA_SYNC_FRAME)
131 omap_writew(w, OMAP_DMA_CSDP(lch)); 159 OMAP_DMA_CCR_REG(lch) |= 1 << 5;
160
161 OMAP1_DMA_CCR2_REG(lch) &= ~(1 << 2);
162 if (sync_mode == OMAP_DMA_SYNC_BLOCK)
163 OMAP1_DMA_CCR2_REG(lch) |= 1 << 2;
164 }
165
166 if (cpu_is_omap24xx() && dma_trigger) {
167 u32 val = OMAP_DMA_CCR_REG(lch);
168
169 if (dma_trigger > 63)
170 val |= 1 << 20;
171 if (dma_trigger > 31)
172 val |= 1 << 19;
132 173
133 w = omap_readw(OMAP_DMA_CCR(lch)); 174 val |= (dma_trigger & 0x1f);
134 w &= ~(1 << 5);
135 if (sync_mode == OMAP_DMA_SYNC_FRAME)
136 w |= 1 << 5;
137 omap_writew(w, OMAP_DMA_CCR(lch));
138 175
139 w = omap_readw(OMAP_DMA_CCR2(lch)); 176 if (sync_mode & OMAP_DMA_SYNC_FRAME)
140 w &= ~(1 << 2); 177 val |= 1 << 5;
141 if (sync_mode == OMAP_DMA_SYNC_BLOCK)
142 w |= 1 << 2;
143 omap_writew(w, OMAP_DMA_CCR2(lch));
144 178
145 omap_writew(elem_count, OMAP_DMA_CEN(lch)); 179 if (sync_mode & OMAP_DMA_SYNC_BLOCK)
146 omap_writew(frame_count, OMAP_DMA_CFN(lch)); 180 val |= 1 << 18;
147 181
182 if (src_or_dst_synch)
183 val |= 1 << 24; /* source synch */
184 else
185 val &= ~(1 << 24); /* dest synch */
186
187 OMAP_DMA_CCR_REG(lch) = val;
188 }
189
190 OMAP_DMA_CEN_REG(lch) = elem_count;
191 OMAP_DMA_CFN_REG(lch) = frame_count;
148} 192}
193
149void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) 194void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
150{ 195{
151 u16 w; 196 u16 w;
152 197
153 BUG_ON(omap_dma_in_1510_mode()); 198 BUG_ON(omap_dma_in_1510_mode());
154 199
155 w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03; 200 if (cpu_is_omap24xx()) {
201 REVISIT_24XX();
202 return;
203 }
204
205 w = OMAP1_DMA_CCR2_REG(lch) & ~0x03;
156 switch (mode) { 206 switch (mode) {
157 case OMAP_DMA_CONSTANT_FILL: 207 case OMAP_DMA_CONSTANT_FILL:
158 w |= 0x01; 208 w |= 0x01;
@@ -165,63 +215,84 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
165 default: 215 default:
166 BUG(); 216 BUG();
167 } 217 }
168 omap_writew(w, OMAP_DMA_CCR2(lch)); 218 OMAP1_DMA_CCR2_REG(lch) = w;
169 219
170 w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f; 220 w = OMAP1_DMA_LCH_CTRL_REG(lch) & ~0x0f;
171 /* Default is channel type 2D */ 221 /* Default is channel type 2D */
172 if (mode) { 222 if (mode) {
173 omap_writew((u16)color, OMAP_DMA_COLOR_L(lch)); 223 OMAP1_DMA_COLOR_L_REG(lch) = (u16)color;
174 omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch)); 224 OMAP1_DMA_COLOR_U_REG(lch) = (u16)(color >> 16);
175 w |= 1; /* Channel type G */ 225 w |= 1; /* Channel type G */
176 } 226 }
177 omap_writew(w, OMAP_DMA_LCH_CTRL(lch)); 227 OMAP1_DMA_LCH_CTRL_REG(lch) = w;
178} 228}
179 229
180 230/* Note that src_port is only for omap1 */
181void omap_set_dma_src_params(int lch, int src_port, int src_amode, 231void omap_set_dma_src_params(int lch, int src_port, int src_amode,
182 unsigned long src_start) 232 unsigned long src_start,
233 int src_ei, int src_fi)
183{ 234{
184 u16 w; 235 if (cpu_class_is_omap1()) {
236 OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 2);
237 OMAP_DMA_CSDP_REG(lch) |= src_port << 2;
238 }
239
240 OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 12);
241 OMAP_DMA_CCR_REG(lch) |= src_amode << 12;
242
243 if (cpu_class_is_omap1()) {
244 OMAP1_DMA_CSSA_U_REG(lch) = src_start >> 16;
245 OMAP1_DMA_CSSA_L_REG(lch) = src_start;
246 }
185 247
186 w = omap_readw(OMAP_DMA_CSDP(lch)); 248 if (cpu_is_omap24xx())
187 w &= ~(0x1f << 2); 249 OMAP2_DMA_CSSA_REG(lch) = src_start;
188 w |= src_port << 2;
189 omap_writew(w, OMAP_DMA_CSDP(lch));
190 250
191 w = omap_readw(OMAP_DMA_CCR(lch)); 251 OMAP_DMA_CSEI_REG(lch) = src_ei;
192 w &= ~(0x03 << 12); 252 OMAP_DMA_CSFI_REG(lch) = src_fi;
193 w |= src_amode << 12; 253}
194 omap_writew(w, OMAP_DMA_CCR(lch));
195 254
196 omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch)); 255void omap_set_dma_params(int lch, struct omap_dma_channel_params * params)
197 omap_writew(src_start, OMAP_DMA_CSSA_L(lch)); 256{
257 omap_set_dma_transfer_params(lch, params->data_type,
258 params->elem_count, params->frame_count,
259 params->sync_mode, params->trigger,
260 params->src_or_dst_synch);
261 omap_set_dma_src_params(lch, params->src_port,
262 params->src_amode, params->src_start,
263 params->src_ei, params->src_fi);
264
265 omap_set_dma_dest_params(lch, params->dst_port,
266 params->dst_amode, params->dst_start,
267 params->dst_ei, params->dst_fi);
198} 268}
199 269
200void omap_set_dma_src_index(int lch, int eidx, int fidx) 270void omap_set_dma_src_index(int lch, int eidx, int fidx)
201{ 271{
202 omap_writew(eidx, OMAP_DMA_CSEI(lch)); 272 if (cpu_is_omap24xx()) {
203 omap_writew(fidx, OMAP_DMA_CSFI(lch)); 273 REVISIT_24XX();
274 return;
275 }
276 OMAP_DMA_CSEI_REG(lch) = eidx;
277 OMAP_DMA_CSFI_REG(lch) = fidx;
204} 278}
205 279
206void omap_set_dma_src_data_pack(int lch, int enable) 280void omap_set_dma_src_data_pack(int lch, int enable)
207{ 281{
208 u16 w; 282 OMAP_DMA_CSDP_REG(lch) &= ~(1 << 6);
209 283 if (enable)
210 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6); 284 OMAP_DMA_CSDP_REG(lch) |= (1 << 6);
211 w |= enable ? (1 << 6) : 0;
212 omap_writew(w, OMAP_DMA_CSDP(lch));
213} 285}
214 286
215void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) 287void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
216{ 288{
217 u16 w; 289 OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7);
218 290
219 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
220 switch (burst_mode) { 291 switch (burst_mode) {
221 case OMAP_DMA_DATA_BURST_DIS: 292 case OMAP_DMA_DATA_BURST_DIS:
222 break; 293 break;
223 case OMAP_DMA_DATA_BURST_4: 294 case OMAP_DMA_DATA_BURST_4:
224 w |= (0x01 << 7); 295 OMAP_DMA_CSDP_REG(lch) |= (0x02 << 7);
225 break; 296 break;
226 case OMAP_DMA_DATA_BURST_8: 297 case OMAP_DMA_DATA_BURST_8:
227 /* not supported by current hardware 298 /* not supported by current hardware
@@ -231,110 +302,283 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
231 default: 302 default:
232 BUG(); 303 BUG();
233 } 304 }
234 omap_writew(w, OMAP_DMA_CSDP(lch));
235} 305}
236 306
307/* Note that dest_port is only for OMAP1 */
237void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, 308void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
238 unsigned long dest_start) 309 unsigned long dest_start,
310 int dst_ei, int dst_fi)
239{ 311{
240 u16 w; 312 if (cpu_class_is_omap1()) {
313 OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 9);
314 OMAP_DMA_CSDP_REG(lch) |= dest_port << 9;
315 }
241 316
242 w = omap_readw(OMAP_DMA_CSDP(lch)); 317 OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 14);
243 w &= ~(0x1f << 9); 318 OMAP_DMA_CCR_REG(lch) |= dest_amode << 14;
244 w |= dest_port << 9; 319
245 omap_writew(w, OMAP_DMA_CSDP(lch)); 320 if (cpu_class_is_omap1()) {
321 OMAP1_DMA_CDSA_U_REG(lch) = dest_start >> 16;
322 OMAP1_DMA_CDSA_L_REG(lch) = dest_start;
323 }
246 324
247 w = omap_readw(OMAP_DMA_CCR(lch)); 325 if (cpu_is_omap24xx())
248 w &= ~(0x03 << 14); 326 OMAP2_DMA_CDSA_REG(lch) = dest_start;
249 w |= dest_amode << 14;
250 omap_writew(w, OMAP_DMA_CCR(lch));
251 327
252 omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch)); 328 OMAP_DMA_CDEI_REG(lch) = dst_ei;
253 omap_writew(dest_start, OMAP_DMA_CDSA_L(lch)); 329 OMAP_DMA_CDFI_REG(lch) = dst_fi;
254} 330}
255 331
256void omap_set_dma_dest_index(int lch, int eidx, int fidx) 332void omap_set_dma_dest_index(int lch, int eidx, int fidx)
257{ 333{
258 omap_writew(eidx, OMAP_DMA_CDEI(lch)); 334 if (cpu_is_omap24xx()) {
259 omap_writew(fidx, OMAP_DMA_CDFI(lch)); 335 REVISIT_24XX();
336 return;
337 }
338 OMAP_DMA_CDEI_REG(lch) = eidx;
339 OMAP_DMA_CDFI_REG(lch) = fidx;
260} 340}
261 341
262void omap_set_dma_dest_data_pack(int lch, int enable) 342void omap_set_dma_dest_data_pack(int lch, int enable)
263{ 343{
264 u16 w; 344 OMAP_DMA_CSDP_REG(lch) &= ~(1 << 13);
265 345 if (enable)
266 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13); 346 OMAP_DMA_CSDP_REG(lch) |= 1 << 13;
267 w |= enable ? (1 << 13) : 0;
268 omap_writew(w, OMAP_DMA_CSDP(lch));
269} 347}
270 348
271void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) 349void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
272{ 350{
273 u16 w; 351 OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14);
274 352
275 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
276 switch (burst_mode) { 353 switch (burst_mode) {
277 case OMAP_DMA_DATA_BURST_DIS: 354 case OMAP_DMA_DATA_BURST_DIS:
278 break; 355 break;
279 case OMAP_DMA_DATA_BURST_4: 356 case OMAP_DMA_DATA_BURST_4:
280 w |= (0x01 << 14); 357 OMAP_DMA_CSDP_REG(lch) |= (0x02 << 14);
281 break; 358 break;
282 case OMAP_DMA_DATA_BURST_8: 359 case OMAP_DMA_DATA_BURST_8:
283 w |= (0x03 << 14); 360 OMAP_DMA_CSDP_REG(lch) |= (0x03 << 14);
284 break; 361 break;
285 default: 362 default:
286 printk(KERN_ERR "Invalid DMA burst mode\n"); 363 printk(KERN_ERR "Invalid DMA burst mode\n");
287 BUG(); 364 BUG();
288 return; 365 return;
289 } 366 }
290 omap_writew(w, OMAP_DMA_CSDP(lch));
291} 367}
292 368
293static inline void init_intr(int lch) 369static inline void omap_enable_channel_irq(int lch)
294{ 370{
295 u16 w; 371 u32 status;
296 372
297 /* Read CSR to make sure it's cleared. */ 373 /* Read CSR to make sure it's cleared. */
298 w = omap_readw(OMAP_DMA_CSR(lch)); 374 status = OMAP_DMA_CSR_REG(lch);
375
299 /* Enable some nice interrupts. */ 376 /* Enable some nice interrupts. */
300 omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch)); 377 OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs;
378
301 dma_chan[lch].flags |= OMAP_DMA_ACTIVE; 379 dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
302} 380}
303 381
304static inline void enable_lnk(int lch) 382static void omap_disable_channel_irq(int lch)
305{ 383{
306 u16 w; 384 if (cpu_is_omap24xx())
385 OMAP_DMA_CICR_REG(lch) = 0;
386}
387
388void omap_enable_dma_irq(int lch, u16 bits)
389{
390 dma_chan[lch].enabled_irqs |= bits;
391}
307 392
308 /* Clear the STOP_LNK bits */ 393void omap_disable_dma_irq(int lch, u16 bits)
309 w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); 394{
310 w &= ~(1 << 14); 395 dma_chan[lch].enabled_irqs &= ~bits;
311 omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); 396}
397
398static inline void enable_lnk(int lch)
399{
400 if (cpu_class_is_omap1())
401 OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 14);
312 402
313 /* And set the ENABLE_LNK bits */ 403 /* Set the ENABLE_LNK bits */
314 if (dma_chan[lch].next_lch != -1) 404 if (dma_chan[lch].next_lch != -1)
315 omap_writew(dma_chan[lch].next_lch | (1 << 15), 405 OMAP_DMA_CLNK_CTRL_REG(lch) =
316 OMAP_DMA_CLNK_CTRL(lch)); 406 dma_chan[lch].next_lch | (1 << 15);
317} 407}
318 408
319static inline void disable_lnk(int lch) 409static inline void disable_lnk(int lch)
320{ 410{
321 u16 w;
322
323 /* Disable interrupts */ 411 /* Disable interrupts */
324 omap_writew(0, OMAP_DMA_CICR(lch)); 412 if (cpu_class_is_omap1()) {
413 OMAP_DMA_CICR_REG(lch) = 0;
414 /* Set the STOP_LNK bit */
415 OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14;
416 }
325 417
326 /* Set the STOP_LNK bit */ 418 if (cpu_is_omap24xx()) {
327 w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); 419 omap_disable_channel_irq(lch);
328 w |= (1 << 14); 420 /* Clear the ENABLE_LNK bit */
329 w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); 421 OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15);
422 }
330 423
331 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; 424 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
332} 425}
333 426
334void omap_start_dma(int lch) 427static inline void omap2_enable_irq_lch(int lch)
335{ 428{
336 u16 w; 429 u32 val;
430
431 if (!cpu_is_omap24xx())
432 return;
433
434 val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
435 val |= 1 << lch;
436 omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
437}
438
439int omap_request_dma(int dev_id, const char *dev_name,
440 void (* callback)(int lch, u16 ch_status, void *data),
441 void *data, int *dma_ch_out)
442{
443 int ch, free_ch = -1;
444 unsigned long flags;
445 struct omap_dma_lch *chan;
446
447 spin_lock_irqsave(&dma_chan_lock, flags);
448 for (ch = 0; ch < dma_chan_count; ch++) {
449 if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
450 free_ch = ch;
451 if (dev_id == 0)
452 break;
453 }
454 }
455 if (free_ch == -1) {
456 spin_unlock_irqrestore(&dma_chan_lock, flags);
457 return -EBUSY;
458 }
459 chan = dma_chan + free_ch;
460 chan->dev_id = dev_id;
461
462 if (cpu_class_is_omap1())
463 clear_lch_regs(free_ch);
337 464
465 if (cpu_is_omap24xx())
466 omap_clear_dma(free_ch);
467
468 spin_unlock_irqrestore(&dma_chan_lock, flags);
469
470 chan->dev_name = dev_name;
471 chan->callback = callback;
472 chan->data = data;
473 chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ |
474 OMAP_DMA_BLOCK_IRQ;
475
476 if (cpu_is_omap24xx())
477 chan->enabled_irqs |= OMAP2_DMA_TRANS_ERR_IRQ;
478
479 if (cpu_is_omap16xx()) {
480 /* If the sync device is set, configure it dynamically. */
481 if (dev_id != 0) {
482 set_gdma_dev(free_ch + 1, dev_id);
483 dev_id = free_ch + 1;
484 }
485 /* Disable the 1510 compatibility mode and set the sync device
486 * id. */
487 OMAP_DMA_CCR_REG(free_ch) = dev_id | (1 << 10);
488 } else if (cpu_is_omap730() || cpu_is_omap15xx()) {
489 OMAP_DMA_CCR_REG(free_ch) = dev_id;
490 }
491
492 if (cpu_is_omap24xx()) {
493 omap2_enable_irq_lch(free_ch);
494
495 omap_enable_channel_irq(free_ch);
496 /* Clear the CSR register and IRQ status register */
497 OMAP_DMA_CSR_REG(free_ch) = 0x0;
498 omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0);
499 }
500
501 *dma_ch_out = free_ch;
502
503 return 0;
504}
505
506void omap_free_dma(int lch)
507{
508 unsigned long flags;
509
510 spin_lock_irqsave(&dma_chan_lock, flags);
511 if (dma_chan[lch].dev_id == -1) {
512 printk("omap_dma: trying to free nonallocated DMA channel %d\n",
513 lch);
514 spin_unlock_irqrestore(&dma_chan_lock, flags);
515 return;
516 }
517 dma_chan[lch].dev_id = -1;
518 dma_chan[lch].next_lch = -1;
519 dma_chan[lch].callback = NULL;
520 spin_unlock_irqrestore(&dma_chan_lock, flags);
521
522 if (cpu_class_is_omap1()) {
523 /* Disable all DMA interrupts for the channel. */
524 OMAP_DMA_CICR_REG(lch) = 0;
525 /* Make sure the DMA transfer is stopped. */
526 OMAP_DMA_CCR_REG(lch) = 0;
527 }
528
529 if (cpu_is_omap24xx()) {
530 u32 val;
531 /* Disable interrupts */
532 val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
533 val &= ~(1 << lch);
534 omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
535
536 /* Clear the CSR register and IRQ status register */
537 OMAP_DMA_CSR_REG(lch) = 0x0;
538
539 val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
540 val |= 1 << lch;
541 omap_writel(val, OMAP_DMA4_IRQSTATUS_L0);
542
543 /* Disable all DMA interrupts for the channel. */
544 OMAP_DMA_CICR_REG(lch) = 0;
545
546 /* Make sure the DMA transfer is stopped. */
547 OMAP_DMA_CCR_REG(lch) = 0;
548 omap_clear_dma(lch);
549 }
550}
551
552/*
553 * Clears any DMA state so the DMA engine is ready to restart with new buffers
554 * through omap_start_dma(). Any buffers in flight are discarded.
555 */
556void omap_clear_dma(int lch)
557{
558 unsigned long flags;
559
560 local_irq_save(flags);
561
562 if (cpu_class_is_omap1()) {
563 int status;
564 OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
565
566 /* Clear pending interrupts */
567 status = OMAP_DMA_CSR_REG(lch);
568 }
569
570 if (cpu_is_omap24xx()) {
571 int i;
572 u32 lch_base = OMAP24XX_DMA_BASE + lch * 0x60 + 0x80;
573 for (i = 0; i < 0x44; i += 4)
574 omap_writel(0, lch_base + i);
575 }
576
577 local_irq_restore(flags);
578}
579
580void omap_start_dma(int lch)
581{
338 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { 582 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
339 int next_lch, cur_lch; 583 int next_lch, cur_lch;
340 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; 584 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
@@ -348,31 +592,37 @@ void omap_start_dma(int lch)
348 do { 592 do {
349 next_lch = dma_chan[cur_lch].next_lch; 593 next_lch = dma_chan[cur_lch].next_lch;
350 594
351 /* The loop case: we've been here already */ 595 /* The loop case: we've been here already */
352 if (dma_chan_link_map[cur_lch]) 596 if (dma_chan_link_map[cur_lch])
353 break; 597 break;
354 /* Mark the current channel */ 598 /* Mark the current channel */
355 dma_chan_link_map[cur_lch] = 1; 599 dma_chan_link_map[cur_lch] = 1;
356 600
357 enable_lnk(cur_lch); 601 enable_lnk(cur_lch);
358 init_intr(cur_lch); 602 omap_enable_channel_irq(cur_lch);
359 603
360 cur_lch = next_lch; 604 cur_lch = next_lch;
361 } while (next_lch != -1); 605 } while (next_lch != -1);
606 } else if (cpu_is_omap24xx()) {
607 /* Errata: Need to write lch even if not using chaining */
608 OMAP_DMA_CLNK_CTRL_REG(lch) = lch;
362 } 609 }
363 610
364 init_intr(lch); 611 omap_enable_channel_irq(lch);
612
613 /* Errata: On ES2.0 BUFFERING disable must be set.
614 * This will always fail on ES1.0 */
615 if (cpu_is_omap24xx()) {
616 OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
617 }
618
619 OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
365 620
366 w = omap_readw(OMAP_DMA_CCR(lch));
367 w |= OMAP_DMA_CCR_EN;
368 omap_writew(w, OMAP_DMA_CCR(lch));
369 dma_chan[lch].flags |= OMAP_DMA_ACTIVE; 621 dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
370} 622}
371 623
372void omap_stop_dma(int lch) 624void omap_stop_dma(int lch)
373{ 625{
374 u16 w;
375
376 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { 626 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
377 int next_lch, cur_lch = lch; 627 int next_lch, cur_lch = lch;
378 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; 628 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
@@ -393,146 +643,83 @@ void omap_stop_dma(int lch)
393 643
394 return; 644 return;
395 } 645 }
646
396 /* Disable all interrupts on the channel */ 647 /* Disable all interrupts on the channel */
397 omap_writew(0, OMAP_DMA_CICR(lch)); 648 if (cpu_class_is_omap1())
649 OMAP_DMA_CICR_REG(lch) = 0;
398 650
399 w = omap_readw(OMAP_DMA_CCR(lch)); 651 OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
400 w &= ~OMAP_DMA_CCR_EN;
401 omap_writew(w, OMAP_DMA_CCR(lch));
402 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; 652 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
403} 653}
404 654
405void omap_enable_dma_irq(int lch, u16 bits) 655/*
656 * Returns current physical source address for the given DMA channel.
657 * If the channel is running the caller must disable interrupts prior calling
658 * this function and process the returned value before re-enabling interrupt to
659 * prevent races with the interrupt handler. Note that in continuous mode there
660 * is a chance for CSSA_L register overflow inbetween the two reads resulting
661 * in incorrect return value.
662 */
663dma_addr_t omap_get_dma_src_pos(int lch)
406{ 664{
407 dma_chan[lch].enabled_irqs |= bits; 665 dma_addr_t offset;
408}
409 666
410void omap_disable_dma_irq(int lch, u16 bits) 667 if (cpu_class_is_omap1())
411{ 668 offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) |
412 dma_chan[lch].enabled_irqs &= ~bits; 669 (OMAP1_DMA_CSSA_U_REG(lch) << 16));
413}
414 670
415static int dma_handle_ch(int ch) 671 if (cpu_is_omap24xx())
416{ 672 offset = OMAP_DMA_CSAC_REG(lch);
417 u16 csr;
418 673
419 if (enable_1510_mode && ch >= 6) { 674 return offset;
420 csr = dma_chan[ch].saved_csr;
421 dma_chan[ch].saved_csr = 0;
422 } else
423 csr = omap_readw(OMAP_DMA_CSR(ch));
424 if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
425 dma_chan[ch + 6].saved_csr = csr >> 7;
426 csr &= 0x7f;
427 }
428 if ((csr & 0x3f) == 0)
429 return 0;
430 if (unlikely(dma_chan[ch].dev_id == -1)) {
431 printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
432 ch, csr);
433 return 0;
434 }
435 if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
436 printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id);
437 if (unlikely(csr & OMAP_DMA_DROP_IRQ))
438 printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n",
439 dma_chan[ch].dev_id);
440 if (likely(csr & OMAP_DMA_BLOCK_IRQ))
441 dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
442 if (likely(dma_chan[ch].callback != NULL))
443 dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
444 return 1;
445} 675}
446 676
447static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) 677/*
678 * Returns current physical destination address for the given DMA channel.
679 * If the channel is running the caller must disable interrupts prior calling
680 * this function and process the returned value before re-enabling interrupt to
681 * prevent races with the interrupt handler. Note that in continuous mode there
682 * is a chance for CDSA_L register overflow inbetween the two reads resulting
683 * in incorrect return value.
684 */
685dma_addr_t omap_get_dma_dst_pos(int lch)
448{ 686{
449 int ch = ((int) dev_id) - 1; 687 dma_addr_t offset;
450 int handled = 0;
451 688
452 for (;;) { 689 if (cpu_class_is_omap1())
453 int handled_now = 0; 690 offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) |
691 (OMAP1_DMA_CDSA_U_REG(lch) << 16));
454 692
455 handled_now += dma_handle_ch(ch); 693 if (cpu_is_omap24xx())
456 if (enable_1510_mode && dma_chan[ch + 6].saved_csr) 694 offset = OMAP2_DMA_CDSA_REG(lch);
457 handled_now += dma_handle_ch(ch + 6);
458 if (!handled_now)
459 break;
460 handled += handled_now;
461 }
462 695
463 return handled ? IRQ_HANDLED : IRQ_NONE; 696 return offset;
464} 697}
465 698
466int omap_request_dma(int dev_id, const char *dev_name, 699/*
467 void (* callback)(int lch, u16 ch_status, void *data), 700 * Returns current source transfer counting for the given DMA channel.
468 void *data, int *dma_ch_out) 701 * Can be used to monitor the progress of a transfer inside a block.
702 * It must be called with disabled interrupts.
703 */
704int omap_get_dma_src_addr_counter(int lch)
469{ 705{
470 int ch, free_ch = -1; 706 return (dma_addr_t) OMAP_DMA_CSAC_REG(lch);
471 unsigned long flags;
472 struct omap_dma_lch *chan;
473
474 spin_lock_irqsave(&dma_chan_lock, flags);
475 for (ch = 0; ch < dma_chan_count; ch++) {
476 if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
477 free_ch = ch;
478 if (dev_id == 0)
479 break;
480 }
481 }
482 if (free_ch == -1) {
483 spin_unlock_irqrestore(&dma_chan_lock, flags);
484 return -EBUSY;
485 }
486 chan = dma_chan + free_ch;
487 chan->dev_id = dev_id;
488 clear_lch_regs(free_ch);
489 spin_unlock_irqrestore(&dma_chan_lock, flags);
490
491 chan->dev_id = dev_id;
492 chan->dev_name = dev_name;
493 chan->callback = callback;
494 chan->data = data;
495 chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
496
497 if (cpu_is_omap16xx()) {
498 /* If the sync device is set, configure it dynamically. */
499 if (dev_id != 0) {
500 set_gdma_dev(free_ch + 1, dev_id);
501 dev_id = free_ch + 1;
502 }
503 /* Disable the 1510 compatibility mode and set the sync device
504 * id. */
505 omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
506 } else {
507 omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
508 }
509 *dma_ch_out = free_ch;
510
511 return 0;
512} 707}
513 708
514void omap_free_dma(int ch) 709int omap_dma_running(void)
515{ 710{
516 unsigned long flags; 711 int lch;
517 712
518 spin_lock_irqsave(&dma_chan_lock, flags); 713 /* Check if LCD DMA is running */
519 if (dma_chan[ch].dev_id == -1) { 714 if (cpu_is_omap16xx())
520 printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch); 715 if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
521 spin_unlock_irqrestore(&dma_chan_lock, flags); 716 return 1;
522 return;
523 }
524 dma_chan[ch].dev_id = -1;
525 spin_unlock_irqrestore(&dma_chan_lock, flags);
526 717
527 /* Disable all DMA interrupts for the channel. */ 718 for (lch = 0; lch < dma_chan_count; lch++)
528 omap_writew(0, OMAP_DMA_CICR(ch)); 719 if (OMAP_DMA_CCR_REG(lch) & OMAP_DMA_CCR_EN)
529 /* Make sure the DMA transfer is stopped. */ 720 return 1;
530 omap_writew(0, OMAP_DMA_CCR(ch));
531}
532 721
533int omap_dma_in_1510_mode(void) 722 return 0;
534{
535 return enable_1510_mode;
536} 723}
537 724
538/* 725/*
@@ -550,7 +737,8 @@ void omap_dma_link_lch (int lch_head, int lch_queue)
550 737
551 if ((dma_chan[lch_head].dev_id == -1) || 738 if ((dma_chan[lch_head].dev_id == -1) ||
552 (dma_chan[lch_queue].dev_id == -1)) { 739 (dma_chan[lch_queue].dev_id == -1)) {
553 printk(KERN_ERR "omap_dma: trying to link non requested channels\n"); 740 printk(KERN_ERR "omap_dma: trying to link "
741 "non requested channels\n");
554 dump_stack(); 742 dump_stack();
555 } 743 }
556 744
@@ -570,20 +758,149 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue)
570 758
571 if (dma_chan[lch_head].next_lch != lch_queue || 759 if (dma_chan[lch_head].next_lch != lch_queue ||
572 dma_chan[lch_head].next_lch == -1) { 760 dma_chan[lch_head].next_lch == -1) {
573 printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n"); 761 printk(KERN_ERR "omap_dma: trying to unlink "
762 "non linked channels\n");
574 dump_stack(); 763 dump_stack();
575 } 764 }
576 765
577 766
578 if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) || 767 if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
579 (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) { 768 (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
580 printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n"); 769 printk(KERN_ERR "omap_dma: You need to stop the DMA channels "
770 "before unlinking\n");
581 dump_stack(); 771 dump_stack();
582 } 772 }
583 773
584 dma_chan[lch_head].next_lch = -1; 774 dma_chan[lch_head].next_lch = -1;
585} 775}
586 776
777/*----------------------------------------------------------------------------*/
778
779#ifdef CONFIG_ARCH_OMAP1
780
781static int omap1_dma_handle_ch(int ch)
782{
783 u16 csr;
784
785 if (enable_1510_mode && ch >= 6) {
786 csr = dma_chan[ch].saved_csr;
787 dma_chan[ch].saved_csr = 0;
788 } else
789 csr = OMAP_DMA_CSR_REG(ch);
790 if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
791 dma_chan[ch + 6].saved_csr = csr >> 7;
792 csr &= 0x7f;
793 }
794 if ((csr & 0x3f) == 0)
795 return 0;
796 if (unlikely(dma_chan[ch].dev_id == -1)) {
797 printk(KERN_WARNING "Spurious interrupt from DMA channel "
798 "%d (CSR %04x)\n", ch, csr);
799 return 0;
800 }
801 if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
802 printk(KERN_WARNING "DMA timeout with device %d\n",
803 dma_chan[ch].dev_id);
804 if (unlikely(csr & OMAP_DMA_DROP_IRQ))
805 printk(KERN_WARNING "DMA synchronization event drop occurred "
806 "with device %d\n", dma_chan[ch].dev_id);
807 if (likely(csr & OMAP_DMA_BLOCK_IRQ))
808 dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
809 if (likely(dma_chan[ch].callback != NULL))
810 dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
811 return 1;
812}
813
814static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id,
815 struct pt_regs *regs)
816{
817 int ch = ((int) dev_id) - 1;
818 int handled = 0;
819
820 for (;;) {
821 int handled_now = 0;
822
823 handled_now += omap1_dma_handle_ch(ch);
824 if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
825 handled_now += omap1_dma_handle_ch(ch + 6);
826 if (!handled_now)
827 break;
828 handled += handled_now;
829 }
830
831 return handled ? IRQ_HANDLED : IRQ_NONE;
832}
833
834#else
835#define omap1_dma_irq_handler NULL
836#endif
837
838#ifdef CONFIG_ARCH_OMAP2
839
840static int omap2_dma_handle_ch(int ch)
841{
842 u32 status = OMAP_DMA_CSR_REG(ch);
843 u32 val;
844
845 if (!status)
846 return 0;
847 if (unlikely(dma_chan[ch].dev_id == -1))
848 return 0;
849 /* REVISIT: According to 24xx TRM, there's no TOUT_IE */
850 if (unlikely(status & OMAP_DMA_TOUT_IRQ))
851 printk(KERN_INFO "DMA timeout with device %d\n",
852 dma_chan[ch].dev_id);
853 if (unlikely(status & OMAP_DMA_DROP_IRQ))
854 printk(KERN_INFO
855 "DMA synchronization event drop occurred with device "
856 "%d\n", dma_chan[ch].dev_id);
857
858 if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ))
859 printk(KERN_INFO "DMA transaction error with device %d\n",
860 dma_chan[ch].dev_id);
861
862 OMAP_DMA_CSR_REG(ch) = 0x20;
863
864 val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
865 /* ch in this function is from 0-31 while in register it is 1-32 */
866 val = 1 << (ch);
867 omap_writel(val, OMAP_DMA4_IRQSTATUS_L0);
868
869 if (likely(dma_chan[ch].callback != NULL))
870 dma_chan[ch].callback(ch, status, dma_chan[ch].data);
871
872 return 0;
873}
874
875/* STATUS register count is from 1-32 while our is 0-31 */
876static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id,
877 struct pt_regs *regs)
878{
879 u32 val;
880 int i;
881
882 val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
883
884 for (i = 1; i <= OMAP_LOGICAL_DMA_CH_COUNT; i++) {
885 int active = val & (1 << (i - 1));
886 if (active)
887 omap2_dma_handle_ch(i - 1);
888 }
889
890 return IRQ_HANDLED;
891}
892
893static struct irqaction omap24xx_dma_irq = {
894 .name = "DMA",
895 .handler = omap2_dma_irq_handler,
896 .flags = SA_INTERRUPT
897};
898
899#else
900static struct irqaction omap24xx_dma_irq;
901#endif
902
903/*----------------------------------------------------------------------------*/
587 904
588static struct lcd_dma_info { 905static struct lcd_dma_info {
589 spinlock_t lock; 906 spinlock_t lock;
@@ -795,7 +1112,7 @@ static void set_b1_regs(void)
795 /* Always set the source port as SDRAM for now*/ 1112 /* Always set the source port as SDRAM for now*/
796 w &= ~(0x03 << 6); 1113 w &= ~(0x03 << 6);
797 if (lcd_dma.callback != NULL) 1114 if (lcd_dma.callback != NULL)
798 w |= 1 << 1; /* Block interrupt enable */ 1115 w |= 1 << 1; /* Block interrupt enable */
799 else 1116 else
800 w &= ~(1 << 1); 1117 w &= ~(1 << 1);
801 omap_writew(w, OMAP1610_DMA_LCD_CTRL); 1118 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
@@ -814,7 +1131,8 @@ static void set_b1_regs(void)
814 omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L); 1131 omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
815} 1132}
816 1133
817static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) 1134static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id,
1135 struct pt_regs *regs)
818{ 1136{
819 u16 w; 1137 u16 w;
820 1138
@@ -870,7 +1188,8 @@ void omap_free_lcd_dma(void)
870 return; 1188 return;
871 } 1189 }
872 if (!enable_1510_mode) 1190 if (!enable_1510_mode)
873 omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR); 1191 omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
1192 OMAP1610_DMA_LCD_CCR);
874 lcd_dma.reserved = 0; 1193 lcd_dma.reserved = 0;
875 spin_unlock(&lcd_dma.lock); 1194 spin_unlock(&lcd_dma.lock);
876} 1195}
@@ -939,93 +1258,24 @@ void omap_stop_lcd_dma(void)
939 omap_writew(w, OMAP1610_DMA_LCD_CTRL); 1258 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
940} 1259}
941 1260
942/* 1261/*----------------------------------------------------------------------------*/
943 * Clears any DMA state so the DMA engine is ready to restart with new buffers
944 * through omap_start_dma(). Any buffers in flight are discarded.
945 */
946void omap_clear_dma(int lch)
947{
948 unsigned long flags;
949 int status;
950
951 local_irq_save(flags);
952 omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN,
953 OMAP_DMA_CCR(lch));
954 status = OMAP_DMA_CSR(lch); /* clear pending interrupts */
955 local_irq_restore(flags);
956}
957
958/*
959 * Returns current physical source address for the given DMA channel.
960 * If the channel is running the caller must disable interrupts prior calling
961 * this function and process the returned value before re-enabling interrupt to
962 * prevent races with the interrupt handler. Note that in continuous mode there
963 * is a chance for CSSA_L register overflow inbetween the two reads resulting
964 * in incorrect return value.
965 */
966dma_addr_t omap_get_dma_src_pos(int lch)
967{
968 return (dma_addr_t) (omap_readw(OMAP_DMA_CSSA_L(lch)) |
969 (omap_readw(OMAP_DMA_CSSA_U(lch)) << 16));
970}
971
972/*
973 * Returns current physical destination address for the given DMA channel.
974 * If the channel is running the caller must disable interrupts prior calling
975 * this function and process the returned value before re-enabling interrupt to
976 * prevent races with the interrupt handler. Note that in continuous mode there
977 * is a chance for CDSA_L register overflow inbetween the two reads resulting
978 * in incorrect return value.
979 */
980dma_addr_t omap_get_dma_dst_pos(int lch)
981{
982 return (dma_addr_t) (omap_readw(OMAP_DMA_CDSA_L(lch)) |
983 (omap_readw(OMAP_DMA_CDSA_U(lch)) << 16));
984}
985
986/*
987 * Returns current source transfer counting for the given DMA channel.
988 * Can be used to monitor the progress of a transfer inside a block.
989 * It must be called with disabled interrupts.
990 */
991int omap_get_dma_src_addr_counter(int lch)
992{
993 return (dma_addr_t) omap_readw(OMAP_DMA_CSAC(lch));
994}
995
996int omap_dma_running(void)
997{
998 int lch;
999
1000 /* Check if LCD DMA is running */
1001 if (cpu_is_omap16xx())
1002 if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
1003 return 1;
1004
1005 for (lch = 0; lch < dma_chan_count; lch++) {
1006 u16 w;
1007
1008 w = omap_readw(OMAP_DMA_CCR(lch));
1009 if (w & OMAP_DMA_CCR_EN)
1010 return 1;
1011 }
1012 return 0;
1013}
1014 1262
1015static int __init omap_init_dma(void) 1263static int __init omap_init_dma(void)
1016{ 1264{
1017 int ch, r; 1265 int ch, r;
1018 1266
1019 if (cpu_is_omap1510()) { 1267 if (cpu_is_omap15xx()) {
1020 printk(KERN_INFO "DMA support for OMAP1510 initialized\n"); 1268 printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
1021 dma_chan_count = 9; 1269 dma_chan_count = 9;
1022 enable_1510_mode = 1; 1270 enable_1510_mode = 1;
1023 } else if (cpu_is_omap16xx() || cpu_is_omap730()) { 1271 } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
1024 printk(KERN_INFO "OMAP DMA hardware version %d\n", 1272 printk(KERN_INFO "OMAP DMA hardware version %d\n",
1025 omap_readw(OMAP_DMA_HW_ID)); 1273 omap_readw(OMAP_DMA_HW_ID));
1026 printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", 1274 printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
1027 (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L), 1275 (omap_readw(OMAP_DMA_CAPS_0_U) << 16) |
1028 (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L), 1276 omap_readw(OMAP_DMA_CAPS_0_L),
1277 (omap_readw(OMAP_DMA_CAPS_1_U) << 16) |
1278 omap_readw(OMAP_DMA_CAPS_1_L),
1029 omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3), 1279 omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
1030 omap_readw(OMAP_DMA_CAPS_4)); 1280 omap_readw(OMAP_DMA_CAPS_4));
1031 if (!enable_1510_mode) { 1281 if (!enable_1510_mode) {
@@ -1038,6 +1288,11 @@ static int __init omap_init_dma(void)
1038 dma_chan_count = 16; 1288 dma_chan_count = 16;
1039 } else 1289 } else
1040 dma_chan_count = 9; 1290 dma_chan_count = 9;
1291 } else if (cpu_is_omap24xx()) {
1292 u8 revision = omap_readb(OMAP_DMA4_REVISION);
1293 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
1294 revision >> 4, revision & 0xf);
1295 dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT;
1041 } else { 1296 } else {
1042 dma_chan_count = 0; 1297 dma_chan_count = 0;
1043 return 0; 1298 return 0;
@@ -1049,41 +1304,56 @@ static int __init omap_init_dma(void)
1049 memset(&dma_chan, 0, sizeof(dma_chan)); 1304 memset(&dma_chan, 0, sizeof(dma_chan));
1050 1305
1051 for (ch = 0; ch < dma_chan_count; ch++) { 1306 for (ch = 0; ch < dma_chan_count; ch++) {
1307 omap_clear_dma(ch);
1052 dma_chan[ch].dev_id = -1; 1308 dma_chan[ch].dev_id = -1;
1053 dma_chan[ch].next_lch = -1; 1309 dma_chan[ch].next_lch = -1;
1054 1310
1055 if (ch >= 6 && enable_1510_mode) 1311 if (ch >= 6 && enable_1510_mode)
1056 continue; 1312 continue;
1057 1313
1058 /* request_irq() doesn't like dev_id (ie. ch) being zero, 1314 if (cpu_class_is_omap1()) {
1059 * so we have to kludge around this. */ 1315 /* request_irq() doesn't like dev_id (ie. ch) being
1060 r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA", 1316 * zero, so we have to kludge around this. */
1061 (void *) (ch + 1)); 1317 r = request_irq(omap1_dma_irq[ch],
1318 omap1_dma_irq_handler, 0, "DMA",
1319 (void *) (ch + 1));
1320 if (r != 0) {
1321 int i;
1322
1323 printk(KERN_ERR "unable to request IRQ %d "
1324 "for DMA (error %d)\n",
1325 omap1_dma_irq[ch], r);
1326 for (i = 0; i < ch; i++)
1327 free_irq(omap1_dma_irq[i],
1328 (void *) (i + 1));
1329 return r;
1330 }
1331 }
1332 }
1333
1334 if (cpu_is_omap24xx())
1335 setup_irq(INT_24XX_SDMA_IRQ0, &omap24xx_dma_irq);
1336
1337 /* FIXME: Update LCD DMA to work on 24xx */
1338 if (cpu_class_is_omap1()) {
1339 r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
1340 "LCD DMA", NULL);
1062 if (r != 0) { 1341 if (r != 0) {
1063 int i; 1342 int i;
1064 1343
1065 printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n", 1344 printk(KERN_ERR "unable to request IRQ for LCD DMA "
1066 dma_irq[ch], r); 1345 "(error %d)\n", r);
1067 for (i = 0; i < ch; i++) 1346 for (i = 0; i < dma_chan_count; i++)
1068 free_irq(dma_irq[i], (void *) (i + 1)); 1347 free_irq(omap1_dma_irq[i], (void *) (i + 1));
1069 return r; 1348 return r;
1070 } 1349 }
1071 } 1350 }
1072 r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
1073 if (r != 0) {
1074 int i;
1075 1351
1076 printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
1077 for (i = 0; i < dma_chan_count; i++)
1078 free_irq(dma_irq[i], (void *) (i + 1));
1079 return r;
1080 }
1081 return 0; 1352 return 0;
1082} 1353}
1083 1354
1084arch_initcall(omap_init_dma); 1355arch_initcall(omap_init_dma);
1085 1356
1086
1087EXPORT_SYMBOL(omap_get_dma_src_pos); 1357EXPORT_SYMBOL(omap_get_dma_src_pos);
1088EXPORT_SYMBOL(omap_get_dma_dst_pos); 1358EXPORT_SYMBOL(omap_get_dma_dst_pos);
1089EXPORT_SYMBOL(omap_get_dma_src_addr_counter); 1359EXPORT_SYMBOL(omap_get_dma_src_addr_counter);
@@ -1109,6 +1379,8 @@ EXPORT_SYMBOL(omap_set_dma_dest_index);
1109EXPORT_SYMBOL(omap_set_dma_dest_data_pack); 1379EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
1110EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); 1380EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
1111 1381
1382EXPORT_SYMBOL(omap_set_dma_params);
1383
1112EXPORT_SYMBOL(omap_dma_link_lch); 1384EXPORT_SYMBOL(omap_dma_link_lch);
1113EXPORT_SYMBOL(omap_dma_unlink_lch); 1385EXPORT_SYMBOL(omap_dma_unlink_lch);
1114 1386
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 55059a24ad41..76f721d85137 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -140,7 +140,7 @@ static struct gpio_bank gpio_bank_1610[5] = {
140}; 140};
141#endif 141#endif
142 142
143#ifdef CONFIG_ARCH_OMAP1510 143#ifdef CONFIG_ARCH_OMAP15XX
144static struct gpio_bank gpio_bank_1510[2] = { 144static struct gpio_bank gpio_bank_1510[2] = {
145 { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, 145 { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
146 { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 } 146 { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 }
@@ -173,7 +173,7 @@ static int gpio_bank_count;
173 173
174static inline struct gpio_bank *get_gpio_bank(int gpio) 174static inline struct gpio_bank *get_gpio_bank(int gpio)
175{ 175{
176#ifdef CONFIG_ARCH_OMAP1510 176#ifdef CONFIG_ARCH_OMAP15XX
177 if (cpu_is_omap1510()) { 177 if (cpu_is_omap1510()) {
178 if (OMAP_GPIO_IS_MPUIO(gpio)) 178 if (OMAP_GPIO_IS_MPUIO(gpio))
179 return &gpio_bank[0]; 179 return &gpio_bank[0];
@@ -222,7 +222,7 @@ static inline int gpio_valid(int gpio)
222 return -1; 222 return -1;
223 return 0; 223 return 0;
224 } 224 }
225#ifdef CONFIG_ARCH_OMAP1510 225#ifdef CONFIG_ARCH_OMAP15XX
226 if (cpu_is_omap1510() && gpio < 16) 226 if (cpu_is_omap1510() && gpio < 16)
227 return 0; 227 return 0;
228#endif 228#endif
@@ -654,7 +654,7 @@ int omap_request_gpio(int gpio)
654 /* Set trigger to none. You need to enable the trigger after request_irq */ 654 /* Set trigger to none. You need to enable the trigger after request_irq */
655 _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); 655 _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
656 656
657#ifdef CONFIG_ARCH_OMAP1510 657#ifdef CONFIG_ARCH_OMAP15XX
658 if (bank->method == METHOD_GPIO_1510) { 658 if (bank->method == METHOD_GPIO_1510) {
659 void __iomem *reg; 659 void __iomem *reg;
660 660
@@ -739,7 +739,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
739 bank = (struct gpio_bank *) desc->data; 739 bank = (struct gpio_bank *) desc->data;
740 if (bank->method == METHOD_MPUIO) 740 if (bank->method == METHOD_MPUIO)
741 isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; 741 isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
742#ifdef CONFIG_ARCH_OMAP1510 742#ifdef CONFIG_ARCH_OMAP15XX
743 if (bank->method == METHOD_GPIO_1510) 743 if (bank->method == METHOD_GPIO_1510)
744 isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS; 744 isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
745#endif 745#endif
@@ -774,7 +774,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
774 d = irq_desc + gpio_irq; 774 d = irq_desc + gpio_irq;
775 desc_handle_irq(gpio_irq, d, regs); 775 desc_handle_irq(gpio_irq, d, regs);
776 } 776 }
777 } 777 }
778} 778}
779 779
780static void gpio_ack_irq(unsigned int irq) 780static void gpio_ack_irq(unsigned int irq)
@@ -837,8 +837,9 @@ static struct irqchip mpuio_irq_chip = {
837 .unmask = mpuio_unmask_irq 837 .unmask = mpuio_unmask_irq
838}; 838};
839 839
840static int initialized = 0; 840static int initialized;
841static struct clk * gpio_ck = NULL; 841static struct clk * gpio_ick;
842static struct clk * gpio_fck;
842 843
843static int __init _omap_gpio_init(void) 844static int __init _omap_gpio_init(void)
844{ 845{
@@ -848,14 +849,26 @@ static int __init _omap_gpio_init(void)
848 initialized = 1; 849 initialized = 1;
849 850
850 if (cpu_is_omap1510()) { 851 if (cpu_is_omap1510()) {
851 gpio_ck = clk_get(NULL, "arm_gpio_ck"); 852 gpio_ick = clk_get(NULL, "arm_gpio_ck");
852 if (IS_ERR(gpio_ck)) 853 if (IS_ERR(gpio_ick))
853 printk("Could not get arm_gpio_ck\n"); 854 printk("Could not get arm_gpio_ck\n");
854 else 855 else
855 clk_use(gpio_ck); 856 clk_use(gpio_ick);
857 }
858 if (cpu_is_omap24xx()) {
859 gpio_ick = clk_get(NULL, "gpios_ick");
860 if (IS_ERR(gpio_ick))
861 printk("Could not get gpios_ick\n");
862 else
863 clk_use(gpio_ick);
864 gpio_fck = clk_get(NULL, "gpios_fck");
865 if (IS_ERR(gpio_ick))
866 printk("Could not get gpios_fck\n");
867 else
868 clk_use(gpio_fck);
856 } 869 }
857 870
858#ifdef CONFIG_ARCH_OMAP1510 871#ifdef CONFIG_ARCH_OMAP15XX
859 if (cpu_is_omap1510()) { 872 if (cpu_is_omap1510()) {
860 printk(KERN_INFO "OMAP1510 GPIO hardware\n"); 873 printk(KERN_INFO "OMAP1510 GPIO hardware\n");
861 gpio_bank_count = 2; 874 gpio_bank_count = 2;
@@ -901,7 +914,7 @@ static int __init _omap_gpio_init(void)
901 if (bank->method == METHOD_MPUIO) { 914 if (bank->method == METHOD_MPUIO) {
902 omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); 915 omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
903 } 916 }
904#ifdef CONFIG_ARCH_OMAP1510 917#ifdef CONFIG_ARCH_OMAP15XX
905 if (bank->method == METHOD_GPIO_1510) { 918 if (bank->method == METHOD_GPIO_1510) {
906 __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); 919 __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
907 __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); 920 __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
@@ -1038,6 +1051,7 @@ static struct sys_device omap_gpio_device = {
1038 1051
1039/* 1052/*
1040 * This may get called early from board specific init 1053 * This may get called early from board specific init
1054 * for boards that have interrupts routed via FPGA.
1041 */ 1055 */
1042int omap_gpio_init(void) 1056int omap_gpio_init(void)
1043{ 1057{
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 9c9b7df3faf6..ea9475c86656 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -491,17 +491,20 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
491 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, 491 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
492 OMAP_DMA_DATA_TYPE_S16, 492 OMAP_DMA_DATA_TYPE_S16,
493 length >> 1, 1, 493 length >> 1, 1,
494 OMAP_DMA_SYNC_ELEMENT); 494 OMAP_DMA_SYNC_ELEMENT,
495 0, 0);
495 496
496 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, 497 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
497 OMAP_DMA_PORT_TIPB, 498 OMAP_DMA_PORT_TIPB,
498 OMAP_DMA_AMODE_CONSTANT, 499 OMAP_DMA_AMODE_CONSTANT,
499 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1); 500 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
501 0, 0);
500 502
501 omap_set_dma_src_params(mcbsp[id].dma_tx_lch, 503 omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
502 OMAP_DMA_PORT_EMIFF, 504 OMAP_DMA_PORT_EMIFF,
503 OMAP_DMA_AMODE_POST_INC, 505 OMAP_DMA_AMODE_POST_INC,
504 buffer); 506 buffer,
507 0, 0);
505 508
506 omap_start_dma(mcbsp[id].dma_tx_lch); 509 omap_start_dma(mcbsp[id].dma_tx_lch);
507 wait_for_completion(&(mcbsp[id].tx_dma_completion)); 510 wait_for_completion(&(mcbsp[id].tx_dma_completion));
@@ -531,17 +534,20 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
531 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, 534 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
532 OMAP_DMA_DATA_TYPE_S16, 535 OMAP_DMA_DATA_TYPE_S16,
533 length >> 1, 1, 536 length >> 1, 1,
534 OMAP_DMA_SYNC_ELEMENT); 537 OMAP_DMA_SYNC_ELEMENT,
538 0, 0);
535 539
536 omap_set_dma_src_params(mcbsp[id].dma_rx_lch, 540 omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
537 OMAP_DMA_PORT_TIPB, 541 OMAP_DMA_PORT_TIPB,
538 OMAP_DMA_AMODE_CONSTANT, 542 OMAP_DMA_AMODE_CONSTANT,
539 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1); 543 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
544 0, 0);
540 545
541 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, 546 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
542 OMAP_DMA_PORT_EMIFF, 547 OMAP_DMA_PORT_EMIFF,
543 OMAP_DMA_AMODE_POST_INC, 548 OMAP_DMA_AMODE_POST_INC,
544 buffer); 549 buffer,
550 0, 0);
545 551
546 omap_start_dma(mcbsp[id].dma_rx_lch); 552 omap_start_dma(mcbsp[id].dma_rx_lch);
547 wait_for_completion(&(mcbsp[id].rx_dma_completion)); 553 wait_for_completion(&(mcbsp[id].rx_dma_completion));
@@ -643,7 +649,7 @@ static const struct omap_mcbsp_info mcbsp_730[] = {
643}; 649};
644#endif 650#endif
645 651
646#ifdef CONFIG_ARCH_OMAP1510 652#ifdef CONFIG_ARCH_OMAP15XX
647static const struct omap_mcbsp_info mcbsp_1510[] = { 653static const struct omap_mcbsp_info mcbsp_1510[] = {
648 [0] = { .virt_base = OMAP1510_MCBSP1_BASE, 654 [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
649 .dma_rx_sync = OMAP_DMA_MCBSP1_RX, 655 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
@@ -712,7 +718,7 @@ static int __init omap_mcbsp_init(void)
712 mcbsp_count = ARRAY_SIZE(mcbsp_730); 718 mcbsp_count = ARRAY_SIZE(mcbsp_730);
713 } 719 }
714#endif 720#endif
715#ifdef CONFIG_ARCH_OMAP1510 721#ifdef CONFIG_ARCH_OMAP15XX
716 if (cpu_is_omap1510()) { 722 if (cpu_is_omap1510()) {
717 mcbsp_info = mcbsp_1510; 723 mcbsp_info = mcbsp_1510;
718 mcbsp_count = ARRAY_SIZE(mcbsp_1510); 724 mcbsp_count = ARRAY_SIZE(mcbsp_1510);
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
index 64482040f89e..8c1c016aa689 100644
--- a/arch/arm/plat-omap/mux.c
+++ b/arch/arm/plat-omap/mux.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h 4 * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
5 * 5 *
6 * Copyright (C) 2003 Nokia Corporation 6 * Copyright (C) 2003 - 2005 Nokia Corporation
7 * 7 *
8 * Written by Tony Lindgren <tony.lindgren@nokia.com> 8 * Written by Tony Lindgren <tony.lindgren@nokia.com>
9 * 9 *
@@ -25,38 +25,74 @@
25#include <linux/config.h> 25#include <linux/config.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/kernel.h>
28#include <asm/system.h> 29#include <asm/system.h>
29#include <asm/io.h> 30#include <asm/io.h>
30#include <linux/spinlock.h> 31#include <linux/spinlock.h>
31
32#define __MUX_C__
33#include <asm/arch/mux.h> 32#include <asm/arch/mux.h>
34 33
35#ifdef CONFIG_OMAP_MUX 34#ifdef CONFIG_OMAP_MUX
36 35
36#define OMAP24XX_L4_BASE 0x48000000
37#define OMAP24XX_PULL_ENA (1 << 3)
38#define OMAP24XX_PULL_UP (1 << 4)
39
40static struct pin_config * pin_table;
41static unsigned long pin_table_sz;
42
43extern struct pin_config * omap730_pins;
44extern struct pin_config * omap1xxx_pins;
45extern struct pin_config * omap24xx_pins;
46
47int __init omap_mux_register(struct pin_config * pins, unsigned long size)
48{
49 pin_table = pins;
50 pin_table_sz = size;
51
52 return 0;
53}
54
37/* 55/*
38 * Sets the Omap MUX and PULL_DWN registers based on the table 56 * Sets the Omap MUX and PULL_DWN registers based on the table
39 */ 57 */
40int __init_or_module 58int __init_or_module omap_cfg_reg(const unsigned long index)
41omap_cfg_reg(const reg_cfg_t reg_cfg)
42{ 59{
43 static DEFINE_SPINLOCK(mux_spin_lock); 60 static DEFINE_SPINLOCK(mux_spin_lock);
44 61
45 unsigned long flags; 62 unsigned long flags;
46 reg_cfg_set *cfg; 63 struct pin_config *cfg;
47 unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, 64 unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
48 pull_orig = 0, pull = 0; 65 pull_orig = 0, pull = 0;
49 unsigned int mask, warn = 0; 66 unsigned int mask, warn = 0;
50 67
51 if (cpu_is_omap7xx()) 68 if (!pin_table)
52 return 0; 69 BUG();
53 70
54 if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) { 71 if (index >= pin_table_sz) {
55 printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg); 72 printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
56 return -EINVAL; 73 index, pin_table_sz);
74 dump_stack();
75 return -ENODEV;
57 } 76 }
58 77
59 cfg = (reg_cfg_set *)&reg_cfg_table[reg_cfg]; 78 cfg = (struct pin_config *)&pin_table[index];
79 if (cpu_is_omap24xx()) {
80 u8 reg = 0;
81
82 reg |= cfg->mask & 0x7;
83 if (cfg->pull_val)
84 reg |= OMAP24XX_PULL_ENA;
85 if(cfg->pu_pd_val)
86 reg |= OMAP24XX_PULL_UP;
87#ifdef CONFIG_OMAP_MUX_DEBUG
88 printk("Muxing %s (0x%08x): 0x%02x -> 0x%02x\n",
89 cfg->name, OMAP24XX_L4_BASE + cfg->mux_reg,
90 omap_readb(OMAP24XX_L4_BASE + cfg->mux_reg), reg);
91#endif
92 omap_writeb(reg, OMAP24XX_L4_BASE + cfg->mux_reg);
93
94 return 0;
95 }
60 96
61 /* Check the mux register in question */ 97 /* Check the mux register in question */
62 if (cfg->mux_reg) { 98 if (cfg->mux_reg) {
@@ -157,7 +193,8 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
157 return 0; 193 return 0;
158#endif 194#endif
159} 195}
160
161EXPORT_SYMBOL(omap_cfg_reg); 196EXPORT_SYMBOL(omap_cfg_reg);
162 197#else
198#define omap_mux_init() do {} while(0)
199#define omap_cfg_reg(x) do {} while(0)
163#endif /* CONFIG_OMAP_MUX */ 200#endif /* CONFIG_OMAP_MUX */
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 1fb16f9edfd5..2ede2ee8cae4 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -25,7 +25,6 @@
25 25
26#include <linux/config.h> 26#include <linux/config.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/version.h>
29#include <linux/types.h> 28#include <linux/types.h>
30#include <linux/errno.h> 29#include <linux/errno.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
index e15c6c1ddec9..966cca031ca7 100644
--- a/arch/arm/plat-omap/pm.c
+++ b/arch/arm/plat-omap/pm.c
@@ -54,11 +54,12 @@
54#include <asm/arch/tps65010.h> 54#include <asm/arch/tps65010.h>
55#include <asm/arch/dsp_common.h> 55#include <asm/arch/dsp_common.h>
56 56
57#include "clock.h" 57#include <asm/arch/clock.h>
58#include "sram.h" 58#include <asm/arch/sram.h>
59 59
60static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; 60static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
61static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; 61static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
62static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
62static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; 63static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
63static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; 64static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
64 65
@@ -120,8 +121,8 @@ void omap_pm_idle(void)
120 */ 121 */
121static void omap_pm_wakeup_setup(void) 122static void omap_pm_wakeup_setup(void)
122{ 123{
123 u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ); 124 u32 level1_wake = 0;
124 u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD); 125 u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
125 126
126 /* 127 /*
127 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, 128 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
@@ -129,19 +130,29 @@ static void omap_pm_wakeup_setup(void)
129 * drivers must still separately call omap_set_gpio_wakeup() to 130 * drivers must still separately call omap_set_gpio_wakeup() to
130 * wake up to a GPIO interrupt. 131 * wake up to a GPIO interrupt.
131 */ 132 */
132 if (cpu_is_omap1510() || cpu_is_omap16xx()) 133 if (cpu_is_omap730())
133 level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1); 134 level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
134 else if (cpu_is_omap730()) 135 OMAP_IRQ_BIT(INT_730_IH2_IRQ);
135 level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1); 136 else if (cpu_is_omap1510())
137 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
138 OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
139 else if (cpu_is_omap16xx())
140 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
141 OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
136 142
137 omap_writel(~level1_wake, OMAP_IH1_MIR); 143 omap_writel(~level1_wake, OMAP_IH1_MIR);
138 144
139 if (cpu_is_omap1510()) 145 if (cpu_is_omap730()) {
146 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
147 omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR);
148 } else if (cpu_is_omap1510()) {
149 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
140 omap_writel(~level2_wake, OMAP_IH2_MIR); 150 omap_writel(~level2_wake, OMAP_IH2_MIR);
141 151 } else if (cpu_is_omap16xx()) {
142 /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ 152 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
143 if (cpu_is_omap16xx()) {
144 omap_writel(~level2_wake, OMAP_IH2_0_MIR); 153 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
154
155 /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
145 omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); 156 omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
146 omap_writel(~0x0, OMAP_IH2_2_MIR); 157 omap_writel(~0x0, OMAP_IH2_2_MIR);
147 omap_writel(~0x0, OMAP_IH2_3_MIR); 158 omap_writel(~0x0, OMAP_IH2_3_MIR);
@@ -185,7 +196,17 @@ void omap_pm_suspend(void)
185 * Save interrupt, MPUI, ARM and UPLD control registers. 196 * Save interrupt, MPUI, ARM and UPLD control registers.
186 */ 197 */
187 198
188 if (cpu_is_omap1510()) { 199 if (cpu_is_omap730()) {
200 MPUI730_SAVE(OMAP_IH1_MIR);
201 MPUI730_SAVE(OMAP_IH2_0_MIR);
202 MPUI730_SAVE(OMAP_IH2_1_MIR);
203 MPUI730_SAVE(MPUI_CTRL);
204 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
205 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
206 MPUI730_SAVE(EMIFS_CONFIG);
207 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
208
209 } else if (cpu_is_omap1510()) {
189 MPUI1510_SAVE(OMAP_IH1_MIR); 210 MPUI1510_SAVE(OMAP_IH1_MIR);
190 MPUI1510_SAVE(OMAP_IH2_MIR); 211 MPUI1510_SAVE(OMAP_IH2_MIR);
191 MPUI1510_SAVE(MPUI_CTRL); 212 MPUI1510_SAVE(MPUI_CTRL);
@@ -280,7 +301,13 @@ void omap_pm_suspend(void)
280 ULPD_RESTORE(ULPD_CLOCK_CTRL); 301 ULPD_RESTORE(ULPD_CLOCK_CTRL);
281 ULPD_RESTORE(ULPD_STATUS_REQ); 302 ULPD_RESTORE(ULPD_STATUS_REQ);
282 303
283 if (cpu_is_omap1510()) { 304 if (cpu_is_omap730()) {
305 MPUI730_RESTORE(EMIFS_CONFIG);
306 MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
307 MPUI730_RESTORE(OMAP_IH1_MIR);
308 MPUI730_RESTORE(OMAP_IH2_0_MIR);
309 MPUI730_RESTORE(OMAP_IH2_1_MIR);
310 } else if (cpu_is_omap1510()) {
284 MPUI1510_RESTORE(MPUI_CTRL); 311 MPUI1510_RESTORE(MPUI_CTRL);
285 MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); 312 MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
286 MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); 313 MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
@@ -355,7 +382,14 @@ static int omap_pm_read_proc(
355 ULPD_SAVE(ULPD_DPLL_CTRL); 382 ULPD_SAVE(ULPD_DPLL_CTRL);
356 ULPD_SAVE(ULPD_POWER_CTRL); 383 ULPD_SAVE(ULPD_POWER_CTRL);
357 384
358 if (cpu_is_omap1510()) { 385 if (cpu_is_omap730()) {
386 MPUI730_SAVE(MPUI_CTRL);
387 MPUI730_SAVE(MPUI_DSP_STATUS);
388 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
389 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
390 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
391 MPUI730_SAVE(EMIFS_CONFIG);
392 } else if (cpu_is_omap1510()) {
359 MPUI1510_SAVE(MPUI_CTRL); 393 MPUI1510_SAVE(MPUI_CTRL);
360 MPUI1510_SAVE(MPUI_DSP_STATUS); 394 MPUI1510_SAVE(MPUI_DSP_STATUS);
361 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); 395 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
@@ -404,7 +438,21 @@ static int omap_pm_read_proc(
404 ULPD_SHOW(ULPD_STATUS_REQ), 438 ULPD_SHOW(ULPD_STATUS_REQ),
405 ULPD_SHOW(ULPD_POWER_CTRL)); 439 ULPD_SHOW(ULPD_POWER_CTRL));
406 440
407 if (cpu_is_omap1510()) { 441 if (cpu_is_omap730()) {
442 my_buffer_offset += sprintf(my_base + my_buffer_offset,
443 "MPUI730_CTRL_REG 0x%-8x \n"
444 "MPUI730_DSP_STATUS_REG: 0x%-8x \n"
445 "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
446 "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
447 "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
448 "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
449 MPUI730_SHOW(MPUI_CTRL),
450 MPUI730_SHOW(MPUI_DSP_STATUS),
451 MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
452 MPUI730_SHOW(MPUI_DSP_API_CONFIG),
453 MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
454 MPUI730_SHOW(EMIFS_CONFIG));
455 } else if (cpu_is_omap1510()) {
408 my_buffer_offset += sprintf(my_base + my_buffer_offset, 456 my_buffer_offset += sprintf(my_base + my_buffer_offset,
409 "MPUI1510_CTRL_REG 0x%-8x \n" 457 "MPUI1510_CTRL_REG 0x%-8x \n"
410 "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" 458 "MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
@@ -553,7 +601,12 @@ static int __init omap_pm_init(void)
553 * These routines need to be in SRAM as that's the only 601 * These routines need to be in SRAM as that's the only
554 * memory the MPU can see when it wakes up. 602 * memory the MPU can see when it wakes up.
555 */ 603 */
556 if (cpu_is_omap1510()) { 604 if (cpu_is_omap730()) {
605 omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
606 omap730_idle_loop_suspend_sz);
607 omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
608 omap730_cpu_suspend_sz);
609 } else if (cpu_is_omap1510()) {
557 omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, 610 omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
558 omap1510_idle_loop_suspend_sz); 611 omap1510_idle_loop_suspend_sz);
559 omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, 612 omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
@@ -572,7 +625,11 @@ static int __init omap_pm_init(void)
572 625
573 pm_idle = omap_pm_idle; 626 pm_idle = omap_pm_idle;
574 627
575 setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); 628 if (cpu_is_omap730())
629 setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
630 else if (cpu_is_omap16xx())
631 setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
632
576#if 0 633#if 0
577 /* --- BEGIN BOARD-DEPENDENT CODE --- */ 634 /* --- BEGIN BOARD-DEPENDENT CODE --- */
578 /* Sleepx mask direction */ 635 /* Sleepx mask direction */
@@ -591,7 +648,9 @@ static int __init omap_pm_init(void)
591 omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); 648 omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
592 649
593 /* Configure IDLECT3 */ 650 /* Configure IDLECT3 */
594 if (cpu_is_omap16xx()) 651 if (cpu_is_omap730())
652 omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
653 else if (cpu_is_omap16xx())
595 omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); 654 omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
596 655
597 pm_set_ops(&omap_pm_ops); 656 pm_set_ops(&omap_pm_ops);
@@ -600,8 +659,10 @@ static int __init omap_pm_init(void)
600 omap_pm_init_proc(); 659 omap_pm_init_proc();
601#endif 660#endif
602 661
603 /* configure LOW_PWR pin */ 662 if (cpu_is_omap16xx()) {
604 omap_cfg_reg(T20_1610_LOW_PWR); 663 /* configure LOW_PWR pin */
664 omap_cfg_reg(T20_1610_LOW_PWR);
665 }
605 666
606 return 0; 667 return 0;
607} 668}
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S
index 9f745836f6aa..4cd7d292f854 100644
--- a/arch/arm/plat-omap/sleep.S
+++ b/arch/arm/plat-omap/sleep.S
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/arch/arm/plat-omap/sleep.S 2 * linux/arch/arm/plat-omap/sleep.S
3 * 3 *
4 * Low-level OMAP1510/1610 sleep/wakeUp support 4 * Low-level OMAP730/1510/1610 sleep/wakeUp support
5 * 5 *
6 * Initial SA1110 code: 6 * Initial SA1110 code:
7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> 7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
@@ -52,7 +52,57 @@
52 * processor specific functions here. 52 * processor specific functions here.
53 */ 53 */
54 54
55#ifdef CONFIG_ARCH_OMAP1510 55#if defined(CONFIG_ARCH_OMAP730)
56ENTRY(omap730_idle_loop_suspend)
57
58 stmfd sp!, {r0 - r12, lr} @ save registers on stack
59
60 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
61 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
62 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
63 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
64
65 @ turn off clock domains
66 @ get ARM_IDLECT2 into r2
67 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
68 mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
69 orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
70 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
71
72 @ request ARM idle
73 @ get ARM_IDLECT1 into r1
74 ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
75 orr r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff
76 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
77
78 mov r5, #IDLE_WAIT_CYCLES & 0xff
79 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
80l_730: subs r5, r5, #1
81 bne l_730
82/*
83 * Let's wait for the next clock tick to wake us up.
84 */
85 mov r0, #0
86 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
87/*
88 * omap730_idle_loop_suspend()'s resume point.
89 *
90 * It will just start executing here, so we'll restore stuff from the
91 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
92 */
93
94 @ restore ARM_IDLECT1 and ARM_IDLECT2 and return
95 @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
96 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
97 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
98
99 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
100
101ENTRY(omap730_idle_loop_suspend_sz)
102 .word . - omap730_idle_loop_suspend
103#endif /* CONFIG_ARCH_OMAP730 */
104
105#ifdef CONFIG_ARCH_OMAP15XX
56ENTRY(omap1510_idle_loop_suspend) 106ENTRY(omap1510_idle_loop_suspend)
57 107
58 stmfd sp!, {r0 - r12, lr} @ save registers on stack 108 stmfd sp!, {r0 - r12, lr} @ save registers on stack
@@ -100,7 +150,7 @@ l_1510: subs r5, r5, #1
100 150
101ENTRY(omap1510_idle_loop_suspend_sz) 151ENTRY(omap1510_idle_loop_suspend_sz)
102 .word . - omap1510_idle_loop_suspend 152 .word . - omap1510_idle_loop_suspend
103#endif /* CONFIG_ARCH_OMAP1510 */ 153#endif /* CONFIG_ARCH_OMAP15XX */
104 154
105#if defined(CONFIG_ARCH_OMAP16XX) 155#if defined(CONFIG_ARCH_OMAP16XX)
106ENTRY(omap1610_idle_loop_suspend) 156ENTRY(omap1610_idle_loop_suspend)
@@ -169,7 +219,86 @@ ENTRY(omap1610_idle_loop_suspend_sz)
169 * 219 *
170 */ 220 */
171 221
172#ifdef CONFIG_ARCH_OMAP1510 222#if defined(CONFIG_ARCH_OMAP730)
223ENTRY(omap730_cpu_suspend)
224
225 @ save registers on stack
226 stmfd sp!, {r0 - r12, lr}
227
228 @ Drain write cache
229 mov r4, #0
230 mcr p15, 0, r0, c7, c10, 4
231 nop
232
233 @ load base address of Traffic Controller
234 mov r6, #TCMIF_ASM_BASE & 0xff000000
235 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
236 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
237
238 @ prepare to put SDRAM into self-refresh manually
239 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
240 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
241 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
242 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
243
244 @ prepare to put EMIFS to Sleep
245 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
246 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
247 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
248
249 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
250 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
251 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
252 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
253
254 @ turn off clock domains
255 @ do not disable PERCK (0x04)
256 mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
257 orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
258 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
259
260 @ request ARM idle
261 mov r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff
262 orr r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00
263 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
264
265 @ disable instruction cache
266 mrc p15, 0, r9, c1, c0, 0
267 bic r2, r9, #0x1000
268 mcr p15, 0, r2, c1, c0, 0
269 nop
270
271/*
272 * Let's wait for the next wake up event to wake us up. r0 can't be
273 * used here because r0 holds ARM_IDLECT1
274 */
275 mov r2, #0
276 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
277/*
278 * omap730_cpu_suspend()'s resume point.
279 *
280 * It will just start executing here, so we'll restore stuff from the
281 * stack.
282 */
283 @ re-enable Icache
284 mcr p15, 0, r9, c1, c0, 0
285
286 @ reset the ARM_IDLECT1 and ARM_IDLECT2.
287 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
288 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
289
290 @ Restore EMIFF controls
291 str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
292 str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
293
294 @ restore regs and return
295 ldmfd sp!, {r0 - r12, pc}
296
297ENTRY(omap730_cpu_suspend_sz)
298 .word . - omap730_cpu_suspend
299#endif /* CONFIG_ARCH_OMAP730 */
300
301#ifdef CONFIG_ARCH_OMAP15XX
173ENTRY(omap1510_cpu_suspend) 302ENTRY(omap1510_cpu_suspend)
174 303
175 @ save registers on stack 304 @ save registers on stack
@@ -241,7 +370,7 @@ l_1510_2:
241 370
242ENTRY(omap1510_cpu_suspend_sz) 371ENTRY(omap1510_cpu_suspend_sz)
243 .word . - omap1510_cpu_suspend 372 .word . - omap1510_cpu_suspend
244#endif /* CONFIG_ARCH_OMAP1510 */ 373#endif /* CONFIG_ARCH_OMAP15XX */
245 374
246#if defined(CONFIG_ARCH_OMAP16XX) 375#if defined(CONFIG_ARCH_OMAP16XX)
247ENTRY(omap1610_cpu_suspend) 376ENTRY(omap1610_cpu_suspend)
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 7ad69f14a3e7..792f66375830 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -20,10 +20,13 @@
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
22 22
23#include "sram.h" 23#include <asm/arch/sram.h>
24
25#define OMAP1_SRAM_PA 0x20000000
26#define OMAP1_SRAM_VA 0xd0000000
27#define OMAP2_SRAM_PA 0x40200000
28#define OMAP2_SRAM_VA 0xd0000000
24 29
25#define OMAP1_SRAM_BASE 0xd0000000
26#define OMAP1_SRAM_START 0x20000000
27#define SRAM_BOOTLOADER_SZ 0x80 30#define SRAM_BOOTLOADER_SZ 0x80
28 31
29static unsigned long omap_sram_base; 32static unsigned long omap_sram_base;
@@ -31,37 +34,40 @@ static unsigned long omap_sram_size;
31static unsigned long omap_sram_ceil; 34static unsigned long omap_sram_ceil;
32 35
33/* 36/*
34 * The amount of SRAM depends on the core type: 37 * The amount of SRAM depends on the core type.
35 * 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K
36 * Note that we cannot try to test for SRAM here because writes 38 * Note that we cannot try to test for SRAM here because writes
37 * to secure SRAM will hang the system. Also the SRAM is not 39 * to secure SRAM will hang the system. Also the SRAM is not
38 * yet mapped at this point. 40 * yet mapped at this point.
39 */ 41 */
40void __init omap_detect_sram(void) 42void __init omap_detect_sram(void)
41{ 43{
42 omap_sram_base = OMAP1_SRAM_BASE; 44 if (!cpu_is_omap24xx())
45 omap_sram_base = OMAP1_SRAM_VA;
46 else
47 omap_sram_base = OMAP2_SRAM_VA;
43 48
44 if (cpu_is_omap730()) 49 if (cpu_is_omap730())
45 omap_sram_size = 0x32000; 50 omap_sram_size = 0x32000; /* 200K */
46 else if (cpu_is_omap1510()) 51 else if (cpu_is_omap15xx())
47 omap_sram_size = 0x80000; 52 omap_sram_size = 0x30000; /* 192K */
48 else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) 53 else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
49 omap_sram_size = 0x4000; 54 omap_sram_size = 0x4000; /* 16K */
50 else if (cpu_is_omap1611()) 55 else if (cpu_is_omap1611())
51 omap_sram_size = 0x3e800; 56 omap_sram_size = 0x3e800; /* 250K */
57 else if (cpu_is_omap2420())
58 omap_sram_size = 0xa0014; /* 640K */
52 else { 59 else {
53 printk(KERN_ERR "Could not detect SRAM size\n"); 60 printk(KERN_ERR "Could not detect SRAM size\n");
54 omap_sram_size = 0x4000; 61 omap_sram_size = 0x4000;
55 } 62 }
56 63
57 printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size);
58 omap_sram_ceil = omap_sram_base + omap_sram_size; 64 omap_sram_ceil = omap_sram_base + omap_sram_size;
59} 65}
60 66
61static struct map_desc omap_sram_io_desc[] __initdata = { 67static struct map_desc omap_sram_io_desc[] __initdata = {
62 { /* .length gets filled in at runtime */ 68 { /* .length gets filled in at runtime */
63 .virtual = OMAP1_SRAM_BASE, 69 .virtual = OMAP1_SRAM_VA,
64 .pfn = __phys_to_pfn(OMAP1_SRAM_START), 70 .pfn = __phys_to_pfn(OMAP1_SRAM_PA),
65 .type = MT_DEVICE 71 .type = MT_DEVICE
66 } 72 }
67}; 73};
@@ -76,10 +82,19 @@ void __init omap_map_sram(void)
76 if (omap_sram_size == 0) 82 if (omap_sram_size == 0)
77 return; 83 return;
78 84
85 if (cpu_is_omap24xx()) {
86 omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
87 omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA);
88 }
89
79 omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; 90 omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
80 omap_sram_io_desc[0].length *= PAGE_SIZE; 91 omap_sram_io_desc[0].length *= PAGE_SIZE;
81 iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); 92 iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
82 93
94 printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
95 omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
96 omap_sram_io_desc[0].length);
97
83 /* 98 /*
84 * Looks like we need to preserve some bootloader code at the 99 * Looks like we need to preserve some bootloader code at the
85 * beginning of SRAM for jumping to flash for reboot to work... 100 * beginning of SRAM for jumping to flash for reboot to work...
@@ -88,16 +103,6 @@ void __init omap_map_sram(void)
88 omap_sram_size - SRAM_BOOTLOADER_SZ); 103 omap_sram_size - SRAM_BOOTLOADER_SZ);
89} 104}
90 105
91static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL;
92
93void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
94{
95 if (_omap_sram_reprogram_clock == NULL)
96 panic("Cannot use SRAM");
97
98 return _omap_sram_reprogram_clock(dpllctl, ckctl);
99}
100
101void * omap_sram_push(void * start, unsigned long size) 106void * omap_sram_push(void * start, unsigned long size)
102{ 107{
103 if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { 108 if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
@@ -111,10 +116,94 @@ void * omap_sram_push(void * start, unsigned long size)
111 return (void *)omap_sram_ceil; 116 return (void *)omap_sram_ceil;
112} 117}
113 118
114void __init omap_sram_init(void) 119static void omap_sram_error(void)
120{
121 panic("Uninitialized SRAM function\n");
122}
123
124#ifdef CONFIG_ARCH_OMAP1
125
126static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
127
128void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
129{
130 if (!_omap_sram_reprogram_clock)
131 omap_sram_error();
132
133 return _omap_sram_reprogram_clock(dpllctl, ckctl);
134}
135
136int __init omap1_sram_init(void)
115{ 137{
116 omap_detect_sram();
117 omap_map_sram();
118 _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock, 138 _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
119 sram_reprogram_clock_sz); 139 sram_reprogram_clock_sz);
140
141 return 0;
142}
143
144#else
145#define omap1_sram_init() do {} while (0)
146#endif
147
148#ifdef CONFIG_ARCH_OMAP2
149
150static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
151 u32 base_cs, u32 force_unlock);
152
153void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
154 u32 base_cs, u32 force_unlock)
155{
156 if (!_omap2_sram_ddr_init)
157 omap_sram_error();
158
159 return _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
160 base_cs, force_unlock);
161}
162
163static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
164 u32 mem_type);
165
166void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
167{
168 if (!_omap2_sram_reprogram_sdrc)
169 omap_sram_error();
170
171 return _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
172}
173
174static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
175
176u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
177{
178 if (!_omap2_set_prcm)
179 omap_sram_error();
180
181 return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
182}
183
184int __init omap2_sram_init(void)
185{
186 _omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz);
187
188 _omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc,
189 sram_reprogram_sdrc_sz);
190 _omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz);
191
192 return 0;
193}
194#else
195#define omap2_sram_init() do {} while (0)
196#endif
197
198int __init omap_sram_init(void)
199{
200 omap_detect_sram();
201 omap_map_sram();
202
203 if (!cpu_is_omap24xx())
204 omap1_sram_init();
205 else
206 omap2_sram_init();
207
208 return 0;
120} 209}
diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h
deleted file mode 100644
index 71984efa6ae8..000000000000
--- a/arch/arm/plat-omap/sram.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * linux/arch/arm/plat-omap/sram.h
3 *
4 * Interface for functions that need to be run in internal SRAM
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ARCH_ARM_OMAP_SRAM_H
12#define __ARCH_ARM_OMAP_SRAM_H
13
14extern void * omap_sram_push(void * start, unsigned long size);
15extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
16
17/* Do not use these */
18extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
19extern unsigned long sram_reprogram_clock_sz;
20
21#endif
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 205e2d0b826d..00afc7a8c2ab 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -91,6 +91,8 @@ EXPORT_SYMBOL(otg_set_transceiver);
91 91
92/*-------------------------------------------------------------------------*/ 92/*-------------------------------------------------------------------------*/
93 93
94#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX)
95
94static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) 96static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
95{ 97{
96 u32 syscon1 = 0; 98 u32 syscon1 = 0;
@@ -271,6 +273,8 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
271 return syscon1 << 24; 273 return syscon1 << 24;
272} 274}
273 275
276#endif
277
274/*-------------------------------------------------------------------------*/ 278/*-------------------------------------------------------------------------*/
275 279
276#if defined(CONFIG_USB_GADGET_OMAP) || \ 280#if defined(CONFIG_USB_GADGET_OMAP) || \
@@ -494,7 +498,7 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
494 498
495/*-------------------------------------------------------------------------*/ 499/*-------------------------------------------------------------------------*/
496 500
497#ifdef CONFIG_ARCH_OMAP1510 501#ifdef CONFIG_ARCH_OMAP15XX
498 502
499#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL) 503#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL)
500#define DPLL_IOB (1 << 13) 504#define DPLL_IOB (1 << 13)
@@ -507,7 +511,6 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
507 511
508static void __init omap_1510_usb_init(struct omap_usb_config *config) 512static void __init omap_1510_usb_init(struct omap_usb_config *config)
509{ 513{
510 int status;
511 unsigned int val; 514 unsigned int val;
512 515
513 omap_usb0_init(config->pins[0], is_usb0_device(config)); 516 omap_usb0_init(config->pins[0], is_usb0_device(config));
@@ -539,6 +542,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
539 542
540#ifdef CONFIG_USB_GADGET_OMAP 543#ifdef CONFIG_USB_GADGET_OMAP
541 if (config->register_dev) { 544 if (config->register_dev) {
545 int status;
546
542 udc_device.dev.platform_data = config; 547 udc_device.dev.platform_data = config;
543 status = platform_device_register(&udc_device); 548 status = platform_device_register(&udc_device);
544 if (status) 549 if (status)
@@ -549,6 +554,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
549 554
550#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 555#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
551 if (config->register_host) { 556 if (config->register_host) {
557 int status;
558
552 ohci_device.dev.platform_data = config; 559 ohci_device.dev.platform_data = config;
553 status = platform_device_register(&ohci_device); 560 status = platform_device_register(&ohci_device);
554 if (status) 561 if (status)
diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
index 9eb9964d32a7..15833a0057dd 100644
--- a/arch/arm26/kernel/process.c
+++ b/arch/arm26/kernel/process.c
@@ -74,15 +74,13 @@ __setup("hlt", hlt_setup);
74void cpu_idle(void) 74void cpu_idle(void)
75{ 75{
76 /* endless idle loop with no priority at all */ 76 /* endless idle loop with no priority at all */
77 preempt_disable();
78 while (1) { 77 while (1) {
79 while (!need_resched()) { 78 while (!need_resched())
80 local_irq_disable(); 79 cpu_relax();
81 if (!need_resched() && !hlt_counter) 80 preempt_enable_no_resched();
82 local_irq_enable(); 81 schedule();
83 } 82 preempt_disable();
84 } 83 }
85 schedule();
86} 84}
87 85
88static char reboot_mode = 'h'; 86static char reboot_mode = 'h';
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 201f4c90d961..f2c55742e90c 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -19,7 +19,6 @@
19 */ 19 */
20 20
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/version.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/types.h> 24#include <linux/types.h>
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
index 094ff45ae85b..cac05a5e514c 100644
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -112,7 +112,6 @@
112#include <asm/rtc.h> 112#include <asm/rtc.h>
113 113
114#include <linux/config.h> 114#include <linux/config.h>
115#include <linux/version.h>
116 115
117#include <asm/arch/svinto.h> 116#include <asm/arch/svinto.h>
118#include <asm/fasttimer.h> 117#include <asm/fasttimer.h>
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/nandflash.c
index fc2a619b035d..93ddea4d9564 100644
--- a/arch/cris/arch-v32/drivers/nandflash.c
+++ b/arch/cris/arch-v32/drivers/nandflash.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
19#include <linux/init.h> 18#include <linux/init.h>
20#include <linux/module.h> 19#include <linux/module.h>
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index f894580b648b..d788bda3578c 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -18,7 +18,6 @@
18 */ 18 */
19 19
20#include <linux/config.h> 20#include <linux/config.h>
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/kernel.h> 22#include <linux/kernel.h>
24#include <linux/types.h> 23#include <linux/types.h>
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 957f551ba5ce..13867f4fad16 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -161,6 +161,7 @@ void __init smp_callin(void)
161 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); 161 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
162 unmask_irq(IPI_INTR_VECT); 162 unmask_irq(IPI_INTR_VECT);
163 unmask_irq(TIMER_INTR_VECT); 163 unmask_irq(TIMER_INTR_VECT);
164 preempt_disable();
164 local_irq_enable(); 165 local_irq_enable();
165 166
166 cpu_set(cpu, cpu_online_map); 167 cpu_set(cpu, cpu_online_map);
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
index 949a0e40e03c..7c80afb10460 100644
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -218,7 +218,9 @@ void cpu_idle (void)
218 idle = default_idle; 218 idle = default_idle;
219 idle(); 219 idle();
220 } 220 }
221 preempt_enable_no_resched();
221 schedule(); 222 schedule();
223 preempt_disable();
222 } 224 }
223} 225}
224 226
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 3001b82b1514..54a452136f00 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -77,16 +77,20 @@ void (*idle)(void) = core_sleep_idle;
77 */ 77 */
78void cpu_idle(void) 78void cpu_idle(void)
79{ 79{
80 int cpu = smp_processor_id();
81
80 /* endless idle loop with no priority at all */ 82 /* endless idle loop with no priority at all */
81 while (1) { 83 while (1) {
82 while (!need_resched()) { 84 while (!need_resched()) {
83 irq_stat[smp_processor_id()].idle_timestamp = jiffies; 85 irq_stat[cpu].idle_timestamp = jiffies;
84 86
85 if (!frv_dma_inprogress && idle) 87 if (!frv_dma_inprogress && idle)
86 idle(); 88 idle();
87 } 89 }
88 90
91 preempt_enable_no_resched();
89 schedule(); 92 schedule();
93 preempt_disable();
90 } 94 }
91} 95}
92 96
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 27f1fce64ce4..fe21adf3e75e 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -53,22 +53,18 @@ asmlinkage void ret_from_fork(void);
53#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM) 53#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
54void default_idle(void) 54void default_idle(void)
55{ 55{
56 while(1) { 56 local_irq_disable();
57 if (!need_resched()) { 57 if (!need_resched()) {
58 local_irq_enable(); 58 local_irq_enable();
59 __asm__("sleep"); 59 /* XXX: race here! What if need_resched() gets set now? */
60 local_irq_disable(); 60 __asm__("sleep");
61 } 61 } else
62 schedule(); 62 local_irq_enable();
63 }
64} 63}
65#else 64#else
66void default_idle(void) 65void default_idle(void)
67{ 66{
68 while(1) { 67 cpu_relax();
69 if (need_resched())
70 schedule();
71 }
72} 68}
73#endif 69#endif
74void (*idle)(void) = default_idle; 70void (*idle)(void) = default_idle;
@@ -81,7 +77,13 @@ void (*idle)(void) = default_idle;
81 */ 77 */
82void cpu_idle(void) 78void cpu_idle(void)
83{ 79{
84 idle(); 80 while (1) {
81 while (!need_resched())
82 idle();
83 preempt_enable_no_resched();
84 schedule();
85 preempt_disable();
86 }
85} 87}
86 88
87void machine_restart(char * __unused) 89void machine_restart(char * __unused)
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 86e80c551478..003548b8735f 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -769,8 +769,26 @@ static int set_system_power_state(u_short state)
769static int apm_do_idle(void) 769static int apm_do_idle(void)
770{ 770{
771 u32 eax; 771 u32 eax;
772 u8 ret = 0;
773 int idled = 0;
774 int polling;
775
776 polling = test_thread_flag(TIF_POLLING_NRFLAG);
777 if (polling) {
778 clear_thread_flag(TIF_POLLING_NRFLAG);
779 smp_mb__after_clear_bit();
780 }
781 if (!need_resched()) {
782 idled = 1;
783 ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
784 }
785 if (polling)
786 set_thread_flag(TIF_POLLING_NRFLAG);
787
788 if (!idled)
789 return 0;
772 790
773 if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) { 791 if (ret) {
774 static unsigned long t; 792 static unsigned long t;
775 793
776 /* This always fails on some SMP boards running UP kernels. 794 /* This always fails on some SMP boards running UP kernels.
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 7a14fdfd3af9..1cb261f225d5 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -99,14 +99,22 @@ EXPORT_SYMBOL(enable_hlt);
99 */ 99 */
100void default_idle(void) 100void default_idle(void)
101{ 101{
102 local_irq_enable();
103
102 if (!hlt_counter && boot_cpu_data.hlt_works_ok) { 104 if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
103 local_irq_disable(); 105 clear_thread_flag(TIF_POLLING_NRFLAG);
104 if (!need_resched()) 106 smp_mb__after_clear_bit();
105 safe_halt(); 107 while (!need_resched()) {
106 else 108 local_irq_disable();
107 local_irq_enable(); 109 if (!need_resched())
110 safe_halt();
111 else
112 local_irq_enable();
113 }
114 set_thread_flag(TIF_POLLING_NRFLAG);
108 } else { 115 } else {
109 cpu_relax(); 116 while (!need_resched())
117 cpu_relax();
110 } 118 }
111} 119}
112#ifdef CONFIG_APM_MODULE 120#ifdef CONFIG_APM_MODULE
@@ -120,29 +128,14 @@ EXPORT_SYMBOL(default_idle);
120 */ 128 */
121static void poll_idle (void) 129static void poll_idle (void)
122{ 130{
123 int oldval;
124
125 local_irq_enable(); 131 local_irq_enable();
126 132
127 /* 133 asm volatile(
128 * Deal with another CPU just having chosen a thread to 134 "2:"
129 * run here: 135 "testl %0, %1;"
130 */ 136 "rep; nop;"
131 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 137 "je 2b;"
132 138 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
133 if (!oldval) {
134 set_thread_flag(TIF_POLLING_NRFLAG);
135 asm volatile(
136 "2:"
137 "testl %0, %1;"
138 "rep; nop;"
139 "je 2b;"
140 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
141
142 clear_thread_flag(TIF_POLLING_NRFLAG);
143 } else {
144 set_need_resched();
145 }
146} 139}
147 140
148#ifdef CONFIG_HOTPLUG_CPU 141#ifdef CONFIG_HOTPLUG_CPU
@@ -179,7 +172,9 @@ static inline void play_dead(void)
179 */ 172 */
180void cpu_idle(void) 173void cpu_idle(void)
181{ 174{
182 int cpu = raw_smp_processor_id(); 175 int cpu = smp_processor_id();
176
177 set_thread_flag(TIF_POLLING_NRFLAG);
183 178
184 /* endless idle loop with no priority at all */ 179 /* endless idle loop with no priority at all */
185 while (1) { 180 while (1) {
@@ -201,7 +196,9 @@ void cpu_idle(void)
201 __get_cpu_var(irq_stat).idle_timestamp = jiffies; 196 __get_cpu_var(irq_stat).idle_timestamp = jiffies;
202 idle(); 197 idle();
203 } 198 }
199 preempt_enable_no_resched();
204 schedule(); 200 schedule();
201 preempt_disable();
205 } 202 }
206} 203}
207 204
@@ -244,15 +241,12 @@ static void mwait_idle(void)
244{ 241{
245 local_irq_enable(); 242 local_irq_enable();
246 243
247 if (!need_resched()) { 244 while (!need_resched()) {
248 set_thread_flag(TIF_POLLING_NRFLAG); 245 __monitor((void *)&current_thread_info()->flags, 0, 0);
249 do { 246 smp_mb();
250 __monitor((void *)&current_thread_info()->flags, 0, 0); 247 if (need_resched())
251 if (need_resched()) 248 break;
252 break; 249 __mwait(0, 0);
253 __mwait(0, 0);
254 } while (!need_resched());
255 clear_thread_flag(TIF_POLLING_NRFLAG);
256 } 250 }
257} 251}
258 252
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index b48ac635f3c1..fdfcb0cba9b4 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -129,9 +129,7 @@ struct drive_info_struct { char dummy[32]; } drive_info;
129EXPORT_SYMBOL(drive_info); 129EXPORT_SYMBOL(drive_info);
130#endif 130#endif
131struct screen_info screen_info; 131struct screen_info screen_info;
132#ifdef CONFIG_VT
133EXPORT_SYMBOL(screen_info); 132EXPORT_SYMBOL(screen_info);
134#endif
135struct apm_info apm_info; 133struct apm_info apm_info;
136EXPORT_SYMBOL(apm_info); 134EXPORT_SYMBOL(apm_info);
137struct sys_desc_table_struct { 135struct sys_desc_table_struct {
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 47ec76794d02..bc5a9d97466b 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -485,6 +485,7 @@ static void __devinit start_secondary(void *unused)
485 * things done here to the most necessary things. 485 * things done here to the most necessary things.
486 */ 486 */
487 cpu_init(); 487 cpu_init();
488 preempt_disable();
488 smp_callin(); 489 smp_callin();
489 while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) 490 while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
490 rep_nop(); 491 rep_nop();
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 3984226a8b98..eeb1b1f2d548 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -433,9 +433,8 @@ static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
433 return; /* only applies to certain Toshibas (so far) */ 433 return; /* only applies to certain Toshibas (so far) */
434 434
435 /* Restore config space on Toshiba laptops */ 435 /* Restore config space on Toshiba laptops */
436 mdelay(10);
437 pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size); 436 pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
438 pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq); 437 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, (u8 *)&dev->irq);
439 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 438 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
440 pci_resource_start(dev, 0)); 439 pci_resource_start(dev, 0));
441 pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 440 pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
index 164b211f4174..88739394f6df 100644
--- a/arch/ia64/ia32/ia32_ioctl.c
+++ b/arch/ia64/ia32/ia32_ioctl.c
@@ -29,10 +29,8 @@
29#define CODE 29#define CODE
30#include "compat_ioctl.c" 30#include "compat_ioctl.c"
31 31
32typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
33
34#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) 32#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
35#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, 33#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
36#define IOCTL_TABLE_START \ 34#define IOCTL_TABLE_START \
37 struct ioctl_trans ioctl_start[] = { 35 struct ioctl_trans ioctl_start[] = {
38#define IOCTL_TABLE_END \ 36#define IOCTL_TABLE_END \
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index f72ea6aebcb1..a3aa45cbcfa0 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -987,7 +987,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
987 break; 987 break;
988 } 988 }
989 989
990 if ((res = kcalloc(1, sizeof(struct resource), GFP_KERNEL)) == NULL) { 990 if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
991 printk(KERN_ERR "failed to alocate resource for iomem\n"); 991 printk(KERN_ERR "failed to alocate resource for iomem\n");
992 return; 992 return;
993 } 993 }
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 96736a119c91..801eeaeaf3de 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -347,7 +347,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
347 ((struct fnptr *)kretprobe_trampoline)->ip; 347 ((struct fnptr *)kretprobe_trampoline)->ip;
348 348
349 spin_lock_irqsave(&kretprobe_lock, flags); 349 spin_lock_irqsave(&kretprobe_lock, flags);
350 head = kretprobe_inst_table_head(current); 350 head = kretprobe_inst_table_head(current);
351 351
352 /* 352 /*
353 * It is possible to have multiple instances associated with a given 353 * It is possible to have multiple instances associated with a given
@@ -363,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
363 * kretprobe_trampoline 363 * kretprobe_trampoline
364 */ 364 */
365 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { 365 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
366 if (ri->task != current) 366 if (ri->task != current)
367 /* another task is sharing our hash bucket */ 367 /* another task is sharing our hash bucket */
368 continue; 368 continue;
369 369
370 if (ri->rp && ri->rp->handler) 370 if (ri->rp && ri->rp->handler)
371 ri->rp->handler(ri, regs); 371 ri->rp->handler(ri, regs);
@@ -394,7 +394,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
394 * kprobe_handler() that we don't want the post_handler 394 * kprobe_handler() that we don't want the post_handler
395 * to run (and have re-enabled preemption) 395 * to run (and have re-enabled preemption)
396 */ 396 */
397 return 1; 397 return 1;
398} 398}
399 399
400/* Called with kretprobe_lock held */ 400/* Called with kretprobe_lock held */
@@ -739,12 +739,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
739 739
740 switch(val) { 740 switch(val) {
741 case DIE_BREAK: 741 case DIE_BREAK:
742 if (pre_kprobes_handler(args)) 742 /* err is break number from ia64_bad_break() */
743 ret = NOTIFY_STOP; 743 if (args->err == 0x80200 || args->err == 0x80300)
744 if (pre_kprobes_handler(args))
745 ret = NOTIFY_STOP;
744 break; 746 break;
745 case DIE_SS: 747 case DIE_FAULT:
746 if (post_kprobes_handler(args->regs)) 748 /* err is vector number from ia64_fault() */
747 ret = NOTIFY_STOP; 749 if (args->err == 36)
750 if (post_kprobes_handler(args->regs))
751 ret = NOTIFY_STOP;
748 break; 752 break;
749 case DIE_PAGE_FAULT: 753 case DIE_PAGE_FAULT:
750 /* kprobe_running() needs smp_processor_id() */ 754 /* kprobe_running() needs smp_processor_id() */
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 52c47da17246..355af15287c7 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -51,6 +51,9 @@
51 * 51 *
52 * 2005-08-12 Keith Owens <kaos@sgi.com> 52 * 2005-08-12 Keith Owens <kaos@sgi.com>
53 * Convert MCA/INIT handlers to use per event stacks and SAL/OS state. 53 * Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
54 *
55 * 2005-10-07 Keith Owens <kaos@sgi.com>
56 * Add notify_die() hooks.
54 */ 57 */
55#include <linux/config.h> 58#include <linux/config.h>
56#include <linux/types.h> 59#include <linux/types.h>
@@ -58,7 +61,6 @@
58#include <linux/sched.h> 61#include <linux/sched.h>
59#include <linux/interrupt.h> 62#include <linux/interrupt.h>
60#include <linux/irq.h> 63#include <linux/irq.h>
61#include <linux/kallsyms.h>
62#include <linux/smp_lock.h> 64#include <linux/smp_lock.h>
63#include <linux/bootmem.h> 65#include <linux/bootmem.h>
64#include <linux/acpi.h> 66#include <linux/acpi.h>
@@ -69,6 +71,7 @@
69#include <linux/workqueue.h> 71#include <linux/workqueue.h>
70 72
71#include <asm/delay.h> 73#include <asm/delay.h>
74#include <asm/kdebug.h>
72#include <asm/machvec.h> 75#include <asm/machvec.h>
73#include <asm/meminit.h> 76#include <asm/meminit.h>
74#include <asm/page.h> 77#include <asm/page.h>
@@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
132 135
133static int mca_init; 136static int mca_init;
134 137
138
139static void inline
140ia64_mca_spin(const char *func)
141{
142 printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func);
143 while (1)
144 cpu_relax();
145}
135/* 146/*
136 * IA64_MCA log support 147 * IA64_MCA log support
137 */ 148 */
@@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void)
526 * Outputs : None 537 * Outputs : None
527 */ 538 */
528static irqreturn_t 539static irqreturn_t
529ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) 540ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
530{ 541{
531 unsigned long flags; 542 unsigned long flags;
532 int cpu = smp_processor_id(); 543 int cpu = smp_processor_id();
533 544
534 /* Mask all interrupts */ 545 /* Mask all interrupts */
535 local_irq_save(flags); 546 local_irq_save(flags);
547 if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0)
548 == NOTIFY_STOP)
549 ia64_mca_spin(__FUNCTION__);
536 550
537 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; 551 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
538 /* Register with the SAL monarch that the slave has 552 /* Register with the SAL monarch that the slave has
@@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
540 */ 554 */
541 ia64_sal_mc_rendez(); 555 ia64_sal_mc_rendez();
542 556
557 if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0)
558 == NOTIFY_STOP)
559 ia64_mca_spin(__FUNCTION__);
560
543 /* Wait for the monarch cpu to exit. */ 561 /* Wait for the monarch cpu to exit. */
544 while (monarch_cpu != -1) 562 while (monarch_cpu != -1)
545 cpu_relax(); /* spin until monarch leaves */ 563 cpu_relax(); /* spin until monarch leaves */
546 564
565 if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0)
566 == NOTIFY_STOP)
567 ia64_mca_spin(__FUNCTION__);
568
547 /* Enable all interrupts */ 569 /* Enable all interrupts */
548 local_irq_restore(flags); 570 local_irq_restore(flags);
549 return IRQ_HANDLED; 571 return IRQ_HANDLED;
@@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
933 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ 955 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
934 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); 956 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
935 monarch_cpu = cpu; 957 monarch_cpu = cpu;
958 if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0)
959 == NOTIFY_STOP)
960 ia64_mca_spin(__FUNCTION__);
936 ia64_wait_for_slaves(cpu); 961 ia64_wait_for_slaves(cpu);
937 962
938 /* Wakeup all the processors which are spinning in the rendezvous loop. 963 /* Wakeup all the processors which are spinning in the rendezvous loop.
@@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
942 * spinning in SAL does not work. 967 * spinning in SAL does not work.
943 */ 968 */
944 ia64_mca_wakeup_all(); 969 ia64_mca_wakeup_all();
970 if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0)
971 == NOTIFY_STOP)
972 ia64_mca_spin(__FUNCTION__);
945 973
946 /* Get the MCA error record and log it */ 974 /* Get the MCA error record and log it */
947 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); 975 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
@@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
960 ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); 988 ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
961 sos->os_status = IA64_MCA_CORRECTED; 989 sos->os_status = IA64_MCA_CORRECTED;
962 } 990 }
991 if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover)
992 == NOTIFY_STOP)
993 ia64_mca_spin(__FUNCTION__);
963 994
964 set_curr_task(cpu, previous_current); 995 set_curr_task(cpu, previous_current);
965 monarch_cpu = -1; 996 monarch_cpu = -1;
@@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy)
1188 1219
1189#endif /* CONFIG_ACPI */ 1220#endif /* CONFIG_ACPI */
1190 1221
1222static int
1223default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
1224{
1225 int c;
1226 struct task_struct *g, *t;
1227 if (val != DIE_INIT_MONARCH_PROCESS)
1228 return NOTIFY_DONE;
1229 printk(KERN_ERR "Processes interrupted by INIT -");
1230 for_each_online_cpu(c) {
1231 struct ia64_sal_os_state *s;
1232 t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
1233 s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
1234 g = s->prev_task;
1235 if (g) {
1236 if (g->pid)
1237 printk(" %d", g->pid);
1238 else
1239 printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
1240 }
1241 }
1242 printk("\n\n");
1243 if (read_trylock(&tasklist_lock)) {
1244 do_each_thread (g, t) {
1245 printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
1246 show_stack(t, NULL);
1247 } while_each_thread (g, t);
1248 read_unlock(&tasklist_lock);
1249 }
1250 return NOTIFY_DONE;
1251}
1252
1191/* 1253/*
1192 * C portion of the OS INIT handler 1254 * C portion of the OS INIT handler
1193 * 1255 *
@@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1212 static atomic_t slaves; 1274 static atomic_t slaves;
1213 static atomic_t monarchs; 1275 static atomic_t monarchs;
1214 task_t *previous_current; 1276 task_t *previous_current;
1215 int cpu = smp_processor_id(), c; 1277 int cpu = smp_processor_id();
1216 struct task_struct *g, *t;
1217 1278
1218 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ 1279 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
1219 console_loglevel = 15; /* make sure printks make it to console */ 1280 console_loglevel = 15; /* make sure printks make it to console */
@@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1253 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; 1314 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
1254 while (monarch_cpu == -1) 1315 while (monarch_cpu == -1)
1255 cpu_relax(); /* spin until monarch enters */ 1316 cpu_relax(); /* spin until monarch enters */
1317 if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0)
1318 == NOTIFY_STOP)
1319 ia64_mca_spin(__FUNCTION__);
1320 if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0)
1321 == NOTIFY_STOP)
1322 ia64_mca_spin(__FUNCTION__);
1256 while (monarch_cpu != -1) 1323 while (monarch_cpu != -1)
1257 cpu_relax(); /* spin until monarch leaves */ 1324 cpu_relax(); /* spin until monarch leaves */
1325 if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0)
1326 == NOTIFY_STOP)
1327 ia64_mca_spin(__FUNCTION__);
1258 printk("Slave on cpu %d returning to normal service.\n", cpu); 1328 printk("Slave on cpu %d returning to normal service.\n", cpu);
1259 set_curr_task(cpu, previous_current); 1329 set_curr_task(cpu, previous_current);
1260 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; 1330 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
@@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1263 } 1333 }
1264 1334
1265 monarch_cpu = cpu; 1335 monarch_cpu = cpu;
1336 if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0)
1337 == NOTIFY_STOP)
1338 ia64_mca_spin(__FUNCTION__);
1266 1339
1267 /* 1340 /*
1268 * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be 1341 * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
@@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1273 printk("Delaying for 5 seconds...\n"); 1346 printk("Delaying for 5 seconds...\n");
1274 udelay(5*1000000); 1347 udelay(5*1000000);
1275 ia64_wait_for_slaves(cpu); 1348 ia64_wait_for_slaves(cpu);
1276 printk(KERN_ERR "Processes interrupted by INIT -"); 1349 /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
1277 for_each_online_cpu(c) { 1350 * to default_monarch_init_process() above and just print all the
1278 struct ia64_sal_os_state *s; 1351 * tasks.
1279 t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); 1352 */
1280 s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); 1353 if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0)
1281 g = s->prev_task; 1354 == NOTIFY_STOP)
1282 if (g) { 1355 ia64_mca_spin(__FUNCTION__);
1283 if (g->pid) 1356 if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0)
1284 printk(" %d", g->pid); 1357 == NOTIFY_STOP)
1285 else 1358 ia64_mca_spin(__FUNCTION__);
1286 printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
1287 }
1288 }
1289 printk("\n\n");
1290 if (read_trylock(&tasklist_lock)) {
1291 do_each_thread (g, t) {
1292 printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
1293 show_stack(t, NULL);
1294 } while_each_thread (g, t);
1295 read_unlock(&tasklist_lock);
1296 }
1297 printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); 1359 printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
1298 atomic_dec(&monarchs); 1360 atomic_dec(&monarchs);
1299 set_curr_task(cpu, previous_current); 1361 set_curr_task(cpu, previous_current);
@@ -1462,6 +1524,10 @@ ia64_mca_init(void)
1462 s64 rc; 1524 s64 rc;
1463 struct ia64_sal_retval isrv; 1525 struct ia64_sal_retval isrv;
1464 u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */ 1526 u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */
1527 static struct notifier_block default_init_monarch_nb = {
1528 .notifier_call = default_monarch_init_process,
1529 .priority = 0/* we need to notified last */
1530 };
1465 1531
1466 IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); 1532 IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
1467 1533
@@ -1555,6 +1621,10 @@ ia64_mca_init(void)
1555 "(status %ld)\n", rc); 1621 "(status %ld)\n", rc);
1556 return; 1622 return;
1557 } 1623 }
1624 if (register_die_notifier(&default_init_monarch_nb)) {
1625 printk(KERN_ERR "Failed to register default monarch INIT process\n");
1626 return;
1627 }
1558 1628
1559 IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); 1629 IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
1560 1630
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index f081c60ab206..3492e3211a44 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -88,7 +88,7 @@ mca_page_isolate(unsigned long paddr)
88 if (!ia64_phys_addr_valid(paddr)) 88 if (!ia64_phys_addr_valid(paddr))
89 return ISOLATE_NONE; 89 return ISOLATE_NONE;
90 90
91 if (!pfn_valid(paddr)) 91 if (!pfn_valid(paddr >> PAGE_SHIFT))
92 return ISOLATE_NONE; 92 return ISOLATE_NONE;
93 93
94 /* convert physical address to physical page number */ 94 /* convert physical address to physical page number */
@@ -108,6 +108,7 @@ mca_page_isolate(unsigned long paddr)
108 return ISOLATE_NG; 108 return ISOLATE_NG;
109 109
110 /* add attribute 'Reserved' and register the page */ 110 /* add attribute 'Reserved' and register the page */
111 get_page(p);
111 SetPageReserved(p); 112 SetPageReserved(p);
112 page_isolate[num_page_isolate++] = p; 113 page_isolate[num_page_isolate++] = p;
113 114
@@ -546,9 +547,20 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
546 (pal_processor_state_info_t*)peidx_psp(peidx); 547 (pal_processor_state_info_t*)peidx_psp(peidx);
547 548
548 /* 549 /*
549 * We cannot recover errors with other than bus_check. 550 * Processor recovery status must key off of the PAL recovery
551 * status in the Processor State Parameter.
550 */ 552 */
551 if (psp->cc || psp->rc || psp->uc) 553
554 /*
555 * The machine check is corrected.
556 */
557 if (psp->cm == 1)
558 return 1;
559
560 /*
561 * The error was not contained. Software must be reset.
562 */
563 if (psp->us || psp->ci == 0)
552 return 0; 564 return 0;
553 565
554 /* 566 /*
@@ -569,8 +581,6 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
569 return 0; 581 return 0;
570 if (pbci->eb && pbci->bsi > 0) 582 if (pbci->eb && pbci->bsi > 0)
571 return 0; 583 return 0;
572 if (psp->ci == 0)
573 return 0;
574 584
575 /* 585 /*
576 * This is a local MCA and estimated as recoverble external bus error. 586 * This is a local MCA and estimated as recoverble external bus error.
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 051e050359e4..e92ea64d8040 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -4,6 +4,9 @@
4 * Copyright (C) 1998-2003 Hewlett-Packard Co 4 * Copyright (C) 1998-2003 Hewlett-Packard Co
5 * David Mosberger-Tang <davidm@hpl.hp.com> 5 * David Mosberger-Tang <davidm@hpl.hp.com>
6 * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support 6 * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
7 *
8 * 2005-10-07 Keith Owens <kaos@sgi.com>
9 * Add notify_die() hooks.
7 */ 10 */
8#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ 11#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
9#include <linux/config.h> 12#include <linux/config.h>
@@ -34,6 +37,7 @@
34#include <asm/elf.h> 37#include <asm/elf.h>
35#include <asm/ia32.h> 38#include <asm/ia32.h>
36#include <asm/irq.h> 39#include <asm/irq.h>
40#include <asm/kdebug.h>
37#include <asm/pgalloc.h> 41#include <asm/pgalloc.h>
38#include <asm/processor.h> 42#include <asm/processor.h>
39#include <asm/sal.h> 43#include <asm/sal.h>
@@ -197,11 +201,15 @@ void
197default_idle (void) 201default_idle (void)
198{ 202{
199 local_irq_enable(); 203 local_irq_enable();
200 while (!need_resched()) 204 while (!need_resched()) {
201 if (can_do_pal_halt) 205 if (can_do_pal_halt) {
202 safe_halt(); 206 local_irq_disable();
203 else 207 if (!need_resched())
208 safe_halt();
209 local_irq_enable();
210 } else
204 cpu_relax(); 211 cpu_relax();
212 }
205} 213}
206 214
207#ifdef CONFIG_HOTPLUG_CPU 215#ifdef CONFIG_HOTPLUG_CPU
@@ -263,16 +271,16 @@ void __attribute__((noreturn))
263cpu_idle (void) 271cpu_idle (void)
264{ 272{
265 void (*mark_idle)(int) = ia64_mark_idle; 273 void (*mark_idle)(int) = ia64_mark_idle;
274 int cpu = smp_processor_id();
275 set_thread_flag(TIF_POLLING_NRFLAG);
266 276
267 /* endless idle loop with no priority at all */ 277 /* endless idle loop with no priority at all */
268 while (1) { 278 while (1) {
279 if (!need_resched()) {
280 void (*idle)(void);
269#ifdef CONFIG_SMP 281#ifdef CONFIG_SMP
270 if (!need_resched())
271 min_xtp(); 282 min_xtp();
272#endif 283#endif
273 while (!need_resched()) {
274 void (*idle)(void);
275
276 if (__get_cpu_var(cpu_idle_state)) 284 if (__get_cpu_var(cpu_idle_state))
277 __get_cpu_var(cpu_idle_state) = 0; 285 __get_cpu_var(cpu_idle_state) = 0;
278 286
@@ -284,17 +292,17 @@ cpu_idle (void)
284 if (!idle) 292 if (!idle)
285 idle = default_idle; 293 idle = default_idle;
286 (*idle)(); 294 (*idle)();
287 } 295 if (mark_idle)
288 296 (*mark_idle)(0);
289 if (mark_idle)
290 (*mark_idle)(0);
291
292#ifdef CONFIG_SMP 297#ifdef CONFIG_SMP
293 normal_xtp(); 298 normal_xtp();
294#endif 299#endif
300 }
301 preempt_enable_no_resched();
295 schedule(); 302 schedule();
303 preempt_disable();
296 check_pgt_cache(); 304 check_pgt_cache();
297 if (cpu_is_offline(smp_processor_id())) 305 if (cpu_is_offline(cpu))
298 play_dead(); 306 play_dead();
299 } 307 }
300} 308}
@@ -804,12 +812,14 @@ cpu_halt (void)
804void 812void
805machine_restart (char *restart_cmd) 813machine_restart (char *restart_cmd)
806{ 814{
815 (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
807 (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); 816 (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
808} 817}
809 818
810void 819void
811machine_halt (void) 820machine_halt (void)
812{ 821{
822 (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
813 cpu_halt(); 823 cpu_halt();
814} 824}
815 825
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 3af6de36a482..5add0bcf87a7 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -461,6 +461,7 @@ setup_arch (char **cmdline_p)
461#endif 461#endif
462 462
463 cpu_init(); /* initialize the bootstrap CPU */ 463 cpu_init(); /* initialize the bootstrap CPU */
464 mmu_context_init(); /* initialize context_id bitmap */
464 465
465#ifdef CONFIG_ACPI 466#ifdef CONFIG_ACPI
466 acpi_boot_init(); 467 acpi_boot_init();
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 774f34b675cf..58ce07efc56e 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
387 struct sigscratch *scr) 387 struct sigscratch *scr)
388{ 388{
389 extern char __kernel_sigtramp[]; 389 extern char __kernel_sigtramp[];
390 unsigned long tramp_addr, new_rbs = 0; 390 unsigned long tramp_addr, new_rbs = 0, new_sp;
391 struct sigframe __user *frame; 391 struct sigframe __user *frame;
392 long err; 392 long err;
393 393
394 frame = (void __user *) scr->pt.r12; 394 new_sp = scr->pt.r12;
395 tramp_addr = (unsigned long) __kernel_sigtramp; 395 tramp_addr = (unsigned long) __kernel_sigtramp;
396 if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) { 396 if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
397 frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size) 397 new_sp = current->sas_ss_sp + current->sas_ss_size;
398 & ~(STACK_ALIGN - 1));
399 /* 398 /*
400 * We need to check for the register stack being on the signal stack 399 * We need to check for the register stack being on the signal stack
401 * separately, because it's switched separately (memory stack is switched 400 * separately, because it's switched separately (memory stack is switched
@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
404 if (!rbs_on_sig_stack(scr->pt.ar_bspstore)) 403 if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
405 new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1); 404 new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
406 } 405 }
407 frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1)); 406 frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
408 407
409 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 408 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
410 return force_sigsegv_info(sig, frame); 409 return force_sigsegv_info(sig, frame);
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 400a48987124..8f44e7d2df66 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -399,6 +399,7 @@ start_secondary (void *unused)
399 Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id()); 399 Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id());
400 efi_map_pal_code(); 400 efi_map_pal_code();
401 cpu_init(); 401 cpu_init();
402 preempt_disable();
402 smp_callin(); 403 smp_callin();
403 404
404 cpu_idle(); 405 cpu_idle();
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index f970359e7edf..fba5fdd1f968 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface;
30EXPORT_SYMBOL(fpswa_interface); 30EXPORT_SYMBOL(fpswa_interface);
31 31
32struct notifier_block *ia64die_chain; 32struct notifier_block *ia64die_chain;
33static DEFINE_SPINLOCK(die_notifier_lock);
34 33
35int register_die_notifier(struct notifier_block *nb) 34int
35register_die_notifier(struct notifier_block *nb)
36{ 36{
37 int err = 0; 37 return notifier_chain_register(&ia64die_chain, nb);
38 unsigned long flags;
39 spin_lock_irqsave(&die_notifier_lock, flags);
40 err = notifier_chain_register(&ia64die_chain, nb);
41 spin_unlock_irqrestore(&die_notifier_lock, flags);
42 return err;
43} 38}
39EXPORT_SYMBOL_GPL(register_die_notifier);
40
41int
42unregister_die_notifier(struct notifier_block *nb)
43{
44 return notifier_chain_unregister(&ia64die_chain, nb);
45}
46EXPORT_SYMBOL_GPL(unregister_die_notifier);
44 47
45void __init 48void __init
46trap_init (void) 49trap_init (void)
@@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err)
105 if (++die.lock_owner_depth < 3) { 108 if (++die.lock_owner_depth < 3) {
106 printk("%s[%d]: %s %ld [%d]\n", 109 printk("%s[%d]: %s %ld [%d]\n",
107 current->comm, current->pid, str, err, ++die_counter); 110 current->comm, current->pid, str, err, ++die_counter);
111 (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
108 show_regs(regs); 112 show_regs(regs);
109 } else 113 } else
110 printk(KERN_ERR "Recursive die() failure, output suppressed\n"); 114 printk(KERN_ERR "Recursive die() failure, output suppressed\n");
@@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
155 switch (break_num) { 159 switch (break_num) {
156 case 0: /* unknown error (used by GCC for __builtin_abort()) */ 160 case 0: /* unknown error (used by GCC for __builtin_abort()) */
157 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) 161 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
158 == NOTIFY_STOP) { 162 == NOTIFY_STOP)
159 return; 163 return;
160 }
161 die_if_kernel("bugcheck!", regs, break_num); 164 die_if_kernel("bugcheck!", regs, break_num);
162 sig = SIGILL; code = ILL_ILLOPC; 165 sig = SIGILL; code = ILL_ILLOPC;
163 break; 166 break;
@@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
210 sig = SIGILL; code = __ILL_BNDMOD; 213 sig = SIGILL; code = __ILL_BNDMOD;
211 break; 214 break;
212 215
213 case 0x80200:
214 case 0x80300:
215 if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
216 == NOTIFY_STOP) {
217 return;
218 }
219 sig = SIGTRAP; code = TRAP_BRKPT;
220 break;
221
222 default: 216 default:
223 if (break_num < 0x40000 || break_num > 0x100000) 217 if (break_num < 0x40000 || break_num > 0x100000)
224 die_if_kernel("Bad break", regs, break_num); 218 die_if_kernel("Bad break", regs, break_num);
@@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
226 if (break_num < 0x80000) { 220 if (break_num < 0x80000) {
227 sig = SIGILL; code = __ILL_BREAK; 221 sig = SIGILL; code = __ILL_BREAK;
228 } else { 222 } else {
223 if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
224 == NOTIFY_STOP)
225 return;
229 sig = SIGTRAP; code = TRAP_BRKPT; 226 sig = SIGTRAP; code = TRAP_BRKPT;
230 } 227 }
231 } 228 }
@@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
578#endif 575#endif
579 break; 576 break;
580 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; 577 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
581 case 36: 578 case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
582 if (notify_die(DIE_SS, "ss", &regs, vector,
583 vector, SIGTRAP) == NOTIFY_STOP)
584 return;
585 siginfo.si_code = TRAP_TRACE; ifa = 0; break;
586 } 579 }
580 if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP)
581 == NOTIFY_STOP)
582 return;
587 siginfo.si_signo = SIGTRAP; 583 siginfo.si_signo = SIGTRAP;
588 siginfo.si_errno = 0; 584 siginfo.si_errno = 0;
589 siginfo.si_addr = (void __user *) ifa; 585 siginfo.si_addr = (void __user *) ifa;
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index a88cdb7232f8..0f776b032d31 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -350,14 +350,12 @@ static void __init initialize_pernode_data(void)
350 * for best. 350 * for best.
351 * @nid: node id 351 * @nid: node id
352 * @pernodesize: size of this node's pernode data 352 * @pernodesize: size of this node's pernode data
353 * @align: alignment to use for this node's pernode data
354 */ 353 */
355static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize, 354static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
356 unsigned long align)
357{ 355{
358 void *ptr = NULL; 356 void *ptr = NULL;
359 u8 best = 0xff; 357 u8 best = 0xff;
360 int bestnode = -1, node; 358 int bestnode = -1, node, anynode = 0;
361 359
362 for_each_online_node(node) { 360 for_each_online_node(node) {
363 if (node_isset(node, memory_less_mask)) 361 if (node_isset(node, memory_less_mask))
@@ -366,13 +364,15 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
366 best = node_distance(nid, node); 364 best = node_distance(nid, node);
367 bestnode = node; 365 bestnode = node;
368 } 366 }
367 anynode = node;
369 } 368 }
370 369
371 ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, 370 if (bestnode == -1)
372 pernodesize, align, __pa(MAX_DMA_ADDRESS)); 371 bestnode = anynode;
372
373 ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize,
374 PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
373 375
374 if (!ptr)
375 panic("NO memory for memory less node\n");
376 return ptr; 376 return ptr;
377} 377}
378 378
@@ -413,8 +413,7 @@ static void __init memory_less_nodes(void)
413 413
414 for_each_node_mask(node, memory_less_mask) { 414 for_each_node_mask(node, memory_less_mask) {
415 pernodesize = compute_pernodesize(node); 415 pernodesize = compute_pernodesize(node);
416 pernode = memory_less_node_alloc(node, pernodesize, 416 pernode = memory_less_node_alloc(node, pernodesize);
417 (node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024));
418 fill_pernode(node, __pa(pernode), pernodesize); 417 fill_pernode(node, __pa(pernode), pernodesize);
419 } 418 }
420 419
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index c79a9b96d02b..41105d454423 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -8,6 +8,8 @@
8 * Modified RID allocation for SMP 8 * Modified RID allocation for SMP
9 * Goutham Rao <goutham.rao@intel.com> 9 * Goutham Rao <goutham.rao@intel.com>
10 * IPI based ptc implementation and A-step IPI implementation. 10 * IPI based ptc implementation and A-step IPI implementation.
11 * Rohit Seth <rohit.seth@intel.com>
12 * Ken Chen <kenneth.w.chen@intel.com>
11 */ 13 */
12#include <linux/config.h> 14#include <linux/config.h>
13#include <linux/module.h> 15#include <linux/module.h>
@@ -16,78 +18,75 @@
16#include <linux/sched.h> 18#include <linux/sched.h>
17#include <linux/smp.h> 19#include <linux/smp.h>
18#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/bootmem.h>
19 22
20#include <asm/delay.h> 23#include <asm/delay.h>
21#include <asm/mmu_context.h> 24#include <asm/mmu_context.h>
22#include <asm/pgalloc.h> 25#include <asm/pgalloc.h>
23#include <asm/pal.h> 26#include <asm/pal.h>
24#include <asm/tlbflush.h> 27#include <asm/tlbflush.h>
28#include <asm/dma.h>
25 29
26static struct { 30static struct {
27 unsigned long mask; /* mask of supported purge page-sizes */ 31 unsigned long mask; /* mask of supported purge page-sizes */
28 unsigned long max_bits; /* log2() of largest supported purge page-size */ 32 unsigned long max_bits; /* log2 of largest supported purge page-size */
29} purge; 33} purge;
30 34
31struct ia64_ctx ia64_ctx = { 35struct ia64_ctx ia64_ctx = {
32 .lock = SPIN_LOCK_UNLOCKED, 36 .lock = SPIN_LOCK_UNLOCKED,
33 .next = 1, 37 .next = 1,
34 .limit = (1 << 15) - 1, /* start out with the safe (architected) limit */
35 .max_ctx = ~0U 38 .max_ctx = ~0U
36}; 39};
37 40
38DEFINE_PER_CPU(u8, ia64_need_tlb_flush); 41DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
39 42
40/* 43/*
44 * Initializes the ia64_ctx.bitmap array based on max_ctx+1.
45 * Called after cpu_init() has setup ia64_ctx.max_ctx based on
46 * maximum RID that is supported by boot CPU.
47 */
48void __init
49mmu_context_init (void)
50{
51 ia64_ctx.bitmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
52 ia64_ctx.flushmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
53}
54
55/*
41 * Acquire the ia64_ctx.lock before calling this function! 56 * Acquire the ia64_ctx.lock before calling this function!
42 */ 57 */
43void 58void
44wrap_mmu_context (struct mm_struct *mm) 59wrap_mmu_context (struct mm_struct *mm)
45{ 60{
46 unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx; 61 int i, cpu;
47 struct task_struct *tsk; 62 unsigned long flush_bit;
48 int i;
49 63
50 if (ia64_ctx.next > max_ctx) 64 for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) {
51 ia64_ctx.next = 300; /* skip daemons */ 65 flush_bit = xchg(&ia64_ctx.flushmap[i], 0);
52 ia64_ctx.limit = max_ctx + 1; 66 ia64_ctx.bitmap[i] ^= flush_bit;
67 }
68
69 /* use offset at 300 to skip daemons */
70 ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
71 ia64_ctx.max_ctx, 300);
72 ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
73 ia64_ctx.max_ctx, ia64_ctx.next);
53 74
54 /* 75 /*
55 * Scan all the task's mm->context and set proper safe range 76 * can't call flush_tlb_all() here because of race condition
77 * with O(1) scheduler [EF]
56 */ 78 */
57 79 cpu = get_cpu(); /* prevent preemption/migration */
58 read_lock(&tasklist_lock); 80 for_each_online_cpu(i)
59 repeat: 81 if (i != cpu)
60 for_each_process(tsk) { 82 per_cpu(ia64_need_tlb_flush, i) = 1;
61 if (!tsk->mm) 83 put_cpu();
62 continue;
63 tsk_context = tsk->mm->context;
64 if (tsk_context == ia64_ctx.next) {
65 if (++ia64_ctx.next >= ia64_ctx.limit) {
66 /* empty range: reset the range limit and start over */
67 if (ia64_ctx.next > max_ctx)
68 ia64_ctx.next = 300;
69 ia64_ctx.limit = max_ctx + 1;
70 goto repeat;
71 }
72 }
73 if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit))
74 ia64_ctx.limit = tsk_context;
75 }
76 read_unlock(&tasklist_lock);
77 /* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
78 {
79 int cpu = get_cpu(); /* prevent preemption/migration */
80 for_each_online_cpu(i) {
81 if (i != cpu)
82 per_cpu(ia64_need_tlb_flush, i) = 1;
83 }
84 put_cpu();
85 }
86 local_flush_tlb_all(); 84 local_flush_tlb_all();
87} 85}
88 86
89void 87void
90ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits) 88ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
89 unsigned long end, unsigned long nbits)
91{ 90{
92 static DEFINE_SPINLOCK(ptcg_lock); 91 static DEFINE_SPINLOCK(ptcg_lock);
93 92
@@ -135,7 +134,8 @@ local_flush_tlb_all (void)
135} 134}
136 135
137void 136void
138flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end) 137flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
138 unsigned long end)
139{ 139{
140 struct mm_struct *mm = vma->vm_mm; 140 struct mm_struct *mm = vma->vm_mm;
141 unsigned long size = end - start; 141 unsigned long size = end - start;
@@ -149,7 +149,8 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
149#endif 149#endif
150 150
151 nbits = ia64_fls(size + 0xfff); 151 nbits = ia64_fls(size + 0xfff);
152 while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits)) 152 while (unlikely (((1UL << nbits) & purge.mask) == 0) &&
153 (nbits < purge.max_bits))
153 ++nbits; 154 ++nbits;
154 if (nbits > purge.max_bits) 155 if (nbits > purge.max_bits)
155 nbits = purge.max_bits; 156 nbits = purge.max_bits;
@@ -191,5 +192,5 @@ ia64_tlb_init (void)
191 local_cpu_data->ptce_stride[0] = ptce_info.stride[0]; 192 local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
192 local_cpu_data->ptce_stride[1] = ptce_info.stride[1]; 193 local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
193 194
194 local_flush_tlb_all(); /* nuke left overs from bootstrapping... */ 195 local_flush_tlb_all(); /* nuke left overs from bootstrapping... */
195} 196}
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 017cfc3f4789..20d76fae24e8 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
95} 95}
96 96
97static struct pci_raw_ops pci_sal_ops = { 97static struct pci_raw_ops pci_sal_ops = {
98 .read = pci_sal_read, 98 .read = pci_sal_read,
99 .write = pci_sal_write 99 .write = pci_sal_write
100}; 100};
101 101
@@ -137,35 +137,98 @@ alloc_pci_controller (int seg)
137 return controller; 137 return controller;
138} 138}
139 139
140static u64 __devinit 140struct pci_root_info {
141add_io_space (struct acpi_resource_address64 *addr) 141 struct pci_controller *controller;
142 char *name;
143};
144
145static unsigned int
146new_space (u64 phys_base, int sparse)
142{ 147{
143 u64 offset; 148 u64 mmio_base;
144 int sparse = 0;
145 int i; 149 int i;
146 150
147 if (addr->address_translation_offset == 0) 151 if (phys_base == 0)
148 return IO_SPACE_BASE(0); /* part of legacy IO space */ 152 return 0; /* legacy I/O port space */
149
150 if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
151 sparse = 1;
152 153
153 offset = (u64) ioremap(addr->address_translation_offset, 0); 154 mmio_base = (u64) ioremap(phys_base, 0);
154 for (i = 0; i < num_io_spaces; i++) 155 for (i = 0; i < num_io_spaces; i++)
155 if (io_space[i].mmio_base == offset && 156 if (io_space[i].mmio_base == mmio_base &&
156 io_space[i].sparse == sparse) 157 io_space[i].sparse == sparse)
157 return IO_SPACE_BASE(i); 158 return i;
158 159
159 if (num_io_spaces == MAX_IO_SPACES) { 160 if (num_io_spaces == MAX_IO_SPACES) {
160 printk("Too many IO port spaces\n"); 161 printk(KERN_ERR "PCI: Too many IO port spaces "
162 "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
161 return ~0; 163 return ~0;
162 } 164 }
163 165
164 i = num_io_spaces++; 166 i = num_io_spaces++;
165 io_space[i].mmio_base = offset; 167 io_space[i].mmio_base = mmio_base;
166 io_space[i].sparse = sparse; 168 io_space[i].sparse = sparse;
167 169
168 return IO_SPACE_BASE(i); 170 return i;
171}
172
173static u64 __devinit
174add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
175{
176 struct resource *resource;
177 char *name;
178 u64 base, min, max, base_port;
179 unsigned int sparse = 0, space_nr, len;
180
181 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
182 if (!resource) {
183 printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
184 info->name);
185 goto out;
186 }
187
188 len = strlen(info->name) + 32;
189 name = kzalloc(len, GFP_KERNEL);
190 if (!name) {
191 printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
192 info->name);
193 goto free_resource;
194 }
195
196 min = addr->min_address_range;
197 max = min + addr->address_length - 1;
198 if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
199 sparse = 1;
200
201 space_nr = new_space(addr->address_translation_offset, sparse);
202 if (space_nr == ~0)
203 goto free_name;
204
205 base = __pa(io_space[space_nr].mmio_base);
206 base_port = IO_SPACE_BASE(space_nr);
207 snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
208 base_port + min, base_port + max);
209
210 /*
211 * The SDM guarantees the legacy 0-64K space is sparse, but if the
212 * mapping is done by the processor (not the bridge), ACPI may not
213 * mark it as sparse.
214 */
215 if (space_nr == 0)
216 sparse = 1;
217
218 resource->name = name;
219 resource->flags = IORESOURCE_MEM;
220 resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
221 resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
222 insert_resource(&iomem_resource, resource);
223
224 return base_port;
225
226free_name:
227 kfree(name);
228free_resource:
229 kfree(resource);
230out:
231 return ~0;
169} 232}
170 233
171static acpi_status __devinit resource_to_window(struct acpi_resource *resource, 234static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data)
205 return AE_OK; 268 return AE_OK;
206} 269}
207 270
208struct pci_root_info {
209 struct pci_controller *controller;
210 char *name;
211};
212
213static __devinit acpi_status add_window(struct acpi_resource *res, void *data) 271static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
214{ 272{
215 struct pci_root_info *info = data; 273 struct pci_root_info *info = data;
@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
231 } else if (addr.resource_type == ACPI_IO_RANGE) { 289 } else if (addr.resource_type == ACPI_IO_RANGE) {
232 flags = IORESOURCE_IO; 290 flags = IORESOURCE_IO;
233 root = &ioport_resource; 291 root = &ioport_resource;
234 offset = add_io_space(&addr); 292 offset = add_io_space(info, &addr);
235 if (offset == ~0) 293 if (offset == ~0)
236 return AE_OK; 294 return AE_OK;
237 } else 295 } else
@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
241 window->resource.name = info->name; 299 window->resource.name = info->name;
242 window->resource.flags = flags; 300 window->resource.flags = flags;
243 window->resource.start = addr.min_address_range + offset; 301 window->resource.start = addr.min_address_range + offset;
244 window->resource.end = addr.max_address_range + offset; 302 window->resource.end = window->resource.start + addr.address_length - 1;
245 window->resource.child = NULL; 303 window->resource.child = NULL;
246 window->offset = offset; 304 window->offset = offset;
247 305
@@ -739,7 +797,7 @@ int pci_vector_resources(int last, int nr_released)
739{ 797{
740 int count = nr_released; 798 int count = nr_released;
741 799
742 count += (IA64_LAST_DEVICE_VECTOR - last); 800 count += (IA64_LAST_DEVICE_VECTOR - last);
743 801
744 return count; 802 return count;
745} 803}
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index b4f5053f5e1b..05e4ea889981 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -349,7 +349,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
349 return; /*bus # does not exist */ 349 return; /*bus # does not exist */
350 prom_bussoft_ptr = __va(prom_bussoft_ptr); 350 prom_bussoft_ptr = __va(prom_bussoft_ptr);
351 351
352 controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); 352 controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL);
353 controller->segment = segment; 353 controller->segment = segment;
354 if (!controller) 354 if (!controller)
355 BUG(); 355 BUG();
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
index fbcedc7c27fa..5483a9f227d4 100644
--- a/arch/ia64/sn/kernel/xpc.h
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -163,7 +163,7 @@ struct xpc_vars {
163 u8 version; 163 u8 version;
164 u64 heartbeat; 164 u64 heartbeat;
165 u64 heartbeating_to_mask; 165 u64 heartbeating_to_mask;
166 u64 kdb_status; /* 0 = machine running */ 166 u64 heartbeat_offline; /* if 0, heartbeat should be changing */
167 int act_nasid; 167 int act_nasid;
168 int act_phys_cpuid; 168 int act_phys_cpuid;
169 u64 vars_part_pa; 169 u64 vars_part_pa;
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index cece3c7c69be..b617236524c6 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -57,6 +57,7 @@
57#include <linux/reboot.h> 57#include <linux/reboot.h>
58#include <asm/sn/intr.h> 58#include <asm/sn/intr.h>
59#include <asm/sn/sn_sal.h> 59#include <asm/sn/sn_sal.h>
60#include <asm/kdebug.h>
60#include <asm/uaccess.h> 61#include <asm/uaccess.h>
61#include "xpc.h" 62#include "xpc.h"
62 63
@@ -188,6 +189,11 @@ static struct notifier_block xpc_reboot_notifier = {
188 .notifier_call = xpc_system_reboot, 189 .notifier_call = xpc_system_reboot,
189}; 190};
190 191
192static int xpc_system_die(struct notifier_block *, unsigned long, void *);
193static struct notifier_block xpc_die_notifier = {
194 .notifier_call = xpc_system_die,
195};
196
191 197
192/* 198/*
193 * Timer function to enforce the timelimit on the partition disengage request. 199 * Timer function to enforce the timelimit on the partition disengage request.
@@ -997,6 +1003,9 @@ xpc_do_exit(enum xpc_retval reason)
997 /* take ourselves off of the reboot_notifier_list */ 1003 /* take ourselves off of the reboot_notifier_list */
998 (void) unregister_reboot_notifier(&xpc_reboot_notifier); 1004 (void) unregister_reboot_notifier(&xpc_reboot_notifier);
999 1005
1006 /* take ourselves off of the die_notifier list */
1007 (void) unregister_die_notifier(&xpc_die_notifier);
1008
1000 /* close down protections for IPI operations */ 1009 /* close down protections for IPI operations */
1001 xpc_restrict_IPI_ops(); 1010 xpc_restrict_IPI_ops();
1002 1011
@@ -1011,6 +1020,63 @@ xpc_do_exit(enum xpc_retval reason)
1011 1020
1012 1021
1013/* 1022/*
1023 * Called when the system is about to be either restarted or halted.
1024 */
1025static void
1026xpc_die_disengage(void)
1027{
1028 struct xpc_partition *part;
1029 partid_t partid;
1030 unsigned long engaged;
1031 long time, print_time, disengage_request_timeout;
1032
1033
1034 /* keep xpc_hb_checker thread from doing anything (just in case) */
1035 xpc_exiting = 1;
1036
1037 xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */
1038
1039 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
1040 part = &xpc_partitions[partid];
1041
1042 if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part->
1043 remote_vars_version)) {
1044
1045 /* just in case it was left set by an earlier XPC */
1046 xpc_clear_partition_engaged(1UL << partid);
1047 continue;
1048 }
1049
1050 if (xpc_partition_engaged(1UL << partid) ||
1051 part->act_state != XPC_P_INACTIVE) {
1052 xpc_request_partition_disengage(part);
1053 xpc_mark_partition_disengaged(part);
1054 xpc_IPI_send_disengage(part);
1055 }
1056 }
1057
1058 print_time = rtc_time();
1059 disengage_request_timeout = print_time +
1060 (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
1061
1062 /* wait for all other partitions to disengage from us */
1063
1064 while ((engaged = xpc_partition_engaged(-1UL)) &&
1065 (time = rtc_time()) < disengage_request_timeout) {
1066
1067 if (time >= print_time) {
1068 dev_info(xpc_part, "waiting for remote partitions to "
1069 "disengage, engaged=0x%lx\n", engaged);
1070 print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL *
1071 sn_rtc_cycles_per_second);
1072 }
1073 }
1074 dev_info(xpc_part, "finished waiting for remote partitions to "
1075 "disengage, engaged=0x%lx\n", engaged);
1076}
1077
1078
1079/*
1014 * This function is called when the system is being rebooted. 1080 * This function is called when the system is being rebooted.
1015 */ 1081 */
1016static int 1082static int
@@ -1038,6 +1104,33 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
1038} 1104}
1039 1105
1040 1106
1107/*
1108 * This function is called when the system is being rebooted.
1109 */
1110static int
1111xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
1112{
1113 switch (event) {
1114 case DIE_MACHINE_RESTART:
1115 case DIE_MACHINE_HALT:
1116 xpc_die_disengage();
1117 break;
1118 case DIE_MCA_MONARCH_ENTER:
1119 case DIE_INIT_MONARCH_ENTER:
1120 xpc_vars->heartbeat++;
1121 xpc_vars->heartbeat_offline = 1;
1122 break;
1123 case DIE_MCA_MONARCH_LEAVE:
1124 case DIE_INIT_MONARCH_LEAVE:
1125 xpc_vars->heartbeat++;
1126 xpc_vars->heartbeat_offline = 0;
1127 break;
1128 }
1129
1130 return NOTIFY_DONE;
1131}
1132
1133
1041int __init 1134int __init
1042xpc_init(void) 1135xpc_init(void)
1043{ 1136{
@@ -1154,6 +1247,12 @@ xpc_init(void)
1154 dev_warn(xpc_part, "can't register reboot notifier\n"); 1247 dev_warn(xpc_part, "can't register reboot notifier\n");
1155 } 1248 }
1156 1249
1250 /* add ourselves to the die_notifier list (i.e., ia64die_chain) */
1251 ret = register_die_notifier(&xpc_die_notifier);
1252 if (ret != 0) {
1253 dev_warn(xpc_part, "can't register die notifier\n");
1254 }
1255
1157 1256
1158 /* 1257 /*
1159 * Set the beating to other partitions into motion. This is 1258 * Set the beating to other partitions into motion. This is
@@ -1179,6 +1278,9 @@ xpc_init(void)
1179 /* take ourselves off of the reboot_notifier_list */ 1278 /* take ourselves off of the reboot_notifier_list */
1180 (void) unregister_reboot_notifier(&xpc_reboot_notifier); 1279 (void) unregister_reboot_notifier(&xpc_reboot_notifier);
1181 1280
1281 /* take ourselves off of the die_notifier list */
1282 (void) unregister_die_notifier(&xpc_die_notifier);
1283
1182 del_timer_sync(&xpc_hb_timer); 1284 del_timer_sync(&xpc_hb_timer);
1183 free_irq(SGI_XPC_ACTIVATE, NULL); 1285 free_irq(SGI_XPC_ACTIVATE, NULL);
1184 xpc_restrict_IPI_ops(); 1286 xpc_restrict_IPI_ops();
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
index 581e113d2d37..cdd6431853a1 100644
--- a/arch/ia64/sn/kernel/xpc_partition.c
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -436,13 +436,13 @@ xpc_check_remote_hb(void)
436 } 436 }
437 437
438 dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat" 438 dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
439 " = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid, 439 " = %ld, heartbeat_offline = %ld, HB_mask = 0x%lx\n",
440 remote_vars->heartbeat, part->last_heartbeat, 440 partid, remote_vars->heartbeat, part->last_heartbeat,
441 remote_vars->kdb_status, 441 remote_vars->heartbeat_offline,
442 remote_vars->heartbeating_to_mask); 442 remote_vars->heartbeating_to_mask);
443 443
444 if (((remote_vars->heartbeat == part->last_heartbeat) && 444 if (((remote_vars->heartbeat == part->last_heartbeat) &&
445 (remote_vars->kdb_status == 0)) || 445 (remote_vars->heartbeat_offline == 0)) ||
446 !xpc_hb_allowed(sn_partition_id, remote_vars)) { 446 !xpc_hb_allowed(sn_partition_id, remote_vars)) {
447 447
448 XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); 448 XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 7b03b8084ffc..1f500c81002c 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -212,13 +212,13 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info)
212 pdi_pcibus_info; 212 pdi_pcibus_info;
213 213
214 /* Disable the device's IRQ */ 214 /* Disable the device's IRQ */
215 pcireg_intr_enable_bit_clr(pcibus_info, bit); 215 pcireg_intr_enable_bit_clr(pcibus_info, (1 << bit));
216 216
217 /* Change the device's IRQ */ 217 /* Change the device's IRQ */
218 pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr); 218 pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr);
219 219
220 /* Re-enable the device's IRQ */ 220 /* Re-enable the device's IRQ */
221 pcireg_intr_enable_bit_set(pcibus_info, bit); 221 pcireg_intr_enable_bit_set(pcibus_info, (1 << bit));
222 222
223 pcibr_force_interrupt(sn_irq_info); 223 pcibr_force_interrupt(sn_irq_info);
224 } 224 }
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
index 4f718c3e93d3..5d534091262c 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
@@ -131,7 +131,7 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
131 __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); 131 __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
132 break; 132 break;
133 case PCIBR_BRIDGETYPE_PIC: 133 case PCIBR_BRIDGETYPE_PIC:
134 __sn_clrq_relaxed(&ptr->pic.p_int_enable, ~bits); 134 __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);
135 break; 135 break;
136 default: 136 default:
137 panic 137 panic
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
index 9f03d4e5121c..dda196c9e324 100644
--- a/arch/ia64/sn/pci/tioce_provider.c
+++ b/arch/ia64/sn/pci/tioce_provider.c
@@ -218,7 +218,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
218 if (i > last) 218 if (i > last)
219 return 0; 219 return 0;
220 220
221 map = kcalloc(1, sizeof(struct tioce_dmamap), GFP_ATOMIC); 221 map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC);
222 if (!map) 222 if (!map)
223 return 0; 223 return 0;
224 224
@@ -555,7 +555,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
555 struct tioce *tioce_mmr; 555 struct tioce *tioce_mmr;
556 struct tioce_kernel *tioce_kern; 556 struct tioce_kernel *tioce_kern;
557 557
558 tioce_kern = kcalloc(1, sizeof(struct tioce_kernel), GFP_KERNEL); 558 tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
559 if (!tioce_kern) { 559 if (!tioce_kern) {
560 return NULL; 560 return NULL;
561 } 561 }
@@ -727,7 +727,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
727 * Allocate kernel bus soft and copy from prom. 727 * Allocate kernel bus soft and copy from prom.
728 */ 728 */
729 729
730 tioce_common = kcalloc(1, sizeof(struct tioce_common), GFP_KERNEL); 730 tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL);
731 if (!tioce_common) 731 if (!tioce_common)
732 return NULL; 732 return NULL;
733 733
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index ea13a8f4d8b0..cc4b571e5db7 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -104,7 +104,9 @@ void cpu_idle (void)
104 104
105 idle(); 105 idle();
106 } 106 }
107 preempt_enable_no_resched();
107 schedule(); 108 schedule();
109 preempt_disable();
108 } 110 }
109} 111}
110 112
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 640d592ea072..b90c54169fa5 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -426,6 +426,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
426int __init start_secondary(void *unused) 426int __init start_secondary(void *unused)
427{ 427{
428 cpu_init(); 428 cpu_init();
429 preempt_disable();
429 smp_callin(); 430 smp_callin();
430 while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) 431 while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
431 cpu_relax(); 432 cpu_relax();
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 11b1b90ba6ba..13d109328a42 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -102,7 +102,9 @@ void cpu_idle(void)
102 while (1) { 102 while (1) {
103 while (!need_resched()) 103 while (!need_resched())
104 idle(); 104 idle();
105 preempt_enable_no_resched();
105 schedule(); 106 schedule();
107 preempt_disable();
106 } 108 }
107} 109}
108 110
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 1ef15d5ef943..4f21f42d096b 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -111,17 +111,6 @@ void __init plat_setup(void)
111 } 111 }
112#endif 112#endif
113 113
114#ifdef CONFIG_FB_E1356
115 if ((argptr = strstr(argptr, "video=")) == NULL) {
116 argptr = prom_getcmdline();
117#ifdef CONFIG_MIPS_PB1000
118 strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1");
119#else
120 strcat(argptr, " video=e1356fb:system:pb1500");
121#endif
122 }
123#endif
124
125#ifdef CONFIG_FB_XPERT98 114#ifdef CONFIG_FB_XPERT98
126 if ((argptr = strstr(argptr, "video=")) == NULL) { 115 if ((argptr = strstr(argptr, "video=")) == NULL) {
127 argptr = prom_getcmdline(); 116 argptr = prom_getcmdline();
diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
index b260e51eb517..326f3aa63741 100644
--- a/arch/mips/configs/ddb5476_defconfig
+++ b/arch/mips/configs/ddb5476_defconfig
@@ -658,7 +658,6 @@ CONFIG_FB=y
658# CONFIG_FB_SMIVGX is not set 658# CONFIG_FB_SMIVGX is not set
659# CONFIG_FB_CYBLA is not set 659# CONFIG_FB_CYBLA is not set
660# CONFIG_FB_TRIDENT is not set 660# CONFIG_FB_TRIDENT is not set
661# CONFIG_FB_E1356 is not set
662# CONFIG_FB_S1D13XXX is not set 661# CONFIG_FB_S1D13XXX is not set
663# CONFIG_FB_VIRTUAL is not set 662# CONFIG_FB_VIRTUAL is not set
664 663
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 9a728c2d8fd5..6390a753e80b 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -628,7 +628,6 @@ CONFIG_FB=y
628# CONFIG_FB_SMIVGX is not set 628# CONFIG_FB_SMIVGX is not set
629# CONFIG_FB_CYBLA is not set 629# CONFIG_FB_CYBLA is not set
630# CONFIG_FB_TRIDENT is not set 630# CONFIG_FB_TRIDENT is not set
631# CONFIG_FB_E1356 is not set
632# CONFIG_FB_S1D13XXX is not set 631# CONFIG_FB_S1D13XXX is not set
633# CONFIG_FB_VIRTUAL is not set 632# CONFIG_FB_VIRTUAL is not set
634 633
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index ffb23fcab862..f18d05c2ca77 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -758,7 +758,6 @@ CONFIG_FB_MODE_HELPERS=y
758# CONFIG_FB_SMIVGX is not set 758# CONFIG_FB_SMIVGX is not set
759# CONFIG_FB_CYBLA is not set 759# CONFIG_FB_CYBLA is not set
760# CONFIG_FB_TRIDENT is not set 760# CONFIG_FB_TRIDENT is not set
761# CONFIG_FB_E1356 is not set
762# CONFIG_FB_S1D13XXX is not set 761# CONFIG_FB_S1D13XXX is not set
763# CONFIG_FB_VIRTUAL is not set 762# CONFIG_FB_VIRTUAL is not set
764 763
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index 05e65206a7b4..37bd8d5c865d 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -897,7 +897,6 @@ CONFIG_FB=y
897# CONFIG_FB_SMIVGX is not set 897# CONFIG_FB_SMIVGX is not set
898# CONFIG_FB_CYBLA is not set 898# CONFIG_FB_CYBLA is not set
899# CONFIG_FB_TRIDENT is not set 899# CONFIG_FB_TRIDENT is not set
900# CONFIG_FB_E1356 is not set
901# CONFIG_FB_S1D13XXX is not set 900# CONFIG_FB_S1D13XXX is not set
902# CONFIG_FB_VIRTUAL is not set 901# CONFIG_FB_VIRTUAL is not set
903 902
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 2bc61ca4ba08..897420d39053 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -876,7 +876,6 @@ CONFIG_FB_ATY_CT=y
876# CONFIG_FB_SMIVGX is not set 876# CONFIG_FB_SMIVGX is not set
877# CONFIG_FB_CYBLA is not set 877# CONFIG_FB_CYBLA is not set
878# CONFIG_FB_TRIDENT is not set 878# CONFIG_FB_TRIDENT is not set
879# CONFIG_FB_E1356 is not set
880# CONFIG_FB_S1D13XXX is not set 879# CONFIG_FB_S1D13XXX is not set
881# CONFIG_FB_VIRTUAL is not set 880# CONFIG_FB_VIRTUAL is not set
882 881
diff --git a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c
index ed9b2da510be..9ea1fc748864 100644
--- a/arch/mips/kernel/ioctl32.c
+++ b/arch/mips/kernel/ioctl32.c
@@ -26,10 +26,8 @@ long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
26#define CODE 26#define CODE
27#include "compat_ioctl.c" 27#include "compat_ioctl.c"
28 28
29typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
30
31#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) 29#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
32#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, 30#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
33#define IOCTL_TABLE_START \ 31#define IOCTL_TABLE_START \
34 struct ioctl_trans ioctl_start[] = { 32 struct ioctl_trans ioctl_start[] = {
35#define IOCTL_TABLE_END \ 33#define IOCTL_TABLE_END \
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 4fe3d5715c41..dd725779d91f 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -52,7 +52,9 @@ ATTRIB_NORET void cpu_idle(void)
52 while (!need_resched()) 52 while (!need_resched())
53 if (cpu_wait) 53 if (cpu_wait)
54 (*cpu_wait)(); 54 (*cpu_wait)();
55 preempt_enable_no_resched();
55 schedule(); 56 schedule();
57 preempt_disable();
56 } 58 }
57} 59}
58 60
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index fcacf1aae98a..25472fcaf715 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -82,7 +82,7 @@ extern ATTRIB_NORET void cpu_idle(void);
82 */ 82 */
83asmlinkage void start_secondary(void) 83asmlinkage void start_secondary(void)
84{ 84{
85 unsigned int cpu = smp_processor_id(); 85 unsigned int cpu;
86 86
87 cpu_probe(); 87 cpu_probe();
88 cpu_report(); 88 cpu_report();
@@ -95,6 +95,8 @@ asmlinkage void start_secondary(void)
95 */ 95 */
96 96
97 calibrate_delay(); 97 calibrate_delay();
98 preempt_disable();
99 cpu = smp_processor_id();
98 cpu_data[cpu].udelay_val = loops_per_jiffy; 100 cpu_data[cpu].udelay_val = loops_per_jiffy;
99 101
100 prom_smp_finish(); 102 prom_smp_finish();
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
index 230f5a93c2e6..9cd9c0fe2265 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -84,7 +84,6 @@ IRQ Device
84#include <asm/ptrace.h> 84#include <asm/ptrace.h>
85#include <asm/reboot.h> 85#include <asm/reboot.h>
86#include <asm/time.h> 86#include <asm/time.h>
87#include <linux/version.h>
88#include <linux/bootmem.h> 87#include <linux/bootmem.h>
89#include <asm/tx4938/rbtx4938.h> 88#include <asm/tx4938/rbtx4938.h>
90 89
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 1ad44f92d6e4..e23c4e1e3a25 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -30,7 +30,6 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/thread_info.h> 32#include <linux/thread_info.h>
33#include <linux/version.h>
34#include <linux/ptrace.h> 33#include <linux/ptrace.h>
35#include <linux/hardirq.h> 34#include <linux/hardirq.h>
36 35
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 7fdca87ef647..fee4f1f09adc 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -88,11 +88,15 @@ void default_idle(void)
88 */ 88 */
89void cpu_idle(void) 89void cpu_idle(void)
90{ 90{
91 set_thread_flag(TIF_POLLING_NRFLAG);
92
91 /* endless idle loop with no priority at all */ 93 /* endless idle loop with no priority at all */
92 while (1) { 94 while (1) {
93 while (!need_resched()) 95 while (!need_resched())
94 barrier(); 96 barrier();
97 preempt_enable_no_resched();
95 schedule(); 98 schedule();
99 preempt_disable();
96 check_pgt_cache(); 100 check_pgt_cache();
97 } 101 }
98} 102}
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 5db3be4e2704..a9ecf6465784 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -463,6 +463,7 @@ void __init smp_callin(void)
463#endif 463#endif
464 464
465 smp_cpu_init(slave_id); 465 smp_cpu_init(slave_id);
466 preempt_disable();
466 467
467#if 0 /* NOT WORKING YET - see entry.S */ 468#if 0 /* NOT WORKING YET - see entry.S */
468 istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER); 469 istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1493c7896fe3..c523029674e6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -581,17 +581,12 @@ config ARCH_FLATMEM_ENABLE
581 def_bool y 581 def_bool y
582 depends on PPC64 && !NUMA 582 depends on PPC64 && !NUMA
583 583
584config ARCH_DISCONTIGMEM_ENABLE 584config ARCH_SPARSEMEM_ENABLE
585 def_bool y
586 depends on SMP && PPC_PSERIES
587
588config ARCH_DISCONTIGMEM_DEFAULT
589 def_bool y 585 def_bool y
590 depends on ARCH_DISCONTIGMEM_ENABLE
591 586
592config ARCH_SPARSEMEM_ENABLE 587config ARCH_SPARSEMEM_DEFAULT
593 def_bool y 588 def_bool y
594 depends on ARCH_DISCONTIGMEM_ENABLE 589 depends on SMP && PPC_PSERIES
595 590
596source "mm/Kconfig" 591source "mm/Kconfig"
597 592
@@ -599,6 +594,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
599 def_bool y 594 def_bool y
600 depends on NEED_MULTIPLE_NODES 595 depends on NEED_MULTIPLE_NODES
601 596
597config ARCH_MEMORY_PROBE
598 def_bool y
599 depends on MEMORY_HOTPLUG
600
602# Some NUMA nodes have memory ranges that span 601# Some NUMA nodes have memory ranges that span
603# other nodes. Even though a pfn is valid and 602# other nodes. Even though a pfn is valid and
604# between a node's start and end pfns, it may not 603# between a node's start and end pfns, it may not
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index b3ae2993efb8..9a74b7ab03a4 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -4,6 +4,7 @@
4 4
5ifeq ($(CONFIG_PPC64),y) 5ifeq ($(CONFIG_PPC64),y)
6EXTRA_CFLAGS += -mno-minimal-toc 6EXTRA_CFLAGS += -mno-minimal-toc
7CFLAGS_ioctl32.o += -Ifs/
7endif 8endif
8ifeq ($(CONFIG_PPC32),y) 9ifeq ($(CONFIG_PPC32),y)
9CFLAGS_prom_init.o += -fPIC 10CFLAGS_prom_init.o += -fPIC
@@ -11,17 +12,29 @@ CFLAGS_btext.o += -fPIC
11endif 12endif
12 13
13obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ 14obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
14 signal_32.o pmc.o 15 irq.o signal_32.o pmc.o vdso.o
16obj-y += vdso32/
15obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
16 signal_64.o ptrace32.o systbl.o 18 signal_64.o ptrace32.o systbl.o \
19 paca.o ioctl32.o cpu_setup_power4.o \
20 firmware.o sysfs.o udbg.o
21obj-$(CONFIG_PPC64) += vdso64/
17obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
18obj-$(CONFIG_POWER4) += idle_power4.o 23obj-$(CONFIG_POWER4) += idle_power4.o
19obj-$(CONFIG_PPC_OF) += of_device.o 24obj-$(CONFIG_PPC_OF) += of_device.o
20obj-$(CONFIG_PPC_RTAS) += rtas.o 25procfs-$(CONFIG_PPC64) := proc_ppc64.o
26obj-$(CONFIG_PROC_FS) += $(procfs-y)
27rtaspci-$(CONFIG_PPC64) := rtas_pci.o
28obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y)
21obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 29obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
22obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 30obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
31obj-$(CONFIG_LPARCFG) += lparcfg.o
23obj-$(CONFIG_IBMVIO) += vio.o 32obj-$(CONFIG_IBMVIO) += vio.o
24obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o 33obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
34obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
35obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
36udbgscc-$(CONFIG_PPC64) := udbg_scc.o
37obj-$(CONFIG_PPC_PMAC) += $(udbgscc-y)
25 38
26ifeq ($(CONFIG_PPC_MERGE),y) 39ifeq ($(CONFIG_PPC_MERGE),y)
27 40
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index b75757251994..4550eb4f4fbd 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -37,12 +37,12 @@
37#include <asm/cputable.h> 37#include <asm/cputable.h>
38#include <asm/thread_info.h> 38#include <asm/thread_info.h>
39#include <asm/rtas.h> 39#include <asm/rtas.h>
40#include <asm/vdso_datapage.h>
40#ifdef CONFIG_PPC64 41#ifdef CONFIG_PPC64
41#include <asm/paca.h> 42#include <asm/paca.h>
42#include <asm/lppaca.h> 43#include <asm/lppaca.h>
43#include <asm/iseries/hv_lp_event.h> 44#include <asm/iseries/hv_lp_event.h>
44#include <asm/cache.h> 45#include <asm/cache.h>
45#include <asm/systemcfg.h>
46#include <asm/compat.h> 46#include <asm/compat.h>
47#endif 47#endif
48 48
@@ -106,7 +106,6 @@ int main(void)
106 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); 106 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
107 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); 107 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
108 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); 108 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
109 DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
110 DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); 109 DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
111 110
112 /* paca */ 111 /* paca */
@@ -252,25 +251,42 @@ int main(void)
252 251
253 DEFINE(TASK_SIZE, TASK_SIZE); 252 DEFINE(TASK_SIZE, TASK_SIZE);
254 DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); 253 DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
255#else /* CONFIG_PPC64 */ 254#endif /* ! CONFIG_PPC64 */
256 /* systemcfg offsets for use by vdso */
257 DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
258 DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
259 DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
260 DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
261 DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
262 DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
263 DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
264 DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
265 DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
266 255
267 /* timeval/timezone offsets for use by vdso */ 256 /* datapage offsets for use by vdso */
257 DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct vdso_data, tb_orig_stamp));
258 DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct vdso_data, tb_ticks_per_sec));
259 DEFINE(CFG_TB_TO_XS, offsetof(struct vdso_data, tb_to_xs));
260 DEFINE(CFG_STAMP_XSEC, offsetof(struct vdso_data, stamp_xsec));
261 DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct vdso_data, tb_update_count));
262 DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct vdso_data, tz_minuteswest));
263 DEFINE(CFG_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
264 DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32));
265 DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec));
266 DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
267#ifdef CONFIG_PPC64
268 DEFINE(CFG_SYSCALL_MAP64, offsetof(struct vdso_data, syscall_map_64));
268 DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec)); 269 DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
269 DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec)); 270 DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
270 DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec)); 271 DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
271 DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec)); 272 DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
273 DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec));
274 DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
275#else
276 DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec));
277 DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec));
278 DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec));
279 DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
280#endif
281 /* timeval/timezone offsets for use by vdso */
272 DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); 282 DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
273 DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime)); 283 DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
274#endif /* CONFIG_PPC64 */ 284
285 /* Other bits used by the vdso */
286 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
287 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
288 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
289 DEFINE(CLOCK_REALTIME_RES, TICK_NSEC);
290
275 return 0; 291 return 0;
276} 292}
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S
index 1fb673c511ff..cca942fe6115 100644
--- a/arch/ppc64/kernel/cpu_setup_power4.S
+++ b/arch/powerpc/kernel/cpu_setup_power4.S
@@ -114,11 +114,11 @@ _GLOBAL(__setup_cpu_ppc970)
114 114
115 .data 115 .data
116 .balign L1_CACHE_BYTES,0 116 .balign L1_CACHE_BYTES,0
117cpu_state_storage: 117cpu_state_storage:
118 .space CS_SIZE 118 .space CS_SIZE
119 .balign L1_CACHE_BYTES,0 119 .balign L1_CACHE_BYTES,0
120 .text 120 .text
121 121
122/* Called in normal context to backup CPU 0 state. This 122/* Called in normal context to backup CPU 0 state. This
123 * does not include cache settings. This function is also 123 * does not include cache settings. This function is also
124 * called for machine sleep. This does not include the MMU 124 * called for machine sleep. This does not include the MMU
@@ -151,7 +151,7 @@ _GLOBAL(__save_cpu_setup)
151 std r3,CS_HID4(r5) 151 std r3,CS_HID4(r5)
152 mfspr r3,SPRN_HID5 152 mfspr r3,SPRN_HID5
153 std r3,CS_HID5(r5) 153 std r3,CS_HID5(r5)
154 154
1552: 1552:
156 mtcr r7 156 mtcr r7
157 blr 157 blr
@@ -213,7 +213,7 @@ _GLOBAL(__restore_cpu_setup)
213 mtspr SPRN_HID1,r3 213 mtspr SPRN_HID1,r3
214 sync 214 sync
215 isync 215 isync
216 216
217 /* Restore HID4 */ 217 /* Restore HID4 */
218 ld r3,CS_HID4(r5) 218 ld r3,CS_HID4(r5)
219 sync 219 sync
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index cc4e9eb1c13f..1d85cedbbb7b 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -52,6 +52,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
52#define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ 52#define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
53 PPC_FEATURE_HAS_MMU) 53 PPC_FEATURE_HAS_MMU)
54#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64) 54#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64)
55#define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
56#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
57#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
55 58
56 59
57/* We only set the spe features if the kernel was compiled with 60/* We only set the spe features if the kernel was compiled with
@@ -160,7 +163,7 @@ struct cpu_spec cpu_specs[] = {
160 .pvr_value = 0x00350000, 163 .pvr_value = 0x00350000,
161 .cpu_name = "POWER4 (gp)", 164 .cpu_name = "POWER4 (gp)",
162 .cpu_features = CPU_FTRS_POWER4, 165 .cpu_features = CPU_FTRS_POWER4,
163 .cpu_user_features = COMMON_USER_PPC64, 166 .cpu_user_features = COMMON_USER_POWER4,
164 .icache_bsize = 128, 167 .icache_bsize = 128,
165 .dcache_bsize = 128, 168 .dcache_bsize = 128,
166 .num_pmcs = 8, 169 .num_pmcs = 8,
@@ -175,7 +178,7 @@ struct cpu_spec cpu_specs[] = {
175 .pvr_value = 0x00380000, 178 .pvr_value = 0x00380000,
176 .cpu_name = "POWER4+ (gq)", 179 .cpu_name = "POWER4+ (gq)",
177 .cpu_features = CPU_FTRS_POWER4, 180 .cpu_features = CPU_FTRS_POWER4,
178 .cpu_user_features = COMMON_USER_PPC64, 181 .cpu_user_features = COMMON_USER_POWER4,
179 .icache_bsize = 128, 182 .icache_bsize = 128,
180 .dcache_bsize = 128, 183 .dcache_bsize = 128,
181 .num_pmcs = 8, 184 .num_pmcs = 8,
@@ -190,7 +193,7 @@ struct cpu_spec cpu_specs[] = {
190 .pvr_value = 0x00390000, 193 .pvr_value = 0x00390000,
191 .cpu_name = "PPC970", 194 .cpu_name = "PPC970",
192 .cpu_features = CPU_FTRS_PPC970, 195 .cpu_features = CPU_FTRS_PPC970,
193 .cpu_user_features = COMMON_USER_PPC64 | 196 .cpu_user_features = COMMON_USER_POWER4 |
194 PPC_FEATURE_HAS_ALTIVEC_COMP, 197 PPC_FEATURE_HAS_ALTIVEC_COMP,
195 .icache_bsize = 128, 198 .icache_bsize = 128,
196 .dcache_bsize = 128, 199 .dcache_bsize = 128,
@@ -212,7 +215,7 @@ struct cpu_spec cpu_specs[] = {
212#else 215#else
213 .cpu_features = CPU_FTRS_PPC970, 216 .cpu_features = CPU_FTRS_PPC970,
214#endif 217#endif
215 .cpu_user_features = COMMON_USER_PPC64 | 218 .cpu_user_features = COMMON_USER_POWER4 |
216 PPC_FEATURE_HAS_ALTIVEC_COMP, 219 PPC_FEATURE_HAS_ALTIVEC_COMP,
217 .icache_bsize = 128, 220 .icache_bsize = 128,
218 .dcache_bsize = 128, 221 .dcache_bsize = 128,
@@ -230,7 +233,7 @@ struct cpu_spec cpu_specs[] = {
230 .pvr_value = 0x00440000, 233 .pvr_value = 0x00440000,
231 .cpu_name = "PPC970MP", 234 .cpu_name = "PPC970MP",
232 .cpu_features = CPU_FTRS_PPC970, 235 .cpu_features = CPU_FTRS_PPC970,
233 .cpu_user_features = COMMON_USER_PPC64 | 236 .cpu_user_features = COMMON_USER_POWER4 |
234 PPC_FEATURE_HAS_ALTIVEC_COMP, 237 PPC_FEATURE_HAS_ALTIVEC_COMP,
235 .icache_bsize = 128, 238 .icache_bsize = 128,
236 .dcache_bsize = 128, 239 .dcache_bsize = 128,
@@ -245,7 +248,7 @@ struct cpu_spec cpu_specs[] = {
245 .pvr_value = 0x003a0000, 248 .pvr_value = 0x003a0000,
246 .cpu_name = "POWER5 (gr)", 249 .cpu_name = "POWER5 (gr)",
247 .cpu_features = CPU_FTRS_POWER5, 250 .cpu_features = CPU_FTRS_POWER5,
248 .cpu_user_features = COMMON_USER_PPC64, 251 .cpu_user_features = COMMON_USER_POWER5,
249 .icache_bsize = 128, 252 .icache_bsize = 128,
250 .dcache_bsize = 128, 253 .dcache_bsize = 128,
251 .num_pmcs = 6, 254 .num_pmcs = 6,
@@ -260,7 +263,7 @@ struct cpu_spec cpu_specs[] = {
260 .pvr_value = 0x003b0000, 263 .pvr_value = 0x003b0000,
261 .cpu_name = "POWER5 (gs)", 264 .cpu_name = "POWER5 (gs)",
262 .cpu_features = CPU_FTRS_POWER5, 265 .cpu_features = CPU_FTRS_POWER5,
263 .cpu_user_features = COMMON_USER_PPC64, 266 .cpu_user_features = COMMON_USER_POWER5_PLUS,
264 .icache_bsize = 128, 267 .icache_bsize = 128,
265 .dcache_bsize = 128, 268 .dcache_bsize = 128,
266 .num_pmcs = 6, 269 .num_pmcs = 6,
@@ -276,7 +279,7 @@ struct cpu_spec cpu_specs[] = {
276 .cpu_name = "Cell Broadband Engine", 279 .cpu_name = "Cell Broadband Engine",
277 .cpu_features = CPU_FTRS_CELL, 280 .cpu_features = CPU_FTRS_CELL,
278 .cpu_user_features = COMMON_USER_PPC64 | 281 .cpu_user_features = COMMON_USER_PPC64 |
279 PPC_FEATURE_HAS_ALTIVEC_COMP, 282 PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP,
280 .icache_bsize = 128, 283 .icache_bsize = 128,
281 .dcache_bsize = 128, 284 .dcache_bsize = 128,
282 .cpu_setup = __setup_cpu_be, 285 .cpu_setup = __setup_cpu_be,
diff --git a/arch/ppc64/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
index d8432c0fb27d..65eae752a527 100644
--- a/arch/ppc64/kernel/firmware.c
+++ b/arch/powerpc/kernel/firmware.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/firmware.c
3 *
4 * Extracted from cputable.c 2 * Extracted from cputable.c
5 * 3 *
6 * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) 4 * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 4d6001fa1cf2..b780b42c95fc 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -41,20 +41,20 @@ _GLOBAL(load_up_fpu)
41#ifndef CONFIG_SMP 41#ifndef CONFIG_SMP
42 LOADBASE(r3, last_task_used_math) 42 LOADBASE(r3, last_task_used_math)
43 toreal(r3) 43 toreal(r3)
44 LDL r4,OFF(last_task_used_math)(r3) 44 PPC_LL r4,OFF(last_task_used_math)(r3)
45 CMPI 0,r4,0 45 PPC_LCMPI 0,r4,0
46 beq 1f 46 beq 1f
47 toreal(r4) 47 toreal(r4)
48 addi r4,r4,THREAD /* want last_task_used_math->thread */ 48 addi r4,r4,THREAD /* want last_task_used_math->thread */
49 SAVE_32FPRS(0, r4) 49 SAVE_32FPRS(0, r4)
50 mffs fr0 50 mffs fr0
51 stfd fr0,THREAD_FPSCR(r4) 51 stfd fr0,THREAD_FPSCR(r4)
52 LDL r5,PT_REGS(r4) 52 PPC_LL r5,PT_REGS(r4)
53 toreal(r5) 53 toreal(r5)
54 LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 54 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
55 li r10,MSR_FP|MSR_FE0|MSR_FE1 55 li r10,MSR_FP|MSR_FE0|MSR_FE1
56 andc r4,r4,r10 /* disable FP for previous task */ 56 andc r4,r4,r10 /* disable FP for previous task */
57 STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 57 PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
581: 581:
59#endif /* CONFIG_SMP */ 59#endif /* CONFIG_SMP */
60 /* enable use of FP after return */ 60 /* enable use of FP after return */
@@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu)
77#ifndef CONFIG_SMP 77#ifndef CONFIG_SMP
78 subi r4,r5,THREAD 78 subi r4,r5,THREAD
79 fromreal(r4) 79 fromreal(r4)
80 STL r4,OFF(last_task_used_math)(r3) 80 PPC_STL r4,OFF(last_task_used_math)(r3)
81#endif /* CONFIG_SMP */ 81#endif /* CONFIG_SMP */
82 /* restore registers and return */ 82 /* restore registers and return */
83 /* we haven't used ctr or xer or lr */ 83 /* we haven't used ctr or xer or lr */
@@ -97,24 +97,24 @@ _GLOBAL(giveup_fpu)
97 MTMSRD(r5) /* enable use of fpu now */ 97 MTMSRD(r5) /* enable use of fpu now */
98 SYNC_601 98 SYNC_601
99 isync 99 isync
100 CMPI 0,r3,0 100 PPC_LCMPI 0,r3,0
101 beqlr- /* if no previous owner, done */ 101 beqlr- /* if no previous owner, done */
102 addi r3,r3,THREAD /* want THREAD of task */ 102 addi r3,r3,THREAD /* want THREAD of task */
103 LDL r5,PT_REGS(r3) 103 PPC_LL r5,PT_REGS(r3)
104 CMPI 0,r5,0 104 PPC_LCMPI 0,r5,0
105 SAVE_32FPRS(0, r3) 105 SAVE_32FPRS(0, r3)
106 mffs fr0 106 mffs fr0
107 stfd fr0,THREAD_FPSCR(r3) 107 stfd fr0,THREAD_FPSCR(r3)
108 beq 1f 108 beq 1f
109 LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 109 PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
110 li r3,MSR_FP|MSR_FE0|MSR_FE1 110 li r3,MSR_FP|MSR_FE0|MSR_FE1
111 andc r4,r4,r3 /* disable FP for previous task */ 111 andc r4,r4,r3 /* disable FP for previous task */
112 STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) 112 PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1131: 1131:
114#ifndef CONFIG_SMP 114#ifndef CONFIG_SMP
115 li r5,0 115 li r5,0
116 LOADBASE(r4,last_task_used_math) 116 LOADBASE(r4,last_task_used_math)
117 STL r5,OFF(last_task_used_math)(r4) 117 PPC_STL r5,OFF(last_task_used_math)(r4)
118#endif /* CONFIG_SMP */ 118#endif /* CONFIG_SMP */
119 blr 119 blr
120 120
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index b102e3a2415e..ccdf94731e30 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -1100,6 +1100,7 @@ start_here:
1100 mr r3,r31 1100 mr r3,r31
1101 mr r4,r30 1101 mr r4,r30
1102 bl machine_init 1102 bl machine_init
1103 bl __save_cpu_setup
1103 bl MMU_init 1104 bl MMU_init
1104 1105
1105#ifdef CONFIG_APUS 1106#ifdef CONFIG_APUS
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 16ab40daa738..8a8bf79ef044 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -28,7 +28,6 @@
28#include <asm/reg.h> 28#include <asm/reg.h>
29#include <asm/page.h> 29#include <asm/page.h>
30#include <asm/mmu.h> 30#include <asm/mmu.h>
31#include <asm/systemcfg.h>
32#include <asm/ppc_asm.h> 31#include <asm/ppc_asm.h>
33#include <asm/asm-offsets.h> 32#include <asm/asm-offsets.h>
34#include <asm/bug.h> 33#include <asm/bug.h>
@@ -1697,25 +1696,14 @@ _GLOBAL(pmac_secondary_start)
1697 * SPRG3 = paca virtual address 1696 * SPRG3 = paca virtual address
1698 */ 1697 */
1699_GLOBAL(__secondary_start) 1698_GLOBAL(__secondary_start)
1699 /* Set thread priority to MEDIUM */
1700 HMT_MEDIUM
1700 1701
1701 HMT_MEDIUM /* Set thread priority to MEDIUM */ 1702 /* Load TOC */
1702
1703 ld r2,PACATOC(r13) 1703 ld r2,PACATOC(r13)
1704 li r6,0 1704
1705 stb r6,PACAPROCENABLED(r13) 1705 /* Do early setup for that CPU (stab, slb, hash table pointer) */
1706 1706 bl .early_setup_secondary
1707#ifndef CONFIG_PPC_ISERIES
1708 /* Initialize the page table pointer register. */
1709 LOADADDR(r6,_SDR1)
1710 ld r6,0(r6) /* get the value of _SDR1 */
1711 mtspr SPRN_SDR1,r6 /* set the htab location */
1712#endif
1713 /* Initialize the first segment table (or SLB) entry */
1714 ld r3,PACASTABVIRT(r13) /* get addr of segment table */
1715BEGIN_FTR_SECTION
1716 bl .stab_initialize
1717END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1718 bl .slb_initialize
1719 1707
1720 /* Initialize the kernel stack. Just a repeat for iSeries. */ 1708 /* Initialize the kernel stack. Just a repeat for iSeries. */
1721 LOADADDR(r3,current_set) 1709 LOADADDR(r3,current_set)
@@ -1724,37 +1712,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1724 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD 1712 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1725 std r1,PACAKSAVE(r13) 1713 std r1,PACAKSAVE(r13)
1726 1714
1727 ld r3,PACASTABREAL(r13) /* get raddr of segment table */ 1715 /* Clear backchain so we get nice backtraces */
1728 ori r4,r3,1 /* turn on valid bit */
1729
1730#ifdef CONFIG_PPC_ISERIES
1731 li r0,-1 /* hypervisor call */
1732 li r3,1
1733 sldi r3,r3,63 /* 0x8000000000000000 */
1734 ori r3,r3,4 /* 0x8000000000000004 */
1735 sc /* HvCall_setASR */
1736#else
1737 /* set the ASR */
1738 ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
1739 ld r3,0(r3)
1740 lwz r3,PLATFORM(r3) /* r3 = platform flags */
1741 andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
1742 beq 98f /* branch if result is 0 */
1743 mfspr r3,SPRN_PVR
1744 srwi r3,r3,16
1745 cmpwi r3,0x37 /* SStar */
1746 beq 97f
1747 cmpwi r3,0x36 /* IStar */
1748 beq 97f
1749 cmpwi r3,0x34 /* Pulsar */
1750 bne 98f
175197: li r3,H_SET_ASR /* hcall = H_SET_ASR */
1752 HVSC /* Invoking hcall */
1753 b 99f
175498: /* !(rpa hypervisor) || !(star) */
1755 mtasr r4 /* set the stab location */
175699:
1757#endif
1758 li r7,0 1716 li r7,0
1759 mtlr r7 1717 mtlr r7
1760 1718
@@ -1777,6 +1735,7 @@ _GLOBAL(start_secondary_prolog)
1777 li r3,0 1735 li r3,0
1778 std r3,0(r1) /* Zero the stack frame pointer */ 1736 std r3,0(r1) /* Zero the stack frame pointer */
1779 bl .start_secondary 1737 bl .start_secondary
1738 b .
1780#endif 1739#endif
1781 1740
1782/* 1741/*
@@ -1896,40 +1855,6 @@ _STATIC(start_here_multiplatform)
1896 mr r3,r31 1855 mr r3,r31
1897 bl .early_setup 1856 bl .early_setup
1898 1857
1899 /* set the ASR */
1900 ld r3,PACASTABREAL(r13)
1901 ori r4,r3,1 /* turn on valid bit */
1902 ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
1903 ld r3,0(r3)
1904 lwz r3,PLATFORM(r3) /* r3 = platform flags */
1905 andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
1906 beq 98f /* branch if result is 0 */
1907 mfspr r3,SPRN_PVR
1908 srwi r3,r3,16
1909 cmpwi r3,0x37 /* SStar */
1910 beq 97f
1911 cmpwi r3,0x36 /* IStar */
1912 beq 97f
1913 cmpwi r3,0x34 /* Pulsar */
1914 bne 98f
191597: li r3,H_SET_ASR /* hcall = H_SET_ASR */
1916 HVSC /* Invoking hcall */
1917 b 99f
191898: /* !(rpa hypervisor) || !(star) */
1919 mtasr r4 /* set the stab location */
192099:
1921 /* Set SDR1 (hash table pointer) */
1922 ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
1923 ld r3,0(r3)
1924 lwz r3,PLATFORM(r3) /* r3 = platform flags */
1925 /* Test if bit 0 is set (LPAR bit) */
1926 andi. r3,r3,PLATFORM_LPAR
1927 bne 98f /* branch if result is !0 */
1928 LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
1929 add r6,r6,r26
1930 ld r6,0(r6) /* get the value of _SDR1 */
1931 mtspr SPRN_SDR1,r6 /* set the htab location */
193298:
1933 LOADADDR(r3,.start_here_common) 1858 LOADADDR(r3,.start_here_common)
1934 SET_REG_TO_CONST(r4, MSR_KERNEL) 1859 SET_REG_TO_CONST(r4, MSR_KERNEL)
1935 mtspr SPRN_SRR0,r3 1860 mtspr SPRN_SRR0,r3
diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c
index ba4a899045c2..3fa6a93adbd0 100644
--- a/arch/ppc64/kernel/ioctl32.c
+++ b/arch/powerpc/kernel/ioctl32.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls. 2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3 * 3 *
4 * Based on sparc64 ioctl32.c by: 4 * Based on sparc64 ioctl32.c by:
5 * 5 *
6 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) 6 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
diff --git a/arch/ppc64/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 87474584033f..4b7940693f3d 100644
--- a/arch/ppc64/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -5,12 +5,12 @@
5 * Copyright (C) 1992 Linus Torvalds 5 * Copyright (C) 1992 Linus Torvalds
6 * Adapted from arch/i386 by Gary Thomas 6 * Adapted from arch/i386 by Gary Thomas
7 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 7 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
8 * Updated and modified by Cort Dougan (cort@cs.nmt.edu) 8 * Updated and modified by Cort Dougan <cort@fsmlabs.com>
9 * Copyright (C) 1996 Cort Dougan 9 * Copyright (C) 1996-2001 Cort Dougan
10 * Adapted for Power Macintosh by Paul Mackerras 10 * Adapted for Power Macintosh by Paul Mackerras
11 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) 11 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
12 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). 12 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
13 * 13 *
14 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 16 * as published by the Free Software Foundation; either version
@@ -21,6 +21,14 @@
21 * instead of just grabbing them. Thus setups with different IRQ numbers 21 * instead of just grabbing them. Thus setups with different IRQ numbers
22 * shouldn't result in any weird surprises, and installing new handlers 22 * shouldn't result in any weird surprises, and installing new handlers
23 * should be easier. 23 * should be easier.
24 *
25 * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the
26 * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit
27 * mask register (of which only 16 are defined), hence the weird shifting
28 * and complement of the cached_irq_mask. I want to be able to stuff
29 * this right into the SIU SMASK register.
30 * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
31 * to reduce code space and undefined function references.
24 */ 32 */
25 33
26#include <linux/errno.h> 34#include <linux/errno.h>
@@ -29,6 +37,7 @@
29#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
30#include <linux/signal.h> 38#include <linux/signal.h>
31#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/ptrace.h>
32#include <linux/ioport.h> 41#include <linux/ioport.h>
33#include <linux/interrupt.h> 42#include <linux/interrupt.h>
34#include <linux/timex.h> 43#include <linux/timex.h>
@@ -40,9 +49,13 @@
40#include <linux/irq.h> 49#include <linux/irq.h>
41#include <linux/proc_fs.h> 50#include <linux/proc_fs.h>
42#include <linux/random.h> 51#include <linux/random.h>
43#include <linux/kallsyms.h> 52#include <linux/seq_file.h>
53#include <linux/cpumask.h>
44#include <linux/profile.h> 54#include <linux/profile.h>
45#include <linux/bitops.h> 55#include <linux/bitops.h>
56#ifdef CONFIG_PPC64
57#include <linux/kallsyms.h>
58#endif
46 59
47#include <asm/uaccess.h> 60#include <asm/uaccess.h>
48#include <asm/system.h> 61#include <asm/system.h>
@@ -52,35 +65,54 @@
52#include <asm/cache.h> 65#include <asm/cache.h>
53#include <asm/prom.h> 66#include <asm/prom.h>
54#include <asm/ptrace.h> 67#include <asm/ptrace.h>
55#include <asm/iseries/it_lp_queue.h>
56#include <asm/machdep.h> 68#include <asm/machdep.h>
69#ifdef CONFIG_PPC64
70#include <asm/iseries/it_lp_queue.h>
57#include <asm/paca.h> 71#include <asm/paca.h>
72#endif
58 73
59#ifdef CONFIG_SMP 74static int ppc_spurious_interrupts;
60extern void iSeries_smp_message_recv( struct pt_regs * ); 75
76#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
77extern void iSeries_smp_message_recv(struct pt_regs *);
78#endif
79
80#ifdef CONFIG_PPC32
81#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
82
83unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
84atomic_t ppc_n_lost_interrupts;
85
86#ifdef CONFIG_TAU_INT
87extern int tau_initialized;
88extern int tau_interrupts(int);
89#endif
90
91#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
92extern atomic_t ipi_recv;
93extern atomic_t ipi_sent;
61#endif 94#endif
95#endif /* CONFIG_PPC32 */
62 96
63extern irq_desc_t irq_desc[NR_IRQS]; 97#ifdef CONFIG_PPC64
64EXPORT_SYMBOL(irq_desc); 98EXPORT_SYMBOL(irq_desc);
65 99
66int distribute_irqs = 1; 100int distribute_irqs = 1;
67int __irq_offset_value; 101int __irq_offset_value;
68int ppc_spurious_interrupts;
69u64 ppc64_interrupt_controller; 102u64 ppc64_interrupt_controller;
103#endif /* CONFIG_PPC64 */
70 104
71int show_interrupts(struct seq_file *p, void *v) 105int show_interrupts(struct seq_file *p, void *v)
72{ 106{
73 int i = *(loff_t *) v, j; 107 int i = *(loff_t *)v, j;
74 struct irqaction * action; 108 struct irqaction *action;
75 irq_desc_t *desc; 109 irq_desc_t *desc;
76 unsigned long flags; 110 unsigned long flags;
77 111
78 if (i == 0) { 112 if (i == 0) {
79 seq_printf(p, " "); 113 seq_puts(p, " ");
80 for (j=0; j<NR_CPUS; j++) { 114 for_each_online_cpu(j)
81 if (cpu_online(j)) 115 seq_printf(p, "CPU%d ", j);
82 seq_printf(p, "CPU%d ",j);
83 }
84 seq_putc(p, '\n'); 116 seq_putc(p, '\n');
85 } 117 }
86 118
@@ -92,26 +124,41 @@ int show_interrupts(struct seq_file *p, void *v)
92 goto skip; 124 goto skip;
93 seq_printf(p, "%3d: ", i); 125 seq_printf(p, "%3d: ", i);
94#ifdef CONFIG_SMP 126#ifdef CONFIG_SMP
95 for (j = 0; j < NR_CPUS; j++) { 127 for_each_online_cpu(j)
96 if (cpu_online(j)) 128 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
97 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
98 }
99#else 129#else
100 seq_printf(p, "%10u ", kstat_irqs(i)); 130 seq_printf(p, "%10u ", kstat_irqs(i));
101#endif /* CONFIG_SMP */ 131#endif /* CONFIG_SMP */
102 if (desc->handler) 132 if (desc->handler)
103 seq_printf(p, " %s ", desc->handler->typename ); 133 seq_printf(p, " %s ", desc->handler->typename);
104 else 134 else
105 seq_printf(p, " None "); 135 seq_puts(p, " None ");
106 seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); 136 seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge ");
107 seq_printf(p, " %s",action->name); 137 seq_printf(p, " %s", action->name);
108 for (action=action->next; action; action = action->next) 138 for (action = action->next; action; action = action->next)
109 seq_printf(p, ", %s", action->name); 139 seq_printf(p, ", %s", action->name);
110 seq_putc(p, '\n'); 140 seq_putc(p, '\n');
111skip: 141skip:
112 spin_unlock_irqrestore(&desc->lock, flags); 142 spin_unlock_irqrestore(&desc->lock, flags);
113 } else if (i == NR_IRQS) 143 } else if (i == NR_IRQS) {
144#ifdef CONFIG_PPC32
145#ifdef CONFIG_TAU_INT
146 if (tau_initialized){
147 seq_puts(p, "TAU: ");
148 for (j = 0; j < NR_CPUS; j++)
149 if (cpu_online(j))
150 seq_printf(p, "%10u ", tau_interrupts(j));
151 seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
152 }
153#endif
154#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
155 /* should this be per processor send/receive? */
156 seq_printf(p, "IPI (recv/sent): %10u/%u\n",
157 atomic_read(&ipi_recv), atomic_read(&ipi_sent));
158#endif
159#endif /* CONFIG_PPC32 */
114 seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); 160 seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
161 }
115 return 0; 162 return 0;
116} 163}
117 164
@@ -144,126 +191,6 @@ void fixup_irqs(cpumask_t map)
144} 191}
145#endif 192#endif
146 193
147extern int noirqdebug;
148
149/*
150 * Eventually, this should take an array of interrupts and an array size
151 * so it can dispatch multiple interrupts.
152 */
153void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
154{
155 int status;
156 struct irqaction *action;
157 int cpu = smp_processor_id();
158 irq_desc_t *desc = get_irq_desc(irq);
159 irqreturn_t action_ret;
160#ifdef CONFIG_IRQSTACKS
161 struct thread_info *curtp, *irqtp;
162#endif
163
164 kstat_cpu(cpu).irqs[irq]++;
165
166 if (desc->status & IRQ_PER_CPU) {
167 /* no locking required for CPU-local interrupts: */
168 ack_irq(irq);
169 action_ret = handle_IRQ_event(irq, regs, desc->action);
170 desc->handler->end(irq);
171 return;
172 }
173
174 spin_lock(&desc->lock);
175 ack_irq(irq);
176 /*
177 REPLAY is when Linux resends an IRQ that was dropped earlier
178 WAITING is used by probe to mark irqs that are being tested
179 */
180 status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
181 status |= IRQ_PENDING; /* we _want_ to handle it */
182
183 /*
184 * If the IRQ is disabled for whatever reason, we cannot
185 * use the action we have.
186 */
187 action = NULL;
188 if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
189 action = desc->action;
190 if (!action || !action->handler) {
191 ppc_spurious_interrupts++;
192 printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
193 /* We can't call disable_irq here, it would deadlock */
194 if (!desc->depth)
195 desc->depth = 1;
196 desc->status |= IRQ_DISABLED;
197 /* This is not a real spurrious interrupt, we
198 * have to eoi it, so we jump to out
199 */
200 mask_irq(irq);
201 goto out;
202 }
203 status &= ~IRQ_PENDING; /* we commit to handling */
204 status |= IRQ_INPROGRESS; /* we are handling it */
205 }
206 desc->status = status;
207
208 /*
209 * If there is no IRQ handler or it was disabled, exit early.
210 Since we set PENDING, if another processor is handling
211 a different instance of this same irq, the other processor
212 will take care of it.
213 */
214 if (unlikely(!action))
215 goto out;
216
217 /*
218 * Edge triggered interrupts need to remember
219 * pending events.
220 * This applies to any hw interrupts that allow a second
221 * instance of the same irq to arrive while we are in do_IRQ
222 * or in the handler. But the code here only handles the _second_
223 * instance of the irq, not the third or fourth. So it is mostly
224 * useful for irq hardware that does not mask cleanly in an
225 * SMP environment.
226 */
227 for (;;) {
228 spin_unlock(&desc->lock);
229
230#ifdef CONFIG_IRQSTACKS
231 /* Switch to the irq stack to handle this */
232 curtp = current_thread_info();
233 irqtp = hardirq_ctx[smp_processor_id()];
234 if (curtp != irqtp) {
235 irqtp->task = curtp->task;
236 irqtp->flags = 0;
237 action_ret = call_handle_IRQ_event(irq, regs, action, irqtp);
238 irqtp->task = NULL;
239 if (irqtp->flags)
240 set_bits(irqtp->flags, &curtp->flags);
241 } else
242#endif
243 action_ret = handle_IRQ_event(irq, regs, action);
244
245 spin_lock(&desc->lock);
246 if (!noirqdebug)
247 note_interrupt(irq, desc, action_ret, regs);
248 if (likely(!(desc->status & IRQ_PENDING)))
249 break;
250 desc->status &= ~IRQ_PENDING;
251 }
252out:
253 desc->status &= ~IRQ_INPROGRESS;
254 /*
255 * The ->end() handler has to deal with interrupts which got
256 * disabled while the handler was running.
257 */
258 if (desc->handler) {
259 if (desc->handler->end)
260 desc->handler->end(irq);
261 else if (desc->handler->enable)
262 desc->handler->enable(irq);
263 }
264 spin_unlock(&desc->lock);
265}
266
267#ifdef CONFIG_PPC_ISERIES 194#ifdef CONFIG_PPC_ISERIES
268void do_IRQ(struct pt_regs *regs) 195void do_IRQ(struct pt_regs *regs)
269{ 196{
@@ -310,8 +237,11 @@ void do_IRQ(struct pt_regs *regs)
310void do_IRQ(struct pt_regs *regs) 237void do_IRQ(struct pt_regs *regs)
311{ 238{
312 int irq; 239 int irq;
240#ifdef CONFIG_IRQSTACKS
241 struct thread_info *curtp, *irqtp;
242#endif
313 243
314 irq_enter(); 244 irq_enter();
315 245
316#ifdef CONFIG_DEBUG_STACKOVERFLOW 246#ifdef CONFIG_DEBUG_STACKOVERFLOW
317 /* Debugging check for stack overflow: is there less than 2KB free? */ 247 /* Debugging check for stack overflow: is there less than 2KB free? */
@@ -328,20 +258,44 @@ void do_IRQ(struct pt_regs *regs)
328 } 258 }
329#endif 259#endif
330 260
261 /*
262 * Every platform is required to implement ppc_md.get_irq.
263 * This function will either return an irq number or -1 to
264 * indicate there are no more pending.
265 * The value -2 is for buggy hardware and means that this IRQ
266 * has already been handled. -- Tom
267 */
331 irq = ppc_md.get_irq(regs); 268 irq = ppc_md.get_irq(regs);
332 269
333 if (irq >= 0) 270 if (irq >= 0) {
334 ppc_irq_dispatch_handler(regs, irq); 271#ifdef CONFIG_IRQSTACKS
335 else 272 /* Switch to the irq stack to handle this */
336 /* That's not SMP safe ... but who cares ? */ 273 curtp = current_thread_info();
337 ppc_spurious_interrupts++; 274 irqtp = hardirq_ctx[smp_processor_id()];
338 275 if (curtp != irqtp) {
339 irq_exit(); 276 irqtp->task = curtp->task;
277 irqtp->flags = 0;
278 call___do_IRQ(irq, regs, irqtp);
279 irqtp->task = NULL;
280 if (irqtp->flags)
281 set_bits(irqtp->flags, &curtp->flags);
282 } else
283#endif
284 __do_IRQ(irq, regs);
285 } else
286#ifdef CONFIG_PPC32
287 if (irq != -2)
288#endif
289 /* That's not SMP safe ... but who cares ? */
290 ppc_spurious_interrupts++;
291 irq_exit();
340} 292}
293
341#endif /* CONFIG_PPC_ISERIES */ 294#endif /* CONFIG_PPC_ISERIES */
342 295
343void __init init_IRQ(void) 296void __init init_IRQ(void)
344{ 297{
298#ifdef CONFIG_PPC64
345 static int once = 0; 299 static int once = 0;
346 300
347 if (once) 301 if (once)
@@ -349,10 +303,14 @@ void __init init_IRQ(void)
349 303
350 once++; 304 once++;
351 305
306#endif
352 ppc_md.init_IRQ(); 307 ppc_md.init_IRQ();
308#ifdef CONFIG_PPC64
353 irq_ctx_init(); 309 irq_ctx_init();
310#endif
354} 311}
355 312
313#ifdef CONFIG_PPC64
356#ifndef CONFIG_PPC_ISERIES 314#ifndef CONFIG_PPC_ISERIES
357/* 315/*
358 * Virtual IRQ mapping code, used on systems with XICS interrupt controllers. 316 * Virtual IRQ mapping code, used on systems with XICS interrupt controllers.
@@ -517,3 +475,4 @@ static int __init setup_noirqdistrib(char *str)
517} 475}
518 476
519__setup("noirqdistrib", setup_noirqdistrib); 477__setup("noirqdistrib", setup_noirqdistrib);
478#endif /* CONFIG_PPC64 */
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 3e7b2f28ec83..1b3ba8a440a6 100644
--- a/arch/ppc64/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -35,6 +35,7 @@
35#include <asm/time.h> 35#include <asm/time.h>
36#include <asm/iseries/it_exp_vpd_panel.h> 36#include <asm/iseries/it_exp_vpd_panel.h>
37#include <asm/prom.h> 37#include <asm/prom.h>
38#include <asm/vdso_datapage.h>
38 39
39#define MODULE_VERS "1.6" 40#define MODULE_VERS "1.6"
40#define MODULE_NAME "lparcfg" 41#define MODULE_NAME "lparcfg"
@@ -42,7 +43,7 @@
42/* #define LPARCFG_DEBUG */ 43/* #define LPARCFG_DEBUG */
43 44
44/* find a better place for this function... */ 45/* find a better place for this function... */
45void log_plpar_hcall_return(unsigned long rc, char *tag) 46static void log_plpar_hcall_return(unsigned long rc, char *tag)
46{ 47{
47 if (rc == 0) /* success, return */ 48 if (rc == 0) /* success, return */
48 return; 49 return;
@@ -96,7 +97,7 @@ static unsigned long get_purr(void)
96 97
97#define lparcfg_write NULL 98#define lparcfg_write NULL
98 99
99/* 100/*
100 * Methods used to fetch LPAR data when running on an iSeries platform. 101 * Methods used to fetch LPAR data when running on an iSeries platform.
101 */ 102 */
102static int lparcfg_data(struct seq_file *m, void *v) 103static int lparcfg_data(struct seq_file *m, void *v)
@@ -168,7 +169,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
168#endif /* CONFIG_PPC_ISERIES */ 169#endif /* CONFIG_PPC_ISERIES */
169 170
170#ifdef CONFIG_PPC_PSERIES 171#ifdef CONFIG_PPC_PSERIES
171/* 172/*
172 * Methods used to fetch LPAR data when running on a pSeries platform. 173 * Methods used to fetch LPAR data when running on a pSeries platform.
173 */ 174 */
174 175
@@ -177,7 +178,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
177 * entitled_capacity,unallocated_capacity, 178 * entitled_capacity,unallocated_capacity,
178 * aggregation, resource_capability). 179 * aggregation, resource_capability).
179 * 180 *
180 * R4 = Entitled Processor Capacity Percentage. 181 * R4 = Entitled Processor Capacity Percentage.
181 * R5 = Unallocated Processor Capacity Percentage. 182 * R5 = Unallocated Processor Capacity Percentage.
182 * R6 (AABBCCDDEEFFGGHH). 183 * R6 (AABBCCDDEEFFGGHH).
183 * XXXX - reserved (0) 184 * XXXX - reserved (0)
@@ -190,7 +191,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
190 * XX - variable processor Capacity Weight 191 * XX - variable processor Capacity Weight
191 * XX - Unallocated Variable Processor Capacity Weight. 192 * XX - Unallocated Variable Processor Capacity Weight.
192 * XXXX - Active processors in Physical Processor Pool. 193 * XXXX - Active processors in Physical Processor Pool.
193 * XXXX - Processors active on platform. 194 * XXXX - Processors active on platform.
194 */ 195 */
195static unsigned int h_get_ppp(unsigned long *entitled, 196static unsigned int h_get_ppp(unsigned long *entitled,
196 unsigned long *unallocated, 197 unsigned long *unallocated,
@@ -212,11 +213,10 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
212 unsigned long dummy; 213 unsigned long dummy;
213 rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy); 214 rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy);
214 215
215 log_plpar_hcall_return(rc, "H_PIC"); 216 if (rc != H_Authority)
217 log_plpar_hcall_return(rc, "H_PIC");
216} 218}
217 219
218static unsigned long get_purr(void);
219
220/* Track sum of all purrs across all processors. This is used to further */ 220/* Track sum of all purrs across all processors. This is used to further */
221/* calculate usage values by different applications */ 221/* calculate usage values by different applications */
222 222
@@ -273,7 +273,7 @@ static void parse_system_parameter_string(struct seq_file *m)
273 if (!workbuffer) { 273 if (!workbuffer) {
274 printk(KERN_ERR "%s %s kmalloc failure at line %d \n", 274 printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
275 __FILE__, __FUNCTION__, __LINE__); 275 __FILE__, __FUNCTION__, __LINE__);
276 kfree(local_buffer); 276 kfree(local_buffer);
277 return; 277 return;
278 } 278 }
279#ifdef LPARCFG_DEBUG 279#ifdef LPARCFG_DEBUG
@@ -318,8 +318,6 @@ static void parse_system_parameter_string(struct seq_file *m)
318 kfree(local_buffer); 318 kfree(local_buffer);
319} 319}
320 320
321static int lparcfg_count_active_processors(void);
322
323/* Return the number of processors in the system. 321/* Return the number of processors in the system.
324 * This function reads through the device tree and counts 322 * This function reads through the device tree and counts
325 * the virtual processors, this does not include threads. 323 * the virtual processors, this does not include threads.
@@ -371,7 +369,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
371 lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL); 369 lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL);
372 370
373 if (lrdrp == NULL) { 371 if (lrdrp == NULL) {
374 partition_potential_processors = systemcfg->processorCount; 372 partition_potential_processors = vdso_data->processorCount;
375 } else { 373 } else {
376 partition_potential_processors = *(lrdrp + 4); 374 partition_potential_processors = *(lrdrp + 4);
377 } 375 }
@@ -547,7 +545,7 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf,
547 retval = -EIO; 545 retval = -EIO;
548 } 546 }
549 547
550 out: 548out:
551 kfree(kbuf); 549 kfree(kbuf);
552 return retval; 550 return retval;
553} 551}
@@ -560,10 +558,10 @@ static int lparcfg_open(struct inode *inode, struct file *file)
560} 558}
561 559
562struct file_operations lparcfg_fops = { 560struct file_operations lparcfg_fops = {
563 .owner = THIS_MODULE, 561 .owner = THIS_MODULE,
564 .read = seq_read, 562 .read = seq_read,
565 .open = lparcfg_open, 563 .open = lparcfg_open,
566 .release = single_release, 564 .release = single_release,
567}; 565};
568 566
569int __init lparcfg_init(void) 567int __init lparcfg_init(void)
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 3bedb532aed9..f6d84a75ed26 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -519,7 +519,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
519 * 519 *
520 * flush_icache_range(unsigned long start, unsigned long stop) 520 * flush_icache_range(unsigned long start, unsigned long stop)
521 */ 521 */
522_GLOBAL(flush_icache_range) 522_GLOBAL(__flush_icache_range)
523BEGIN_FTR_SECTION 523BEGIN_FTR_SECTION
524 blr /* for 601, do nothing */ 524 blr /* for 601, do nothing */
525END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 525END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
@@ -607,27 +607,6 @@ _GLOBAL(invalidate_dcache_range)
607 sync /* wait for dcbi's to get to ram */ 607 sync /* wait for dcbi's to get to ram */
608 blr 608 blr
609 609
610#ifdef CONFIG_NOT_COHERENT_CACHE
611/*
612 * 40x cores have 8K or 16K dcache and 32 byte line size.
613 * 44x has a 32K dcache and 32 byte line size.
614 * 8xx has 1, 2, 4, 8K variants.
615 * For now, cover the worst case of the 44x.
616 * Must be called with external interrupts disabled.
617 */
618#define CACHE_NWAYS 64
619#define CACHE_NLINES 16
620
621_GLOBAL(flush_dcache_all)
622 li r4, (2 * CACHE_NWAYS * CACHE_NLINES)
623 mtctr r4
624 lis r5, KERNELBASE@h
6251: lwz r3, 0(r5) /* Load one word from every line */
626 addi r5, r5, L1_CACHE_BYTES
627 bdnz 1b
628 blr
629#endif /* CONFIG_NOT_COHERENT_CACHE */
630
631/* 610/*
632 * Flush a particular page from the data cache to RAM. 611 * Flush a particular page from the data cache to RAM.
633 * Note: this is necessary because the instruction cache does *not* 612 * Note: this is necessary because the instruction cache does *not*
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index ae1433da09b2..ae48a002f81a 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -89,12 +89,12 @@ _GLOBAL(call_do_softirq)
89 mtlr r0 89 mtlr r0
90 blr 90 blr
91 91
92_GLOBAL(call_handle_IRQ_event) 92_GLOBAL(call___do_IRQ)
93 mflr r0 93 mflr r0
94 std r0,16(r1) 94 std r0,16(r1)
95 stdu r1,THREAD_SIZE-112(r6) 95 stdu r1,THREAD_SIZE-112(r5)
96 mr r1,r6 96 mr r1,r5
97 bl .handle_IRQ_event 97 bl .__do_IRQ
98 ld r1,0(r1) 98 ld r1,0(r1)
99 ld r0,16(r1) 99 ld r0,16(r1)
100 mtlr r0 100 mtlr r0
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/powerpc/kernel/paca.c
index 3133c72b28ec..a7b68f911eb1 100644
--- a/arch/ppc64/kernel/pacaData.c
+++ b/arch/powerpc/kernel/paca.c
@@ -15,24 +15,16 @@
15#include <asm/processor.h> 15#include <asm/processor.h>
16#include <asm/ptrace.h> 16#include <asm/ptrace.h>
17#include <asm/page.h> 17#include <asm/page.h>
18
19#include <asm/lppaca.h> 18#include <asm/lppaca.h>
20#include <asm/iseries/it_lp_queue.h> 19#include <asm/iseries/it_lp_queue.h>
21#include <asm/paca.h> 20#include <asm/paca.h>
22 21
23static union {
24 struct systemcfg data;
25 u8 page[PAGE_SIZE];
26} systemcfg_store __attribute__((__section__(".data.page.aligned")));
27struct systemcfg *systemcfg = &systemcfg_store.data;
28EXPORT_SYMBOL(systemcfg);
29
30 22
31/* This symbol is provided by the linker - let it fill in the paca 23/* This symbol is provided by the linker - let it fill in the paca
32 * field correctly */ 24 * field correctly */
33extern unsigned long __toc_start; 25extern unsigned long __toc_start;
34 26
35/* The Paca is an array with one entry per processor. Each contains an 27/* The Paca is an array with one entry per processor. Each contains an
36 * lppaca, which contains the information shared between the 28 * lppaca, which contains the information shared between the
37 * hypervisor and Linux. Each also contains an ItLpRegSave area which 29 * hypervisor and Linux. Each also contains an ItLpRegSave area which
38 * is used by the hypervisor to save registers. 30 * is used by the hypervisor to save registers.
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 47d6f7e2ea9f..5dcf4ba05ee8 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -44,6 +44,7 @@
44#include <asm/cputable.h> 44#include <asm/cputable.h>
45#include <asm/btext.h> 45#include <asm/btext.h>
46#include <asm/div64.h> 46#include <asm/div64.h>
47#include <asm/signal.h>
47 48
48#ifdef CONFIG_8xx 49#ifdef CONFIG_8xx
49#include <asm/commproc.h> 50#include <asm/commproc.h>
@@ -56,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
56extern void alignment_exception(struct pt_regs *regs); 57extern void alignment_exception(struct pt_regs *regs);
57extern void program_check_exception(struct pt_regs *regs); 58extern void program_check_exception(struct pt_regs *regs);
58extern void single_step_exception(struct pt_regs *regs); 59extern void single_step_exception(struct pt_regs *regs);
59extern int do_signal(sigset_t *, struct pt_regs *);
60extern int pmac_newworld; 60extern int pmac_newworld;
61extern int sys_sigreturn(struct pt_regs *regs); 61extern int sys_sigreturn(struct pt_regs *regs);
62 62
@@ -188,9 +188,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
188EXPORT_SYMBOL(cuda_request); 188EXPORT_SYMBOL(cuda_request);
189EXPORT_SYMBOL(cuda_poll); 189EXPORT_SYMBOL(cuda_poll);
190#endif /* CONFIG_ADB_CUDA */ 190#endif /* CONFIG_ADB_CUDA */
191#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
192EXPORT_SYMBOL(_machine);
193#endif
194#ifdef CONFIG_PPC_PMAC 191#ifdef CONFIG_PPC_PMAC
195EXPORT_SYMBOL(sys_ctrler); 192EXPORT_SYMBOL(sys_ctrler);
196#endif 193#endif
diff --git a/arch/ppc64/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c
index 24e955ee9487..7ba42a405f41 100644
--- a/arch/ppc64/kernel/proc_ppc64.c
+++ b/arch/powerpc/kernel/proc_ppc64.c
@@ -1,18 +1,16 @@
1/* 1/*
2 * arch/ppc64/kernel/proc_ppc64.c
3 *
4 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation 2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
5 * 3 *
6 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 7 * (at your option) any later version.
10 * 8 *
11 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 12 * GNU General Public License for more details.
15 * 13 *
16 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -25,7 +23,7 @@
25#include <linux/slab.h> 23#include <linux/slab.h>
26#include <linux/kernel.h> 24#include <linux/kernel.h>
27 25
28#include <asm/systemcfg.h> 26#include <asm/vdso_datapage.h>
29#include <asm/rtas.h> 27#include <asm/rtas.h>
30#include <asm/uaccess.h> 28#include <asm/uaccess.h>
31#include <asm/prom.h> 29#include <asm/prom.h>
@@ -53,7 +51,7 @@ static int __init proc_ppc64_create(void)
53 if (!root) 51 if (!root)
54 return 1; 52 return 1;
55 53
56 if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_CELL))) 54 if (!(platform_is_pseries() || _machine == PLATFORM_CELL))
57 return 0; 55 return 0;
58 56
59 if (!proc_mkdir("rtas", root)) 57 if (!proc_mkdir("rtas", root))
@@ -74,7 +72,7 @@ static int __init proc_ppc64_init(void)
74 if (!pde) 72 if (!pde)
75 return 1; 73 return 1;
76 pde->nlink = 1; 74 pde->nlink = 1;
77 pde->data = systemcfg; 75 pde->data = vdso_data;
78 pde->size = PAGE_SIZE; 76 pde->size = PAGE_SIZE;
79 pde->proc_fops = &page_map_fops; 77 pde->proc_fops = &page_map_fops;
80 78
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f645adb57534..6a5b468edb4d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -48,9 +48,6 @@
48#include <asm/machdep.h> 48#include <asm/machdep.h>
49#include <asm/pSeries_reconfig.h> 49#include <asm/pSeries_reconfig.h>
50#include <asm/pci-bridge.h> 50#include <asm/pci-bridge.h>
51#ifdef CONFIG_PPC64
52#include <asm/systemcfg.h>
53#endif
54 51
55#ifdef DEBUG 52#ifdef DEBUG
56#define DBG(fmt...) printk(KERN_ERR fmt) 53#define DBG(fmt...) printk(KERN_ERR fmt)
@@ -74,10 +71,6 @@ struct isa_reg_property {
74typedef int interpret_func(struct device_node *, unsigned long *, 71typedef int interpret_func(struct device_node *, unsigned long *,
75 int, int, int); 72 int, int, int);
76 73
77extern struct rtas_t rtas;
78extern struct lmb lmb;
79extern unsigned long klimit;
80
81static int __initdata dt_root_addr_cells; 74static int __initdata dt_root_addr_cells;
82static int __initdata dt_root_size_cells; 75static int __initdata dt_root_size_cells;
83 76
@@ -391,7 +384,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
391 384
392#ifdef CONFIG_PPC64 385#ifdef CONFIG_PPC64
393 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ 386 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
394 if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) { 387 if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
395 char *name = get_property(ic->parent, "name", NULL); 388 char *name = get_property(ic->parent, "name", NULL);
396 if (name && !strcmp(name, "u3")) 389 if (name && !strcmp(name, "u3"))
397 np->intrs[intrcount].line += 128; 390 np->intrs[intrcount].line += 128;
@@ -1087,9 +1080,9 @@ void __init unflatten_device_tree(void)
1087static int __init early_init_dt_scan_cpus(unsigned long node, 1080static int __init early_init_dt_scan_cpus(unsigned long node,
1088 const char *uname, int depth, void *data) 1081 const char *uname, int depth, void *data)
1089{ 1082{
1090 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
1091 u32 *prop; 1083 u32 *prop;
1092 unsigned long size = 0; 1084 unsigned long size;
1085 char *type = of_get_flat_dt_prop(node, "device_type", &size);
1093 1086
1094 /* We are scanning "cpu" nodes only */ 1087 /* We are scanning "cpu" nodes only */
1095 if (type == NULL || strcmp(type, "cpu") != 0) 1088 if (type == NULL || strcmp(type, "cpu") != 0)
@@ -1115,7 +1108,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
1115 1108
1116#ifdef CONFIG_ALTIVEC 1109#ifdef CONFIG_ALTIVEC
1117 /* Check if we have a VMX and eventually update CPU features */ 1110 /* Check if we have a VMX and eventually update CPU features */
1118 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", &size); 1111 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
1119 if (prop && (*prop) > 0) { 1112 if (prop && (*prop) > 0) {
1120 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; 1113 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
1121 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; 1114 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
@@ -1161,13 +1154,9 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
1161 prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); 1154 prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
1162 if (prop == NULL) 1155 if (prop == NULL)
1163 return 0; 1156 return 0;
1164#ifdef CONFIG_PPC64
1165 systemcfg->platform = *prop;
1166#else
1167#ifdef CONFIG_PPC_MULTIPLATFORM 1157#ifdef CONFIG_PPC_MULTIPLATFORM
1168 _machine = *prop; 1158 _machine = *prop;
1169#endif 1159#endif
1170#endif
1171 1160
1172#ifdef CONFIG_PPC64 1161#ifdef CONFIG_PPC64
1173 /* check if iommu is forced on or off */ 1162 /* check if iommu is forced on or off */
@@ -1264,7 +1253,14 @@ static int __init early_init_dt_scan_memory(unsigned long node,
1264 unsigned long l; 1253 unsigned long l;
1265 1254
1266 /* We are scanning "memory" nodes only */ 1255 /* We are scanning "memory" nodes only */
1267 if (type == NULL || strcmp(type, "memory") != 0) 1256 if (type == NULL) {
1257 /*
1258 * The longtrail doesn't have a device_type on the
1259 * /memory node, so look for the node called /memory@0.
1260 */
1261 if (depth != 1 || strcmp(uname, "memory@0") != 0)
1262 return 0;
1263 } else if (strcmp(type, "memory") != 0)
1268 return 0; 1264 return 0;
1269 1265
1270 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); 1266 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
@@ -1339,9 +1335,6 @@ void __init early_init_devtree(void *params)
1339 of_scan_flat_dt(early_init_dt_scan_memory, NULL); 1335 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
1340 lmb_enforce_memory_limit(memory_limit); 1336 lmb_enforce_memory_limit(memory_limit);
1341 lmb_analyze(); 1337 lmb_analyze();
1342#ifdef CONFIG_PPC64
1343 systemcfg->physicalMemorySize = lmb_phys_mem_size();
1344#endif
1345 lmb_reserve(0, __pa(klimit)); 1338 lmb_reserve(0, __pa(klimit));
1346 1339
1347 DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); 1340 DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
@@ -1908,7 +1901,7 @@ static int of_finish_dynamic_node(struct device_node *node,
1908 /* We don't support that function on PowerMac, at least 1901 /* We don't support that function on PowerMac, at least
1909 * not yet 1902 * not yet
1910 */ 1903 */
1911 if (systemcfg->platform == PLATFORM_POWERMAC) 1904 if (_machine == PLATFORM_POWERMAC)
1912 return -ENODEV; 1905 return -ENODEV;
1913 1906
1914 /* fix up new node's linux_phandle field */ 1907 /* fix up new node's linux_phandle field */
@@ -1992,9 +1985,11 @@ int prom_add_property(struct device_node* np, struct property* prop)
1992 *next = prop; 1985 *next = prop;
1993 write_unlock(&devtree_lock); 1986 write_unlock(&devtree_lock);
1994 1987
1988#ifdef CONFIG_PROC_DEVICETREE
1995 /* try to add to proc as well if it was initialized */ 1989 /* try to add to proc as well if it was initialized */
1996 if (np->pde) 1990 if (np->pde)
1997 proc_device_tree_add_prop(np->pde, prop); 1991 proc_device_tree_add_prop(np->pde, prop);
1992#endif /* CONFIG_PROC_DEVICETREE */
1998 1993
1999 return 0; 1994 return 0;
2000} 1995}
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 6dc33d19fc2a..4ce0105c308e 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -94,11 +94,17 @@ extern const struct linux_logo logo_linux_clut224;
94#ifdef CONFIG_PPC64 94#ifdef CONFIG_PPC64
95#define RELOC(x) (*PTRRELOC(&(x))) 95#define RELOC(x) (*PTRRELOC(&(x)))
96#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x)) 96#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
97#define OF_WORKAROUNDS 0
97#else 98#else
98#define RELOC(x) (x) 99#define RELOC(x) (x)
99#define ADDR(x) (u32) (x) 100#define ADDR(x) (u32) (x)
101#define OF_WORKAROUNDS of_workarounds
102int of_workarounds;
100#endif 103#endif
101 104
105#define OF_WA_CLAIM 1 /* do phys/virt claim separately, then map */
106#define OF_WA_LONGTRAIL 2 /* work around longtrail bugs */
107
102#define PROM_BUG() do { \ 108#define PROM_BUG() do { \
103 prom_printf("kernel BUG at %s line 0x%x!\n", \ 109 prom_printf("kernel BUG at %s line 0x%x!\n", \
104 RELOC(__FILE__), __LINE__); \ 110 RELOC(__FILE__), __LINE__); \
@@ -111,11 +117,6 @@ extern const struct linux_logo logo_linux_clut224;
111#define prom_debug(x...) 117#define prom_debug(x...)
112#endif 118#endif
113 119
114#ifdef CONFIG_PPC32
115#define PLATFORM_POWERMAC _MACH_Pmac
116#define PLATFORM_CHRP _MACH_chrp
117#endif
118
119 120
120typedef u32 prom_arg_t; 121typedef u32 prom_arg_t;
121 122
@@ -128,10 +129,11 @@ struct prom_args {
128 129
129struct prom_t { 130struct prom_t {
130 ihandle root; 131 ihandle root;
131 ihandle chosen; 132 phandle chosen;
132 int cpu; 133 int cpu;
133 ihandle stdout; 134 ihandle stdout;
134 ihandle mmumap; 135 ihandle mmumap;
136 ihandle memory;
135}; 137};
136 138
137struct mem_map_entry { 139struct mem_map_entry {
@@ -360,16 +362,36 @@ static void __init prom_printf(const char *format, ...)
360static unsigned int __init prom_claim(unsigned long virt, unsigned long size, 362static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
361 unsigned long align) 363 unsigned long align)
362{ 364{
363 int ret;
364 struct prom_t *_prom = &RELOC(prom); 365 struct prom_t *_prom = &RELOC(prom);
365 366
366 ret = call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size, 367 if (align == 0 && (OF_WORKAROUNDS & OF_WA_CLAIM)) {
367 (prom_arg_t)align); 368 /*
368 if (ret != -1 && _prom->mmumap != 0) 369 * Old OF requires we claim physical and virtual separately
369 /* old pmacs need us to map as well */ 370 * and then map explicitly (assuming virtual mode)
371 */
372 int ret;
373 prom_arg_t result;
374
375 ret = call_prom_ret("call-method", 5, 2, &result,
376 ADDR("claim"), _prom->memory,
377 align, size, virt);
378 if (ret != 0 || result == -1)
379 return -1;
380 ret = call_prom_ret("call-method", 5, 2, &result,
381 ADDR("claim"), _prom->mmumap,
382 align, size, virt);
383 if (ret != 0) {
384 call_prom("call-method", 4, 1, ADDR("release"),
385 _prom->memory, size, virt);
386 return -1;
387 }
388 /* the 0x12 is M (coherence) + PP == read/write */
370 call_prom("call-method", 6, 1, 389 call_prom("call-method", 6, 1,
371 ADDR("map"), _prom->mmumap, 0, size, virt, virt); 390 ADDR("map"), _prom->mmumap, 0x12, size, virt, virt);
372 return ret; 391 return virt;
392 }
393 return call_prom("claim", 3, 1, (prom_arg_t)virt, (prom_arg_t)size,
394 (prom_arg_t)align);
373} 395}
374 396
375static void __init __attribute__((noreturn)) prom_panic(const char *reason) 397static void __init __attribute__((noreturn)) prom_panic(const char *reason)
@@ -415,11 +437,52 @@ static int inline prom_getproplen(phandle node, const char *pname)
415 return call_prom("getproplen", 2, 1, node, ADDR(pname)); 437 return call_prom("getproplen", 2, 1, node, ADDR(pname));
416} 438}
417 439
418static int inline prom_setprop(phandle node, const char *pname, 440static void add_string(char **str, const char *q)
419 void *value, size_t valuelen)
420{ 441{
421 return call_prom("setprop", 4, 1, node, ADDR(pname), 442 char *p = *str;
422 (u32)(unsigned long) value, (u32) valuelen); 443
444 while (*q)
445 *p++ = *q++;
446 *p++ = ' ';
447 *str = p;
448}
449
450static char *tohex(unsigned int x)
451{
452 static char digits[] = "0123456789abcdef";
453 static char result[9];
454 int i;
455
456 result[8] = 0;
457 i = 8;
458 do {
459 --i;
460 result[i] = digits[x & 0xf];
461 x >>= 4;
462 } while (x != 0 && i > 0);
463 return &result[i];
464}
465
466static int __init prom_setprop(phandle node, const char *nodename,
467 const char *pname, void *value, size_t valuelen)
468{
469 char cmd[256], *p;
470
471 if (!(OF_WORKAROUNDS & OF_WA_LONGTRAIL))
472 return call_prom("setprop", 4, 1, node, ADDR(pname),
473 (u32)(unsigned long) value, (u32) valuelen);
474
475 /* gah... setprop doesn't work on longtrail, have to use interpret */
476 p = cmd;
477 add_string(&p, "dev");
478 add_string(&p, nodename);
479 add_string(&p, tohex((u32)(unsigned long) value));
480 add_string(&p, tohex(valuelen));
481 add_string(&p, tohex(ADDR(pname)));
482 add_string(&p, tohex(strlen(RELOC(pname))));
483 add_string(&p, "property");
484 *p = 0;
485 return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
423} 486}
424 487
425/* We can't use the standard versions because of RELOC headaches. */ 488/* We can't use the standard versions because of RELOC headaches. */
@@ -980,7 +1043,7 @@ static void __init prom_instantiate_rtas(void)
980 1043
981 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); 1044 rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
982 if (!IHANDLE_VALID(rtas_inst)) { 1045 if (!IHANDLE_VALID(rtas_inst)) {
983 prom_printf("opening rtas package failed"); 1046 prom_printf("opening rtas package failed (%x)\n", rtas_inst);
984 return; 1047 return;
985 } 1048 }
986 1049
@@ -988,7 +1051,7 @@ static void __init prom_instantiate_rtas(void)
988 1051
989 if (call_prom_ret("call-method", 3, 2, &entry, 1052 if (call_prom_ret("call-method", 3, 2, &entry,
990 ADDR("instantiate-rtas"), 1053 ADDR("instantiate-rtas"),
991 rtas_inst, base) == PROM_ERROR 1054 rtas_inst, base) != 0
992 || entry == 0) { 1055 || entry == 0) {
993 prom_printf(" failed\n"); 1056 prom_printf(" failed\n");
994 return; 1057 return;
@@ -997,8 +1060,10 @@ static void __init prom_instantiate_rtas(void)
997 1060
998 reserve_mem(base, size); 1061 reserve_mem(base, size);
999 1062
1000 prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); 1063 prom_setprop(rtas_node, "/rtas", "linux,rtas-base",
1001 prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); 1064 &base, sizeof(base));
1065 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1066 &entry, sizeof(entry));
1002 1067
1003 prom_debug("rtas base = 0x%x\n", base); 1068 prom_debug("rtas base = 0x%x\n", base);
1004 prom_debug("rtas entry = 0x%x\n", entry); 1069 prom_debug("rtas entry = 0x%x\n", entry);
@@ -1089,10 +1154,6 @@ static void __init prom_initialize_tce_table(void)
1089 if (base < local_alloc_bottom) 1154 if (base < local_alloc_bottom)
1090 local_alloc_bottom = base; 1155 local_alloc_bottom = base;
1091 1156
1092 /* Save away the TCE table attributes for later use. */
1093 prom_setprop(node, "linux,tce-base", &base, sizeof(base));
1094 prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
1095
1096 /* It seems OF doesn't null-terminate the path :-( */ 1157 /* It seems OF doesn't null-terminate the path :-( */
1097 memset(path, 0, sizeof(path)); 1158 memset(path, 0, sizeof(path));
1098 /* Call OF to setup the TCE hardware */ 1159 /* Call OF to setup the TCE hardware */
@@ -1101,6 +1162,10 @@ static void __init prom_initialize_tce_table(void)
1101 prom_printf("package-to-path failed\n"); 1162 prom_printf("package-to-path failed\n");
1102 } 1163 }
1103 1164
1165 /* Save away the TCE table attributes for later use. */
1166 prom_setprop(node, path, "linux,tce-base", &base, sizeof(base));
1167 prom_setprop(node, path, "linux,tce-size", &minsize, sizeof(minsize));
1168
1104 prom_debug("TCE table: %s\n", path); 1169 prom_debug("TCE table: %s\n", path);
1105 prom_debug("\tnode = 0x%x\n", node); 1170 prom_debug("\tnode = 0x%x\n", node);
1106 prom_debug("\tbase = 0x%x\n", base); 1171 prom_debug("\tbase = 0x%x\n", base);
@@ -1342,6 +1407,7 @@ static void __init prom_init_client_services(unsigned long pp)
1342/* 1407/*
1343 * For really old powermacs, we need to map things we claim. 1408 * For really old powermacs, we need to map things we claim.
1344 * For that, we need the ihandle of the mmu. 1409 * For that, we need the ihandle of the mmu.
1410 * Also, on the longtrail, we need to work around other bugs.
1345 */ 1411 */
1346static void __init prom_find_mmu(void) 1412static void __init prom_find_mmu(void)
1347{ 1413{
@@ -1355,12 +1421,19 @@ static void __init prom_find_mmu(void)
1355 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0) 1421 if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)
1356 return; 1422 return;
1357 version[sizeof(version) - 1] = 0; 1423 version[sizeof(version) - 1] = 0;
1358 prom_printf("OF version is '%s'\n", version);
1359 /* XXX might need to add other versions here */ 1424 /* XXX might need to add other versions here */
1360 if (strcmp(version, "Open Firmware, 1.0.5") != 0) 1425 if (strcmp(version, "Open Firmware, 1.0.5") == 0)
1426 of_workarounds = OF_WA_CLAIM;
1427 else if (strncmp(version, "FirmWorks,3.", 12) == 0) {
1428 of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;
1429 call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");
1430 } else
1361 return; 1431 return;
1432 _prom->memory = call_prom("open", 1, 1, ADDR("/memory"));
1362 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap, 1433 prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,
1363 sizeof(_prom->mmumap)); 1434 sizeof(_prom->mmumap));
1435 if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))
1436 of_workarounds &= ~OF_WA_CLAIM; /* hmmm */
1364} 1437}
1365#else 1438#else
1366#define prom_find_mmu() 1439#define prom_find_mmu()
@@ -1382,16 +1455,17 @@ static void __init prom_init_stdout(void)
1382 memset(path, 0, 256); 1455 memset(path, 0, 256);
1383 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255); 1456 call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
1384 val = call_prom("instance-to-package", 1, 1, _prom->stdout); 1457 val = call_prom("instance-to-package", 1, 1, _prom->stdout);
1385 prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val)); 1458 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",
1459 &val, sizeof(val));
1386 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device)); 1460 prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
1387 prom_setprop(_prom->chosen, "linux,stdout-path", 1461 prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",
1388 RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1); 1462 path, strlen(path) + 1);
1389 1463
1390 /* If it's a display, note it */ 1464 /* If it's a display, note it */
1391 memset(type, 0, sizeof(type)); 1465 memset(type, 0, sizeof(type));
1392 prom_getprop(val, "device_type", type, sizeof(type)); 1466 prom_getprop(val, "device_type", type, sizeof(type));
1393 if (strcmp(type, RELOC("display")) == 0) 1467 if (strcmp(type, RELOC("display")) == 0)
1394 prom_setprop(val, "linux,boot-display", NULL, 0); 1468 prom_setprop(val, path, "linux,boot-display", NULL, 0);
1395} 1469}
1396 1470
1397static void __init prom_close_stdin(void) 1471static void __init prom_close_stdin(void)
@@ -1514,7 +1588,7 @@ static void __init prom_check_displays(void)
1514 1588
1515 /* Success */ 1589 /* Success */
1516 prom_printf("done\n"); 1590 prom_printf("done\n");
1517 prom_setprop(node, "linux,opened", NULL, 0); 1591 prom_setprop(node, path, "linux,opened", NULL, 0);
1518 1592
1519 /* Setup a usable color table when the appropriate 1593 /* Setup a usable color table when the appropriate
1520 * method is available. Should update this to set-colors */ 1594 * method is available. Should update this to set-colors */
@@ -1884,9 +1958,11 @@ static void __init fixup_device_tree(void)
1884 /* interrupt on this revision of u3 is number 0 and level */ 1958 /* interrupt on this revision of u3 is number 0 and level */
1885 interrupts[0] = 0; 1959 interrupts[0] = 0;
1886 interrupts[1] = 1; 1960 interrupts[1] = 1;
1887 prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts)); 1961 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupts",
1962 &interrupts, sizeof(interrupts));
1888 parent = (u32)mpic; 1963 parent = (u32)mpic;
1889 prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent)); 1964 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
1965 &parent, sizeof(parent));
1890#endif 1966#endif
1891} 1967}
1892 1968
@@ -1922,11 +1998,11 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
1922 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; 1998 RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
1923 1999
1924 val = RELOC(prom_initrd_start); 2000 val = RELOC(prom_initrd_start);
1925 prom_setprop(_prom->chosen, "linux,initrd-start", &val, 2001 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
1926 sizeof(val)); 2002 &val, sizeof(val));
1927 val = RELOC(prom_initrd_end); 2003 val = RELOC(prom_initrd_end);
1928 prom_setprop(_prom->chosen, "linux,initrd-end", &val, 2004 prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
1929 sizeof(val)); 2005 &val, sizeof(val));
1930 2006
1931 reserve_mem(RELOC(prom_initrd_start), 2007 reserve_mem(RELOC(prom_initrd_start),
1932 RELOC(prom_initrd_end) - RELOC(prom_initrd_start)); 2008 RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
@@ -1969,14 +2045,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
1969 prom_init_client_services(pp); 2045 prom_init_client_services(pp);
1970 2046
1971 /* 2047 /*
1972 * Init prom stdout device 2048 * See if this OF is old enough that we need to do explicit maps
2049 * and other workarounds
1973 */ 2050 */
1974 prom_init_stdout(); 2051 prom_find_mmu();
1975 2052
1976 /* 2053 /*
1977 * See if this OF is old enough that we need to do explicit maps 2054 * Init prom stdout device
1978 */ 2055 */
1979 prom_find_mmu(); 2056 prom_init_stdout();
1980 2057
1981 /* 2058 /*
1982 * Check for an initrd 2059 * Check for an initrd
@@ -1989,14 +2066,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
1989 */ 2066 */
1990 RELOC(of_platform) = prom_find_machine_type(); 2067 RELOC(of_platform) = prom_find_machine_type();
1991 getprop_rval = RELOC(of_platform); 2068 getprop_rval = RELOC(of_platform);
1992 prom_setprop(_prom->chosen, "linux,platform", 2069 prom_setprop(_prom->chosen, "/chosen", "linux,platform",
1993 &getprop_rval, sizeof(getprop_rval)); 2070 &getprop_rval, sizeof(getprop_rval));
1994 2071
1995#ifdef CONFIG_PPC_PSERIES 2072#ifdef CONFIG_PPC_PSERIES
1996 /* 2073 /*
1997 * On pSeries, inform the firmware about our capabilities 2074 * On pSeries, inform the firmware about our capabilities
1998 */ 2075 */
1999 if (RELOC(of_platform) & PLATFORM_PSERIES) 2076 if (RELOC(of_platform) == PLATFORM_PSERIES ||
2077 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
2000 prom_send_capabilities(); 2078 prom_send_capabilities();
2001#endif 2079#endif
2002 2080
@@ -2050,21 +2128,23 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2050 * Fill in some infos for use by the kernel later on 2128 * Fill in some infos for use by the kernel later on
2051 */ 2129 */
2052 if (RELOC(prom_memory_limit)) 2130 if (RELOC(prom_memory_limit))
2053 prom_setprop(_prom->chosen, "linux,memory-limit", 2131 prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
2054 &RELOC(prom_memory_limit), 2132 &RELOC(prom_memory_limit),
2055 sizeof(prom_memory_limit)); 2133 sizeof(prom_memory_limit));
2056#ifdef CONFIG_PPC64 2134#ifdef CONFIG_PPC64
2057 if (RELOC(ppc64_iommu_off)) 2135 if (RELOC(ppc64_iommu_off))
2058 prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0); 2136 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2137 NULL, 0);
2059 2138
2060 if (RELOC(iommu_force_on)) 2139 if (RELOC(iommu_force_on))
2061 prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0); 2140 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2141 NULL, 0);
2062 2142
2063 if (RELOC(prom_tce_alloc_start)) { 2143 if (RELOC(prom_tce_alloc_start)) {
2064 prom_setprop(_prom->chosen, "linux,tce-alloc-start", 2144 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-start",
2065 &RELOC(prom_tce_alloc_start), 2145 &RELOC(prom_tce_alloc_start),
2066 sizeof(prom_tce_alloc_start)); 2146 sizeof(prom_tce_alloc_start));
2067 prom_setprop(_prom->chosen, "linux,tce-alloc-end", 2147 prom_setprop(_prom->chosen, "/chosen", "linux,tce-alloc-end",
2068 &RELOC(prom_tce_alloc_end), 2148 &RELOC(prom_tce_alloc_end),
2069 sizeof(prom_tce_alloc_end)); 2149 sizeof(prom_tce_alloc_end));
2070 } 2150 }
@@ -2081,8 +2161,13 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2081 prom_printf("copying OF device tree ...\n"); 2161 prom_printf("copying OF device tree ...\n");
2082 flatten_device_tree(); 2162 flatten_device_tree();
2083 2163
2084 /* in case stdin is USB and still active on IBM machines... */ 2164 /*
2085 prom_close_stdin(); 2165 * in case stdin is USB and still active on IBM machines...
2166 * Unfortunately quiesce crashes on some powermacs if we have
2167 * closed stdin already (in particular the powerbook 101).
2168 */
2169 if (RELOC(of_platform) != PLATFORM_POWERMAC)
2170 prom_close_stdin();
2086 2171
2087 /* 2172 /*
2088 * Call OF "quiesce" method to shut down pending DMA's from 2173 * Call OF "quiesce" method to shut down pending DMA's from
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 5bdd5b079d96..7a95b8a28354 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -32,7 +32,6 @@
32#include <asm/rtas.h> 32#include <asm/rtas.h>
33#include <asm/machdep.h> /* for ppc_md */ 33#include <asm/machdep.h> /* for ppc_md */
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/systemcfg.h>
36 35
37/* Token for Sensors */ 36/* Token for Sensors */
38#define KEY_SWITCH 0x0001 37#define KEY_SWITCH 0x0001
@@ -259,7 +258,7 @@ static int __init proc_rtas_init(void)
259{ 258{
260 struct proc_dir_entry *entry; 259 struct proc_dir_entry *entry;
261 260
262 if (!(systemcfg->platform & PLATFORM_PSERIES)) 261 if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR)
263 return 1; 262 return 1;
264 263
265 rtas_node = of_find_node_by_name(NULL, "rtas"); 264 rtas_node = of_find_node_by_name(NULL, "rtas");
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 9d4e07f6f1ec..4283fa33f784 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -29,9 +29,6 @@
29#include <asm/delay.h> 29#include <asm/delay.h>
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
31#include <asm/lmb.h> 31#include <asm/lmb.h>
32#ifdef CONFIG_PPC64
33#include <asm/systemcfg.h>
34#endif
35 32
36struct rtas_t rtas = { 33struct rtas_t rtas = {
37 .lock = SPIN_LOCK_UNLOCKED 34 .lock = SPIN_LOCK_UNLOCKED
@@ -671,7 +668,7 @@ void __init rtas_initialize(void)
671 * the stop-self token if any 668 * the stop-self token if any
672 */ 669 */
673#ifdef CONFIG_PPC64 670#ifdef CONFIG_PPC64
674 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) 671 if (_machine == PLATFORM_PSERIES_LPAR)
675 rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); 672 rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
676#endif 673#endif
677 rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); 674 rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 3c3f19192fcc..0e5a8e116653 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -5,19 +5,19 @@
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 6 *
7 * RTAS specific routines for PCI. 7 * RTAS specific routines for PCI.
8 * 8 *
9 * Based on code from pci.c, chrp_pci.c and pSeries_pci.c 9 * Based on code from pci.c, chrp_pci.c and pSeries_pci.c
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 14 * (at your option) any later version.
15 * 15 *
16 * This program is distributed in the hope that it will be useful, 16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details. 19 * GNU General Public License for more details.
20 * 20 *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -47,7 +47,7 @@ static int write_pci_config;
47static int ibm_read_pci_config; 47static int ibm_read_pci_config;
48static int ibm_write_pci_config; 48static int ibm_write_pci_config;
49 49
50static int config_access_valid(struct pci_dn *dn, int where) 50static inline int config_access_valid(struct pci_dn *dn, int where)
51{ 51{
52 if (where < 256) 52 if (where < 256)
53 return 1; 53 return 1;
@@ -72,16 +72,14 @@ static int of_device_available(struct device_node * dn)
72 return 0; 72 return 0;
73} 73}
74 74
75static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) 75static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
76{ 76{
77 int returnval = -1; 77 int returnval = -1;
78 unsigned long buid, addr; 78 unsigned long buid, addr;
79 int ret; 79 int ret;
80 struct pci_dn *pdn;
81 80
82 if (!dn || !dn->data) 81 if (!pdn)
83 return PCIBIOS_DEVICE_NOT_FOUND; 82 return PCIBIOS_DEVICE_NOT_FOUND;
84 pdn = dn->data;
85 if (!config_access_valid(pdn, where)) 83 if (!config_access_valid(pdn, where))
86 return PCIBIOS_BAD_REGISTER_NUMBER; 84 return PCIBIOS_BAD_REGISTER_NUMBER;
87 85
@@ -90,7 +88,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
90 buid = pdn->phb->buid; 88 buid = pdn->phb->buid;
91 if (buid) { 89 if (buid) {
92 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, 90 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
93 addr, buid >> 32, buid & 0xffffffff, size); 91 addr, BUID_HI(buid), BUID_LO(buid), size);
94 } else { 92 } else {
95 ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size); 93 ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
96 } 94 }
@@ -100,7 +98,7 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
100 return PCIBIOS_DEVICE_NOT_FOUND; 98 return PCIBIOS_DEVICE_NOT_FOUND;
101 99
102 if (returnval == EEH_IO_ERROR_VALUE(size) && 100 if (returnval == EEH_IO_ERROR_VALUE(size) &&
103 eeh_dn_check_failure (dn, NULL)) 101 eeh_dn_check_failure (pdn->node, NULL))
104 return PCIBIOS_DEVICE_NOT_FOUND; 102 return PCIBIOS_DEVICE_NOT_FOUND;
105 103
106 return PCIBIOS_SUCCESSFUL; 104 return PCIBIOS_SUCCESSFUL;
@@ -118,23 +116,23 @@ static int rtas_pci_read_config(struct pci_bus *bus,
118 busdn = bus->sysdata; /* must be a phb */ 116 busdn = bus->sysdata; /* must be a phb */
119 117
120 /* Search only direct children of the bus */ 118 /* Search only direct children of the bus */
121 for (dn = busdn->child; dn; dn = dn->sibling) 119 for (dn = busdn->child; dn; dn = dn->sibling) {
122 if (dn->data && PCI_DN(dn)->devfn == devfn 120 struct pci_dn *pdn = PCI_DN(dn);
121 if (pdn && pdn->devfn == devfn
123 && of_device_available(dn)) 122 && of_device_available(dn))
124 return rtas_read_config(dn, where, size, val); 123 return rtas_read_config(pdn, where, size, val);
124 }
125 125
126 return PCIBIOS_DEVICE_NOT_FOUND; 126 return PCIBIOS_DEVICE_NOT_FOUND;
127} 127}
128 128
129int rtas_write_config(struct device_node *dn, int where, int size, u32 val) 129int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
130{ 130{
131 unsigned long buid, addr; 131 unsigned long buid, addr;
132 int ret; 132 int ret;
133 struct pci_dn *pdn;
134 133
135 if (!dn || !dn->data) 134 if (!pdn)
136 return PCIBIOS_DEVICE_NOT_FOUND; 135 return PCIBIOS_DEVICE_NOT_FOUND;
137 pdn = dn->data;
138 if (!config_access_valid(pdn, where)) 136 if (!config_access_valid(pdn, where))
139 return PCIBIOS_BAD_REGISTER_NUMBER; 137 return PCIBIOS_BAD_REGISTER_NUMBER;
140 138
@@ -142,7 +140,8 @@ int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
142 (pdn->devfn << 8) | (where & 0xff); 140 (pdn->devfn << 8) | (where & 0xff);
143 buid = pdn->phb->buid; 141 buid = pdn->phb->buid;
144 if (buid) { 142 if (buid) {
145 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); 143 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
144 BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
146 } else { 145 } else {
147 ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val); 146 ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
148 } 147 }
@@ -165,10 +164,12 @@ static int rtas_pci_write_config(struct pci_bus *bus,
165 busdn = bus->sysdata; /* must be a phb */ 164 busdn = bus->sysdata; /* must be a phb */
166 165
167 /* Search only direct children of the bus */ 166 /* Search only direct children of the bus */
168 for (dn = busdn->child; dn; dn = dn->sibling) 167 for (dn = busdn->child; dn; dn = dn->sibling) {
169 if (dn->data && PCI_DN(dn)->devfn == devfn 168 struct pci_dn *pdn = PCI_DN(dn);
169 if (pdn && pdn->devfn == devfn
170 && of_device_available(dn)) 170 && of_device_available(dn))
171 return rtas_write_config(dn, where, size, val); 171 return rtas_write_config(pdn, where, size, val);
172 }
172 return PCIBIOS_DEVICE_NOT_FOUND; 173 return PCIBIOS_DEVICE_NOT_FOUND;
173} 174}
174 175
@@ -221,7 +222,7 @@ static void python_countermeasures(struct device_node *dev,
221 /* Python's register file is 1 MB in size. */ 222 /* Python's register file is 1 MB in size. */
222 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); 223 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
223 224
224 /* 225 /*
225 * Firmware doesn't always clear this bit which is critical 226 * Firmware doesn't always clear this bit which is critical
226 * for good performance - Anton 227 * for good performance - Anton
227 */ 228 */
@@ -292,7 +293,7 @@ static int phb_set_bus_ranges(struct device_node *dev,
292 if (bus_range == NULL || len < 2 * sizeof(int)) { 293 if (bus_range == NULL || len < 2 * sizeof(int)) {
293 return 1; 294 return 1;
294 } 295 }
295 296
296 phb->first_busno = bus_range[0]; 297 phb->first_busno = bus_range[0];
297 phb->last_busno = bus_range[1]; 298 phb->last_busno = bus_range[1];
298 299
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index e22856ecb5a0..33e7f2c7f194 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -33,6 +33,7 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/prom.h> 34#include <asm/prom.h>
35#include <asm/processor.h> 35#include <asm/processor.h>
36#include <asm/vdso_datapage.h>
36#include <asm/pgtable.h> 37#include <asm/pgtable.h>
37#include <asm/smp.h> 38#include <asm/smp.h>
38#include <asm/elf.h> 39#include <asm/elf.h>
@@ -51,6 +52,9 @@
51#include <asm/page.h> 52#include <asm/page.h>
52#include <asm/mmu.h> 53#include <asm/mmu.h>
53#include <asm/lmb.h> 54#include <asm/lmb.h>
55#include <asm/xmon.h>
56
57#include "setup.h"
54 58
55#undef DEBUG 59#undef DEBUG
56 60
@@ -60,6 +64,13 @@
60#define DBG(fmt...) 64#define DBG(fmt...)
61#endif 65#endif
62 66
67#ifdef CONFIG_PPC_MULTIPLATFORM
68int _machine = 0;
69EXPORT_SYMBOL(_machine);
70#endif
71
72unsigned long klimit = (unsigned long) _end;
73
63/* 74/*
64 * This still seems to be needed... -- paulus 75 * This still seems to be needed... -- paulus
65 */ 76 */
@@ -433,10 +444,8 @@ void __init check_for_initrd(void)
433 if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && 444 if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
434 initrd_end > initrd_start) 445 initrd_end > initrd_start)
435 ROOT_DEV = Root_RAM0; 446 ROOT_DEV = Root_RAM0;
436 else { 447 else
437 printk("Bogus initrd %08lx %08lx\n", initrd_start, initrd_end);
438 initrd_start = initrd_end = 0; 448 initrd_start = initrd_end = 0;
439 }
440 449
441 if (initrd_start) 450 if (initrd_start)
442 printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end); 451 printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end);
@@ -510,8 +519,8 @@ void __init smp_setup_cpu_maps(void)
510 * On pSeries LPAR, we need to know how many cpus 519 * On pSeries LPAR, we need to know how many cpus
511 * could possibly be added to this partition. 520 * could possibly be added to this partition.
512 */ 521 */
513 if (systemcfg->platform == PLATFORM_PSERIES_LPAR && 522 if (_machine == PLATFORM_PSERIES_LPAR &&
514 (dn = of_find_node_by_path("/rtas"))) { 523 (dn = of_find_node_by_path("/rtas"))) {
515 int num_addr_cell, num_size_cell, maxcpus; 524 int num_addr_cell, num_size_cell, maxcpus;
516 unsigned int *ireg; 525 unsigned int *ireg;
517 526
@@ -555,7 +564,27 @@ void __init smp_setup_cpu_maps(void)
555 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); 564 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
556 } 565 }
557 566
558 systemcfg->processorCount = num_present_cpus(); 567 vdso_data->processorCount = num_present_cpus();
559#endif /* CONFIG_PPC64 */ 568#endif /* CONFIG_PPC64 */
560} 569}
561#endif /* CONFIG_SMP */ 570#endif /* CONFIG_SMP */
571
572#ifdef CONFIG_XMON
573static int __init early_xmon(char *p)
574{
575 /* ensure xmon is enabled */
576 if (p) {
577 if (strncmp(p, "on", 2) == 0)
578 xmon_init(1);
579 if (strncmp(p, "off", 3) == 0)
580 xmon_init(0);
581 if (strncmp(p, "early", 5) != 0)
582 return 0;
583 }
584 xmon_init(1);
585 debugger(NULL);
586
587 return 0;
588}
589early_param("xmon", early_xmon);
590#endif
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
new file mode 100644
index 000000000000..2ebba755272e
--- /dev/null
+++ b/arch/powerpc/kernel/setup.h
@@ -0,0 +1,6 @@
1#ifndef _POWERPC_KERNEL_SETUP_H
2#define _POWERPC_KERNEL_SETUP_H
3
4void check_for_initrd(void);
5
6#endif /* _POWERPC_KERNEL_SETUP_H */
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 3af2631e3fab..c98cfcc9cd9a 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -40,6 +40,8 @@
40#include <asm/xmon.h> 40#include <asm/xmon.h>
41#include <asm/time.h> 41#include <asm/time.h>
42 42
43#include "setup.h"
44
43#define DBG(fmt...) 45#define DBG(fmt...)
44 46
45#if defined CONFIG_KGDB 47#if defined CONFIG_KGDB
@@ -70,8 +72,6 @@ unsigned int DMA_MODE_WRITE;
70int have_of = 1; 72int have_of = 1;
71 73
72#ifdef CONFIG_PPC_MULTIPLATFORM 74#ifdef CONFIG_PPC_MULTIPLATFORM
73int _machine = 0;
74
75extern void prep_init(void); 75extern void prep_init(void);
76extern void pmac_init(void); 76extern void pmac_init(void);
77extern void chrp_init(void); 77extern void chrp_init(void);
@@ -279,7 +279,6 @@ arch_initcall(ppc_init);
279/* Warning, IO base is not yet inited */ 279/* Warning, IO base is not yet inited */
280void __init setup_arch(char **cmdline_p) 280void __init setup_arch(char **cmdline_p)
281{ 281{
282 extern char *klimit;
283 extern void do_init_bootmem(void); 282 extern void do_init_bootmem(void);
284 283
285 /* so udelay does something sensible, assume <= 1000 bogomips */ 284 /* so udelay does something sensible, assume <= 1000 bogomips */
@@ -303,14 +302,9 @@ void __init setup_arch(char **cmdline_p)
303 pmac_feature_init(); /* New cool way */ 302 pmac_feature_init(); /* New cool way */
304#endif 303#endif
305 304
306#ifdef CONFIG_XMON 305#ifdef CONFIG_XMON_DEFAULT
307 xmon_map_scc(); 306 xmon_init(1);
308 if (strstr(cmd_line, "xmon")) { 307#endif
309 xmon_init(1);
310 debugger(NULL);
311 }
312#endif /* CONFIG_XMON */
313 if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
314 308
315#if defined(CONFIG_KGDB) 309#if defined(CONFIG_KGDB)
316 if (ppc_md.kgdb_map_scc) 310 if (ppc_md.kgdb_map_scc)
@@ -343,7 +337,7 @@ void __init setup_arch(char **cmdline_p)
343 init_mm.start_code = PAGE_OFFSET; 337 init_mm.start_code = PAGE_OFFSET;
344 init_mm.end_code = (unsigned long) _etext; 338 init_mm.end_code = (unsigned long) _etext;
345 init_mm.end_data = (unsigned long) _edata; 339 init_mm.end_data = (unsigned long) _edata;
346 init_mm.brk = (unsigned long) klimit; 340 init_mm.brk = klimit;
347 341
348 /* Save unparsed command line copy for /proc/cmdline */ 342 /* Save unparsed command line copy for /proc/cmdline */
349 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); 343 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 0471e843b6c5..fdbd9f9122f2 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -57,10 +57,11 @@
57#include <asm/lmb.h> 57#include <asm/lmb.h>
58#include <asm/iseries/it_lp_naca.h> 58#include <asm/iseries/it_lp_naca.h>
59#include <asm/firmware.h> 59#include <asm/firmware.h>
60#include <asm/systemcfg.h>
61#include <asm/xmon.h> 60#include <asm/xmon.h>
62#include <asm/udbg.h> 61#include <asm/udbg.h>
63 62
63#include "setup.h"
64
64#ifdef DEBUG 65#ifdef DEBUG
65#define DBG(fmt...) udbg_printf(fmt) 66#define DBG(fmt...) udbg_printf(fmt)
66#else 67#else
@@ -94,15 +95,6 @@ extern void udbg_init_maple_realmode(void);
94 do { udbg_putc = call_rtas_display_status_delay; } while(0) 95 do { udbg_putc = call_rtas_display_status_delay; } while(0)
95#endif 96#endif
96 97
97/* extern void *stab; */
98extern unsigned long klimit;
99
100extern void mm_init_ppc64(void);
101extern void stab_initialize(unsigned long stab);
102extern void htab_initialize(void);
103extern void early_init_devtree(void *flat_dt);
104extern void unflatten_device_tree(void);
105
106int have_of = 1; 98int have_of = 1;
107int boot_cpuid = 0; 99int boot_cpuid = 0;
108int boot_cpuid_phys = 0; 100int boot_cpuid_phys = 0;
@@ -254,11 +246,10 @@ void __init early_setup(unsigned long dt_ptr)
254 * Iterate all ppc_md structures until we find the proper 246 * Iterate all ppc_md structures until we find the proper
255 * one for the current machine type 247 * one for the current machine type
256 */ 248 */
257 DBG("Probing machine type for platform %x...\n", 249 DBG("Probing machine type for platform %x...\n", _machine);
258 systemcfg->platform);
259 250
260 for (mach = machines; *mach; mach++) { 251 for (mach = machines; *mach; mach++) {
261 if ((*mach)->probe(systemcfg->platform)) 252 if ((*mach)->probe(_machine))
262 break; 253 break;
263 } 254 }
264 /* What can we do if we didn't find ? */ 255 /* What can we do if we didn't find ? */
@@ -290,6 +281,28 @@ void __init early_setup(unsigned long dt_ptr)
290 DBG(" <- early_setup()\n"); 281 DBG(" <- early_setup()\n");
291} 282}
292 283
284#ifdef CONFIG_SMP
285void early_setup_secondary(void)
286{
287 struct paca_struct *lpaca = get_paca();
288
289 /* Mark enabled in PACA */
290 lpaca->proc_enabled = 0;
291
292 /* Initialize hash table for that CPU */
293 htab_initialize_secondary();
294
295 /* Initialize STAB/SLB. We use a virtual address as it works
296 * in real mode on pSeries and we want a virutal address on
297 * iSeries anyway
298 */
299 if (cpu_has_feature(CPU_FTR_SLB))
300 slb_initialize();
301 else
302 stab_initialize(lpaca->stab_addr);
303}
304
305#endif /* CONFIG_SMP */
293 306
294#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) 307#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
295void smp_release_cpus(void) 308void smp_release_cpus(void)
@@ -315,7 +328,8 @@ void smp_release_cpus(void)
315#endif /* CONFIG_SMP || CONFIG_KEXEC */ 328#endif /* CONFIG_SMP || CONFIG_KEXEC */
316 329
317/* 330/*
318 * Initialize some remaining members of the ppc64_caches and systemcfg structures 331 * Initialize some remaining members of the ppc64_caches and systemcfg
332 * structures
319 * (at least until we get rid of them completely). This is mostly some 333 * (at least until we get rid of them completely). This is mostly some
320 * cache informations about the CPU that will be used by cache flush 334 * cache informations about the CPU that will be used by cache flush
321 * routines and/or provided to userland 335 * routines and/or provided to userland
@@ -340,7 +354,7 @@ static void __init initialize_cache_info(void)
340 const char *dc, *ic; 354 const char *dc, *ic;
341 355
342 /* Then read cache informations */ 356 /* Then read cache informations */
343 if (systemcfg->platform == PLATFORM_POWERMAC) { 357 if (_machine == PLATFORM_POWERMAC) {
344 dc = "d-cache-block-size"; 358 dc = "d-cache-block-size";
345 ic = "i-cache-block-size"; 359 ic = "i-cache-block-size";
346 } else { 360 } else {
@@ -360,9 +374,8 @@ static void __init initialize_cache_info(void)
360 DBG("Argh, can't find dcache properties ! " 374 DBG("Argh, can't find dcache properties ! "
361 "sizep: %p, lsizep: %p\n", sizep, lsizep); 375 "sizep: %p, lsizep: %p\n", sizep, lsizep);
362 376
363 systemcfg->dcache_size = ppc64_caches.dsize = size; 377 ppc64_caches.dsize = size;
364 systemcfg->dcache_line_size = 378 ppc64_caches.dline_size = lsize;
365 ppc64_caches.dline_size = lsize;
366 ppc64_caches.log_dline_size = __ilog2(lsize); 379 ppc64_caches.log_dline_size = __ilog2(lsize);
367 ppc64_caches.dlines_per_page = PAGE_SIZE / lsize; 380 ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
368 381
@@ -378,20 +391,13 @@ static void __init initialize_cache_info(void)
378 DBG("Argh, can't find icache properties ! " 391 DBG("Argh, can't find icache properties ! "
379 "sizep: %p, lsizep: %p\n", sizep, lsizep); 392 "sizep: %p, lsizep: %p\n", sizep, lsizep);
380 393
381 systemcfg->icache_size = ppc64_caches.isize = size; 394 ppc64_caches.isize = size;
382 systemcfg->icache_line_size = 395 ppc64_caches.iline_size = lsize;
383 ppc64_caches.iline_size = lsize;
384 ppc64_caches.log_iline_size = __ilog2(lsize); 396 ppc64_caches.log_iline_size = __ilog2(lsize);
385 ppc64_caches.ilines_per_page = PAGE_SIZE / lsize; 397 ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
386 } 398 }
387 } 399 }
388 400
389 /* Add an eye catcher and the systemcfg layout version number */
390 strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
391 systemcfg->version.major = SYSTEMCFG_MAJOR;
392 systemcfg->version.minor = SYSTEMCFG_MINOR;
393 systemcfg->processor = mfspr(SPRN_PVR);
394
395 DBG(" <- initialize_cache_info()\n"); 401 DBG(" <- initialize_cache_info()\n");
396} 402}
397 403
@@ -478,15 +484,14 @@ void __init setup_system(void)
478 484
479 printk("-----------------------------------------------------\n"); 485 printk("-----------------------------------------------------\n");
480 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); 486 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
481 printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); 487 printk("ppc64_interrupt_controller = 0x%ld\n",
482 printk("systemcfg = 0x%p\n", systemcfg); 488 ppc64_interrupt_controller);
483 printk("systemcfg->platform = 0x%x\n", systemcfg->platform); 489 printk("platform = 0x%x\n", _machine);
484 printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount); 490 printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size());
485 printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
486 printk("ppc64_caches.dcache_line_size = 0x%x\n", 491 printk("ppc64_caches.dcache_line_size = 0x%x\n",
487 ppc64_caches.dline_size); 492 ppc64_caches.dline_size);
488 printk("ppc64_caches.icache_line_size = 0x%x\n", 493 printk("ppc64_caches.icache_line_size = 0x%x\n",
489 ppc64_caches.iline_size); 494 ppc64_caches.iline_size);
490 printk("htab_address = 0x%p\n", htab_address); 495 printk("htab_address = 0x%p\n", htab_address);
491 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); 496 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
492 printk("-----------------------------------------------------\n"); 497 printk("-----------------------------------------------------\n");
@@ -551,33 +556,6 @@ static void __init emergency_stack_init(void)
551} 556}
552 557
553/* 558/*
554 * Called from setup_arch to initialize the bitmap of available
555 * syscalls in the systemcfg page
556 */
557void __init setup_syscall_map(void)
558{
559 unsigned int i, count64 = 0, count32 = 0;
560 extern unsigned long *sys_call_table;
561 extern unsigned long sys_ni_syscall;
562
563
564 for (i = 0; i < __NR_syscalls; i++) {
565 if (sys_call_table[i*2] != sys_ni_syscall) {
566 count64++;
567 systemcfg->syscall_map_64[i >> 5] |=
568 0x80000000UL >> (i & 0x1f);
569 }
570 if (sys_call_table[i*2+1] != sys_ni_syscall) {
571 count32++;
572 systemcfg->syscall_map_32[i >> 5] |=
573 0x80000000UL >> (i & 0x1f);
574 }
575 }
576 printk(KERN_INFO "Syscall map setup, %d 32-bit and %d 64-bit syscalls\n",
577 count32, count64);
578}
579
580/*
581 * Called into from start_kernel, after lock_kernel has been called. 559 * Called into from start_kernel, after lock_kernel has been called.
582 * Initializes bootmem, which is unsed to manage page allocation until 560 * Initializes bootmem, which is unsed to manage page allocation until
583 * mem_init is called. 561 * mem_init is called.
@@ -618,9 +596,6 @@ void __init setup_arch(char **cmdline_p)
618 do_init_bootmem(); 596 do_init_bootmem();
619 sparse_init(); 597 sparse_init();
620 598
621 /* initialize the syscall map in systemcfg */
622 setup_syscall_map();
623
624#ifdef CONFIG_DUMMY_CONSOLE 599#ifdef CONFIG_DUMMY_CONSOLE
625 conswitchp = &dummy_con; 600 conswitchp = &dummy_con;
626#endif 601#endif
@@ -858,26 +833,6 @@ int check_legacy_ioport(unsigned long base_port)
858} 833}
859EXPORT_SYMBOL(check_legacy_ioport); 834EXPORT_SYMBOL(check_legacy_ioport);
860 835
861#ifdef CONFIG_XMON
862static int __init early_xmon(char *p)
863{
864 /* ensure xmon is enabled */
865 if (p) {
866 if (strncmp(p, "on", 2) == 0)
867 xmon_init(1);
868 if (strncmp(p, "off", 3) == 0)
869 xmon_init(0);
870 if (strncmp(p, "early", 5) != 0)
871 return 0;
872 }
873 xmon_init(1);
874 debugger(NULL);
875
876 return 0;
877}
878early_param("xmon", early_xmon);
879#endif
880
881void cpu_die(void) 836void cpu_die(void)
882{ 837{
883 if (ppc_md.cpu_die) 838 if (ppc_md.cpu_die)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 081d931eae48..8bdf95b7e420 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -42,10 +42,11 @@
42 42
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
45#include <asm/sigcontext.h>
46#include <asm/vdso.h>
45#ifdef CONFIG_PPC64 47#ifdef CONFIG_PPC64
46#include "ppc32.h" 48#include "ppc32.h"
47#include <asm/unistd.h> 49#include <asm/unistd.h>
48#include <asm/vdso.h>
49#else 50#else
50#include <asm/ucontext.h> 51#include <asm/ucontext.h>
51#include <asm/pgtable.h> 52#include <asm/pgtable.h>
@@ -808,14 +809,11 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
808 809
809 /* Save user registers on the stack */ 810 /* Save user registers on the stack */
810 frame = &rt_sf->uc.uc_mcontext; 811 frame = &rt_sf->uc.uc_mcontext;
811#ifdef CONFIG_PPC64
812 if (vdso32_rt_sigtramp && current->thread.vdso_base) { 812 if (vdso32_rt_sigtramp && current->thread.vdso_base) {
813 if (save_user_regs(regs, frame, 0)) 813 if (save_user_regs(regs, frame, 0))
814 goto badframe; 814 goto badframe;
815 regs->link = current->thread.vdso_base + vdso32_rt_sigtramp; 815 regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
816 } else 816 } else {
817#endif
818 {
819 if (save_user_regs(regs, frame, __NR_rt_sigreturn)) 817 if (save_user_regs(regs, frame, __NR_rt_sigreturn))
820 goto badframe; 818 goto badframe;
821 regs->link = (unsigned long) frame->tramp; 819 regs->link = (unsigned long) frame->tramp;
@@ -1089,14 +1087,11 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1089 || __put_user(sig, &sc->signal)) 1087 || __put_user(sig, &sc->signal))
1090 goto badframe; 1088 goto badframe;
1091 1089
1092#ifdef CONFIG_PPC64
1093 if (vdso32_sigtramp && current->thread.vdso_base) { 1090 if (vdso32_sigtramp && current->thread.vdso_base) {
1094 if (save_user_regs(regs, &frame->mctx, 0)) 1091 if (save_user_regs(regs, &frame->mctx, 0))
1095 goto badframe; 1092 goto badframe;
1096 regs->link = current->thread.vdso_base + vdso32_sigtramp; 1093 regs->link = current->thread.vdso_base + vdso32_sigtramp;
1097 } else 1094 } else {
1098#endif
1099 {
1100 if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) 1095 if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
1101 goto badframe; 1096 goto badframe;
1102 regs->link = (unsigned long) frame->mctx.tramp; 1097 regs->link = (unsigned long) frame->mctx.tramp;
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 5c330c3366e4..62dfc5b8d765 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -44,6 +44,7 @@
44#include <asm/cputable.h> 44#include <asm/cputable.h>
45#include <asm/system.h> 45#include <asm/system.h>
46#include <asm/mpic.h> 46#include <asm/mpic.h>
47#include <asm/vdso_datapage.h>
47#ifdef CONFIG_PPC64 48#ifdef CONFIG_PPC64
48#include <asm/paca.h> 49#include <asm/paca.h>
49#endif 50#endif
@@ -368,9 +369,11 @@ int generic_cpu_disable(void)
368 if (cpu == boot_cpuid) 369 if (cpu == boot_cpuid)
369 return -EBUSY; 370 return -EBUSY;
370 371
371 systemcfg->processorCount--;
372 cpu_clear(cpu, cpu_online_map); 372 cpu_clear(cpu, cpu_online_map);
373#ifdef CONFIG_PPC64
374 vdso_data->processorCount--;
373 fixup_irqs(cpu_online_map); 375 fixup_irqs(cpu_online_map);
376#endif
374 return 0; 377 return 0;
375} 378}
376 379
@@ -388,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu)
388 while (!cpu_online(cpu)) 391 while (!cpu_online(cpu))
389 cpu_relax(); 392 cpu_relax();
390 393
394#ifdef CONFIG_PPC64
391 fixup_irqs(cpu_online_map); 395 fixup_irqs(cpu_online_map);
392 /* counter the irq disable in fixup_irqs */ 396 /* counter the irq disable in fixup_irqs */
393 local_irq_enable(); 397 local_irq_enable();
398#endif
394 return 0; 399 return 0;
395} 400}
396 401
@@ -419,7 +424,9 @@ void generic_mach_cpu_die(void)
419 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) 424 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
420 cpu_relax(); 425 cpu_relax();
421 426
427#ifdef CONFIG_PPC64
422 flush_tlb_pending(); 428 flush_tlb_pending();
429#endif
423 cpu_set(cpu, cpu_online_map); 430 cpu_set(cpu, cpu_online_map);
424 local_irq_enable(); 431 local_irq_enable();
425} 432}
@@ -510,6 +517,7 @@ int __devinit start_secondary(void *unused)
510 517
511 smp_store_cpu_info(cpu); 518 smp_store_cpu_info(cpu);
512 set_dec(tb_ticks_per_jiffy); 519 set_dec(tb_ticks_per_jiffy);
520 preempt_disable();
513 cpu_callin_map[cpu] = 1; 521 cpu_callin_map[cpu] = 1;
514 522
515 smp_ops->setup_cpu(cpu); 523 smp_ops->setup_cpu(cpu);
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index a8210ed5c686..9c921d1c4084 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -52,7 +52,6 @@
52#include <asm/semaphore.h> 52#include <asm/semaphore.h>
53#include <asm/time.h> 53#include <asm/time.h>
54#include <asm/mmu_context.h> 54#include <asm/mmu_context.h>
55#include <asm/systemcfg.h>
56#include <asm/ppc-pci.h> 55#include <asm/ppc-pci.h>
57 56
58/* readdir & getdents */ 57/* readdir & getdents */
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index e99ec62c2c52..0f0c3a9ae2e5 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -16,7 +16,6 @@
16#include <asm/firmware.h> 16#include <asm/firmware.h>
17#include <asm/hvcall.h> 17#include <asm/hvcall.h>
18#include <asm/prom.h> 18#include <asm/prom.h>
19#include <asm/systemcfg.h>
20#include <asm/paca.h> 19#include <asm/paca.h>
21#include <asm/lppaca.h> 20#include <asm/lppaca.h>
22#include <asm/machdep.h> 21#include <asm/machdep.h>
@@ -232,7 +231,7 @@ static void register_cpu_online(unsigned int cpu)
232 sysdev_create_file(s, &attr_pmc7); 231 sysdev_create_file(s, &attr_pmc7);
233 if (cur_cpu_spec->num_pmcs >= 8) 232 if (cur_cpu_spec->num_pmcs >= 8)
234 sysdev_create_file(s, &attr_pmc8); 233 sysdev_create_file(s, &attr_pmc8);
235 234
236 if (cpu_has_feature(CPU_FTR_SMT)) 235 if (cpu_has_feature(CPU_FTR_SMT))
237 sysdev_create_file(s, &attr_purr); 236 sysdev_create_file(s, &attr_purr);
238} 237}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index a6282b625b44..070b4b458aaf 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -62,8 +62,8 @@
62#include <asm/irq.h> 62#include <asm/irq.h>
63#include <asm/div64.h> 63#include <asm/div64.h>
64#include <asm/smp.h> 64#include <asm/smp.h>
65#include <asm/vdso_datapage.h>
65#ifdef CONFIG_PPC64 66#ifdef CONFIG_PPC64
66#include <asm/systemcfg.h>
67#include <asm/firmware.h> 67#include <asm/firmware.h>
68#endif 68#endif
69#ifdef CONFIG_PPC_ISERIES 69#ifdef CONFIG_PPC_ISERIES
@@ -261,7 +261,6 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
261 do_gtod.varp = temp_varp; 261 do_gtod.varp = temp_varp;
262 do_gtod.var_idx = temp_idx; 262 do_gtod.var_idx = temp_idx;
263 263
264#ifdef CONFIG_PPC64
265 /* 264 /*
266 * tb_update_count is used to allow the userspace gettimeofday code 265 * tb_update_count is used to allow the userspace gettimeofday code
267 * to assure itself that it sees a consistent view of the tb_to_xs and 266 * to assure itself that it sees a consistent view of the tb_to_xs and
@@ -271,14 +270,15 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
271 * tb_to_xs and stamp_xsec values are consistent. If not, then it 270 * tb_to_xs and stamp_xsec values are consistent. If not, then it
272 * loops back and reads them again until this criteria is met. 271 * loops back and reads them again until this criteria is met.
273 */ 272 */
274 ++(systemcfg->tb_update_count); 273 ++(vdso_data->tb_update_count);
275 smp_wmb(); 274 smp_wmb();
276 systemcfg->tb_orig_stamp = new_tb_stamp; 275 vdso_data->tb_orig_stamp = new_tb_stamp;
277 systemcfg->stamp_xsec = new_stamp_xsec; 276 vdso_data->stamp_xsec = new_stamp_xsec;
278 systemcfg->tb_to_xs = new_tb_to_xs; 277 vdso_data->tb_to_xs = new_tb_to_xs;
278 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
279 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
279 smp_wmb(); 280 smp_wmb();
280 ++(systemcfg->tb_update_count); 281 ++(vdso_data->tb_update_count);
281#endif
282} 282}
283 283
284/* 284/*
@@ -357,8 +357,8 @@ static void iSeries_tb_recal(void)
357 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; 357 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
358 tb_to_xs = divres.result_low; 358 tb_to_xs = divres.result_low;
359 do_gtod.varp->tb_to_xs = tb_to_xs; 359 do_gtod.varp->tb_to_xs = tb_to_xs;
360 systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; 360 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
361 systemcfg->tb_to_xs = tb_to_xs; 361 vdso_data->tb_to_xs = tb_to_xs;
362 } 362 }
363 else { 363 else {
364 printk( "Titan recalibrate: FAILED (difference > 4 percent)\n" 364 printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
@@ -483,6 +483,8 @@ void __init smp_space_timers(unsigned int max_cpus)
483 unsigned long offset = tb_ticks_per_jiffy / max_cpus; 483 unsigned long offset = tb_ticks_per_jiffy / max_cpus;
484 unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); 484 unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
485 485
486 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
487 previous_tb -= tb_ticks_per_jiffy;
486 for_each_cpu(i) { 488 for_each_cpu(i) {
487 if (i != boot_cpuid) { 489 if (i != boot_cpuid) {
488 previous_tb += offset; 490 previous_tb += offset;
@@ -558,10 +560,8 @@ int do_settimeofday(struct timespec *tv)
558 new_xsec += (u64)new_sec * XSEC_PER_SEC - tb_delta_xs; 560 new_xsec += (u64)new_sec * XSEC_PER_SEC - tb_delta_xs;
559 update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs); 561 update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
560 562
561#ifdef CONFIG_PPC64 563 vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
562 systemcfg->tz_minuteswest = sys_tz.tz_minuteswest; 564 vdso_data->tz_dsttime = sys_tz.tz_dsttime;
563 systemcfg->tz_dsttime = sys_tz.tz_dsttime;
564#endif
565 565
566 write_sequnlock_irqrestore(&xtime_lock, flags); 566 write_sequnlock_irqrestore(&xtime_lock, flags);
567 clock_was_set(); 567 clock_was_set();
@@ -710,13 +710,12 @@ void __init time_init(void)
710 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; 710 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
711 do_gtod.varp->tb_to_xs = tb_to_xs; 711 do_gtod.varp->tb_to_xs = tb_to_xs;
712 do_gtod.tb_to_us = tb_to_us; 712 do_gtod.tb_to_us = tb_to_us;
713#ifdef CONFIG_PPC64 713
714 systemcfg->tb_orig_stamp = tb_last_jiffy; 714 vdso_data->tb_orig_stamp = tb_last_jiffy;
715 systemcfg->tb_update_count = 0; 715 vdso_data->tb_update_count = 0;
716 systemcfg->tb_ticks_per_sec = tb_ticks_per_sec; 716 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
717 systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; 717 vdso_data->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
718 systemcfg->tb_to_xs = tb_to_xs; 718 vdso_data->tb_to_xs = tb_to_xs;
719#endif
720 719
721 time_freq = 0; 720 time_freq = 0;
722 721
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 32f215825e8d..1511454c4690 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -49,7 +49,6 @@
49#ifdef CONFIG_PPC64 49#ifdef CONFIG_PPC64
50#include <asm/firmware.h> 50#include <asm/firmware.h>
51#include <asm/processor.h> 51#include <asm/processor.h>
52#include <asm/systemcfg.h>
53#endif 52#endif
54 53
55#ifdef CONFIG_PPC64 /* XXX */ 54#ifdef CONFIG_PPC64 /* XXX */
@@ -129,7 +128,7 @@ int die(const char *str, struct pt_regs *regs, long err)
129 nl = 1; 128 nl = 1;
130#endif 129#endif
131#ifdef CONFIG_PPC64 130#ifdef CONFIG_PPC64
132 switch (systemcfg->platform) { 131 switch (_machine) {
133 case PLATFORM_PSERIES: 132 case PLATFORM_PSERIES:
134 printk("PSERIES "); 133 printk("PSERIES ");
135 nl = 1; 134 nl = 1;
@@ -887,10 +886,6 @@ void altivec_unavailable_exception(struct pt_regs *regs)
887 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); 886 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
888} 887}
889 888
890#ifdef CONFIG_PPC64
891extern perf_irq_t perf_irq;
892#endif
893
894#if defined(CONFIG_PPC64) || defined(CONFIG_E500) 889#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
895void performance_monitor_exception(struct pt_regs *regs) 890void performance_monitor_exception(struct pt_regs *regs)
896{ 891{
diff --git a/arch/ppc64/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 0d878e72fc44..0d878e72fc44 100644
--- a/arch/ppc64/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
diff --git a/arch/ppc64/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 9313574ab935..9313574ab935 100644
--- a/arch/ppc64/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
diff --git a/arch/ppc64/kernel/udbg_scc.c b/arch/powerpc/kernel/udbg_scc.c
index 820c53551507..820c53551507 100644
--- a/arch/ppc64/kernel/udbg_scc.c
+++ b/arch/powerpc/kernel/udbg_scc.c
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
new file mode 100644
index 000000000000..0d4d8bec0df4
--- /dev/null
+++ b/arch/powerpc/kernel/vdso.c
@@ -0,0 +1,746 @@
1/*
2 * linux/arch/ppc64/kernel/vdso.c
3 *
4 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/module.h>
15#include <linux/errno.h>
16#include <linux/sched.h>
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/smp.h>
20#include <linux/smp_lock.h>
21#include <linux/stddef.h>
22#include <linux/unistd.h>
23#include <linux/slab.h>
24#include <linux/user.h>
25#include <linux/elf.h>
26#include <linux/security.h>
27#include <linux/bootmem.h>
28
29#include <asm/pgtable.h>
30#include <asm/system.h>
31#include <asm/processor.h>
32#include <asm/mmu.h>
33#include <asm/mmu_context.h>
34#include <asm/lmb.h>
35#include <asm/machdep.h>
36#include <asm/cputable.h>
37#include <asm/sections.h>
38#include <asm/vdso.h>
39#include <asm/vdso_datapage.h>
40
41#undef DEBUG
42
43#ifdef DEBUG
44#define DBG(fmt...) printk(fmt)
45#else
46#define DBG(fmt...)
47#endif
48
49/* Max supported size for symbol names */
50#define MAX_SYMNAME 64
51
52extern char vdso32_start, vdso32_end;
53static void *vdso32_kbase = &vdso32_start;
54unsigned int vdso32_pages;
55unsigned long vdso32_sigtramp;
56unsigned long vdso32_rt_sigtramp;
57
58#ifdef CONFIG_PPC64
59extern char vdso64_start, vdso64_end;
60static void *vdso64_kbase = &vdso64_start;
61unsigned int vdso64_pages;
62unsigned long vdso64_rt_sigtramp;
63#endif /* CONFIG_PPC64 */
64
65/*
66 * The vdso data page (aka. systemcfg for old ppc64 fans) is here.
67 * Once the early boot kernel code no longer needs to muck around
68 * with it, it will become dynamically allocated
69 */
70static union {
71 struct vdso_data data;
72 u8 page[PAGE_SIZE];
73} vdso_data_store __attribute__((__section__(".data.page_aligned")));
74struct vdso_data *vdso_data = &vdso_data_store.data;
75
76/* Format of the patch table */
77struct vdso_patch_def
78{
79 unsigned long ftr_mask, ftr_value;
80 const char *gen_name;
81 const char *fix_name;
82};
83
84/* Table of functions to patch based on the CPU type/revision
85 *
86 * Currently, we only change sync_dicache to do nothing on processors
87 * with a coherent icache
88 */
89static struct vdso_patch_def vdso_patches[] = {
90 {
91 CPU_FTR_COHERENT_ICACHE, CPU_FTR_COHERENT_ICACHE,
92 "__kernel_sync_dicache", "__kernel_sync_dicache_p5"
93 },
94 {
95 CPU_FTR_USE_TB, 0,
96 "__kernel_gettimeofday", NULL
97 },
98};
99
100/*
101 * Some infos carried around for each of them during parsing at
102 * boot time.
103 */
104struct lib32_elfinfo
105{
106 Elf32_Ehdr *hdr; /* ptr to ELF */
107 Elf32_Sym *dynsym; /* ptr to .dynsym section */
108 unsigned long dynsymsize; /* size of .dynsym section */
109 char *dynstr; /* ptr to .dynstr section */
110 unsigned long text; /* offset of .text section in .so */
111};
112
113struct lib64_elfinfo
114{
115 Elf64_Ehdr *hdr;
116 Elf64_Sym *dynsym;
117 unsigned long dynsymsize;
118 char *dynstr;
119 unsigned long text;
120};
121
122
123#ifdef __DEBUG
124static void dump_one_vdso_page(struct page *pg, struct page *upg)
125{
126 printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT),
127 page_count(pg),
128 pg->flags);
129 if (upg/* && pg != upg*/) {
130 printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg)
131 << PAGE_SHIFT),
132 page_count(upg),
133 upg->flags);
134 }
135 printk("\n");
136}
137
138static void dump_vdso_pages(struct vm_area_struct * vma)
139{
140 int i;
141
142 if (!vma || test_thread_flag(TIF_32BIT)) {
143 printk("vDSO32 @ %016lx:\n", (unsigned long)vdso32_kbase);
144 for (i=0; i<vdso32_pages; i++) {
145 struct page *pg = virt_to_page(vdso32_kbase +
146 i*PAGE_SIZE);
147 struct page *upg = (vma && vma->vm_mm) ?
148 follow_page(vma->vm_mm, vma->vm_start +
149 i*PAGE_SIZE, 0)
150 : NULL;
151 dump_one_vdso_page(pg, upg);
152 }
153 }
154 if (!vma || !test_thread_flag(TIF_32BIT)) {
155 printk("vDSO64 @ %016lx:\n", (unsigned long)vdso64_kbase);
156 for (i=0; i<vdso64_pages; i++) {
157 struct page *pg = virt_to_page(vdso64_kbase +
158 i*PAGE_SIZE);
159 struct page *upg = (vma && vma->vm_mm) ?
160 follow_page(vma->vm_mm, vma->vm_start +
161 i*PAGE_SIZE, 0)
162 : NULL;
163 dump_one_vdso_page(pg, upg);
164 }
165 }
166}
167#endif /* DEBUG */
168
169/*
170 * Keep a dummy vma_close for now, it will prevent VMA merging.
171 */
172static void vdso_vma_close(struct vm_area_struct * vma)
173{
174}
175
176/*
177 * Our nopage() function, maps in the actual vDSO kernel pages, they will
178 * be mapped read-only by do_no_page(), and eventually COW'ed, either
179 * right away for an initial write access, or by do_wp_page().
180 */
181static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
182 unsigned long address, int *type)
183{
184 unsigned long offset = address - vma->vm_start;
185 struct page *pg;
186#ifdef CONFIG_PPC64
187 void *vbase = test_thread_flag(TIF_32BIT) ?
188 vdso32_kbase : vdso64_kbase;
189#else
190 void *vbase = vdso32_kbase;
191#endif
192
193 DBG("vdso_vma_nopage(current: %s, address: %016lx, off: %lx)\n",
194 current->comm, address, offset);
195
196 if (address < vma->vm_start || address > vma->vm_end)
197 return NOPAGE_SIGBUS;
198
199 /*
200 * Last page is systemcfg.
201 */
202 if ((vma->vm_end - address) <= PAGE_SIZE)
203 pg = virt_to_page(vdso_data);
204 else
205 pg = virt_to_page(vbase + offset);
206
207 get_page(pg);
208 DBG(" ->page count: %d\n", page_count(pg));
209
210 return pg;
211}
212
213static struct vm_operations_struct vdso_vmops = {
214 .close = vdso_vma_close,
215 .nopage = vdso_vma_nopage,
216};
217
218/*
219 * This is called from binfmt_elf, we create the special vma for the
220 * vDSO and insert it into the mm struct tree
221 */
222int arch_setup_additional_pages(struct linux_binprm *bprm,
223 int executable_stack)
224{
225 struct mm_struct *mm = current->mm;
226 struct vm_area_struct *vma;
227 unsigned long vdso_pages;
228 unsigned long vdso_base;
229
230#ifdef CONFIG_PPC64
231 if (test_thread_flag(TIF_32BIT)) {
232 vdso_pages = vdso32_pages;
233 vdso_base = VDSO32_MBASE;
234 } else {
235 vdso_pages = vdso64_pages;
236 vdso_base = VDSO64_MBASE;
237 }
238#else
239 vdso_pages = vdso32_pages;
240 vdso_base = VDSO32_MBASE;
241#endif
242
243 current->thread.vdso_base = 0;
244
245 /* vDSO has a problem and was disabled, just don't "enable" it for the
246 * process
247 */
248 if (vdso_pages == 0)
249 return 0;
250
251 vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
252 if (vma == NULL)
253 return -ENOMEM;
254
255 memset(vma, 0, sizeof(*vma));
256
257 /* Add a page to the vdso size for the data page */
258 vdso_pages ++;
259
260 /*
261 * pick a base address for the vDSO in process space. We try to put it
262 * at vdso_base which is the "natural" base for it, but we might fail
263 * and end up putting it elsewhere.
264 */
265 vdso_base = get_unmapped_area(NULL, vdso_base,
266 vdso_pages << PAGE_SHIFT, 0, 0);
267 if (vdso_base & ~PAGE_MASK) {
268 kmem_cache_free(vm_area_cachep, vma);
269 return (int)vdso_base;
270 }
271
272 current->thread.vdso_base = vdso_base;
273
274 vma->vm_mm = mm;
275 vma->vm_start = current->thread.vdso_base;
276 vma->vm_end = vma->vm_start + (vdso_pages << PAGE_SHIFT);
277
278 /*
279 * our vma flags don't have VM_WRITE so by default, the process isn't
280 * allowed to write those pages.
281 * gdb can break that with ptrace interface, and thus trigger COW on
282 * those pages but it's then your responsibility to never do that on
283 * the "data" page of the vDSO or you'll stop getting kernel updates
284 * and your nice userland gettimeofday will be totally dead.
285 * It's fine to use that for setting breakpoints in the vDSO code
286 * pages though
287 */
288 vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE |
289 VM_MAYEXEC | VM_RESERVED;
290 vma->vm_flags |= mm->def_flags;
291 vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
292 vma->vm_ops = &vdso_vmops;
293
294 down_write(&mm->mmap_sem);
295 if (insert_vm_struct(mm, vma)) {
296 up_write(&mm->mmap_sem);
297 kmem_cache_free(vm_area_cachep, vma);
298 return -ENOMEM;
299 }
300 mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
301 up_write(&mm->mmap_sem);
302
303 return 0;
304}
305
306static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
307 unsigned long *size)
308{
309 Elf32_Shdr *sechdrs;
310 unsigned int i;
311 char *secnames;
312
313 /* Grab section headers and strings so we can tell who is who */
314 sechdrs = (void *)ehdr + ehdr->e_shoff;
315 secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
316
317 /* Find the section they want */
318 for (i = 1; i < ehdr->e_shnum; i++) {
319 if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
320 if (size)
321 *size = sechdrs[i].sh_size;
322 return (void *)ehdr + sechdrs[i].sh_offset;
323 }
324 }
325 *size = 0;
326 return NULL;
327}
328
329static Elf32_Sym * __init find_symbol32(struct lib32_elfinfo *lib,
330 const char *symname)
331{
332 unsigned int i;
333 char name[MAX_SYMNAME], *c;
334
335 for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) {
336 if (lib->dynsym[i].st_name == 0)
337 continue;
338 strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,
339 MAX_SYMNAME);
340 c = strchr(name, '@');
341 if (c)
342 *c = 0;
343 if (strcmp(symname, name) == 0)
344 return &lib->dynsym[i];
345 }
346 return NULL;
347}
348
349/* Note that we assume the section is .text and the symbol is relative to
350 * the library base
351 */
352static unsigned long __init find_function32(struct lib32_elfinfo *lib,
353 const char *symname)
354{
355 Elf32_Sym *sym = find_symbol32(lib, symname);
356
357 if (sym == NULL) {
358 printk(KERN_WARNING "vDSO32: function %s not found !\n",
359 symname);
360 return 0;
361 }
362 return sym->st_value - VDSO32_LBASE;
363}
364
365static int vdso_do_func_patch32(struct lib32_elfinfo *v32,
366 struct lib64_elfinfo *v64,
367 const char *orig, const char *fix)
368{
369 Elf32_Sym *sym32_gen, *sym32_fix;
370
371 sym32_gen = find_symbol32(v32, orig);
372 if (sym32_gen == NULL) {
373 printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", orig);
374 return -1;
375 }
376 if (fix == NULL) {
377 sym32_gen->st_name = 0;
378 return 0;
379 }
380 sym32_fix = find_symbol32(v32, fix);
381 if (sym32_fix == NULL) {
382 printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix);
383 return -1;
384 }
385 sym32_gen->st_value = sym32_fix->st_value;
386 sym32_gen->st_size = sym32_fix->st_size;
387 sym32_gen->st_info = sym32_fix->st_info;
388 sym32_gen->st_other = sym32_fix->st_other;
389 sym32_gen->st_shndx = sym32_fix->st_shndx;
390
391 return 0;
392}
393
394
395#ifdef CONFIG_PPC64
396
397static void * __init find_section64(Elf64_Ehdr *ehdr, const char *secname,
398 unsigned long *size)
399{
400 Elf64_Shdr *sechdrs;
401 unsigned int i;
402 char *secnames;
403
404 /* Grab section headers and strings so we can tell who is who */
405 sechdrs = (void *)ehdr + ehdr->e_shoff;
406 secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
407
408 /* Find the section they want */
409 for (i = 1; i < ehdr->e_shnum; i++) {
410 if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
411 if (size)
412 *size = sechdrs[i].sh_size;
413 return (void *)ehdr + sechdrs[i].sh_offset;
414 }
415 }
416 if (size)
417 *size = 0;
418 return NULL;
419}
420
421static Elf64_Sym * __init find_symbol64(struct lib64_elfinfo *lib,
422 const char *symname)
423{
424 unsigned int i;
425 char name[MAX_SYMNAME], *c;
426
427 for (i = 0; i < (lib->dynsymsize / sizeof(Elf64_Sym)); i++) {
428 if (lib->dynsym[i].st_name == 0)
429 continue;
430 strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,
431 MAX_SYMNAME);
432 c = strchr(name, '@');
433 if (c)
434 *c = 0;
435 if (strcmp(symname, name) == 0)
436 return &lib->dynsym[i];
437 }
438 return NULL;
439}
440
441/* Note that we assume the section is .text and the symbol is relative to
442 * the library base
443 */
444static unsigned long __init find_function64(struct lib64_elfinfo *lib,
445 const char *symname)
446{
447 Elf64_Sym *sym = find_symbol64(lib, symname);
448
449 if (sym == NULL) {
450 printk(KERN_WARNING "vDSO64: function %s not found !\n",
451 symname);
452 return 0;
453 }
454#ifdef VDS64_HAS_DESCRIPTORS
455 return *((u64 *)(vdso64_kbase + sym->st_value - VDSO64_LBASE)) -
456 VDSO64_LBASE;
457#else
458 return sym->st_value - VDSO64_LBASE;
459#endif
460}
461
462static int vdso_do_func_patch64(struct lib32_elfinfo *v32,
463 struct lib64_elfinfo *v64,
464 const char *orig, const char *fix)
465{
466 Elf64_Sym *sym64_gen, *sym64_fix;
467
468 sym64_gen = find_symbol64(v64, orig);
469 if (sym64_gen == NULL) {
470 printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", orig);
471 return -1;
472 }
473 if (fix == NULL) {
474 sym64_gen->st_name = 0;
475 return 0;
476 }
477 sym64_fix = find_symbol64(v64, fix);
478 if (sym64_fix == NULL) {
479 printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", fix);
480 return -1;
481 }
482 sym64_gen->st_value = sym64_fix->st_value;
483 sym64_gen->st_size = sym64_fix->st_size;
484 sym64_gen->st_info = sym64_fix->st_info;
485 sym64_gen->st_other = sym64_fix->st_other;
486 sym64_gen->st_shndx = sym64_fix->st_shndx;
487
488 return 0;
489}
490
491#endif /* CONFIG_PPC64 */
492
493
494static __init int vdso_do_find_sections(struct lib32_elfinfo *v32,
495 struct lib64_elfinfo *v64)
496{
497 void *sect;
498
499 /*
500 * Locate symbol tables & text section
501 */
502
503 v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize);
504 v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL);
505 if (v32->dynsym == NULL || v32->dynstr == NULL) {
506 printk(KERN_ERR "vDSO32: required symbol section not found\n");
507 return -1;
508 }
509 sect = find_section32(v32->hdr, ".text", NULL);
510 if (sect == NULL) {
511 printk(KERN_ERR "vDSO32: the .text section was not found\n");
512 return -1;
513 }
514 v32->text = sect - vdso32_kbase;
515
516#ifdef CONFIG_PPC64
517 v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize);
518 v64->dynstr = find_section64(v64->hdr, ".dynstr", NULL);
519 if (v64->dynsym == NULL || v64->dynstr == NULL) {
520 printk(KERN_ERR "vDSO64: required symbol section not found\n");
521 return -1;
522 }
523 sect = find_section64(v64->hdr, ".text", NULL);
524 if (sect == NULL) {
525 printk(KERN_ERR "vDSO64: the .text section was not found\n");
526 return -1;
527 }
528 v64->text = sect - vdso64_kbase;
529#endif /* CONFIG_PPC64 */
530
531 return 0;
532}
533
534static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
535 struct lib64_elfinfo *v64)
536{
537 /*
538 * Find signal trampolines
539 */
540
541#ifdef CONFIG_PPC64
542 vdso64_rt_sigtramp = find_function64(v64, "__kernel_sigtramp_rt64");
543#endif
544 vdso32_sigtramp = find_function32(v32, "__kernel_sigtramp32");
545 vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32");
546}
547
548static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
549 struct lib64_elfinfo *v64)
550{
551 Elf32_Sym *sym32;
552#ifdef CONFIG_PPC64
553 Elf64_Sym *sym64;
554
555 sym64 = find_symbol64(v64, "__kernel_datapage_offset");
556 if (sym64 == NULL) {
557 printk(KERN_ERR "vDSO64: Can't find symbol "
558 "__kernel_datapage_offset !\n");
559 return -1;
560 }
561 *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =
562 (vdso64_pages << PAGE_SHIFT) -
563 (sym64->st_value - VDSO64_LBASE);
564#endif /* CONFIG_PPC64 */
565
566 sym32 = find_symbol32(v32, "__kernel_datapage_offset");
567 if (sym32 == NULL) {
568 printk(KERN_ERR "vDSO32: Can't find symbol "
569 "__kernel_datapage_offset !\n");
570 return -1;
571 }
572 *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
573 (vdso32_pages << PAGE_SHIFT) -
574 (sym32->st_value - VDSO32_LBASE);
575
576 return 0;
577}
578
579static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32,
580 struct lib64_elfinfo *v64)
581{
582 int i;
583
584 for (i = 0; i < ARRAY_SIZE(vdso_patches); i++) {
585 struct vdso_patch_def *patch = &vdso_patches[i];
586 int match = (cur_cpu_spec->cpu_features & patch->ftr_mask)
587 == patch->ftr_value;
588 if (!match)
589 continue;
590
591 DBG("replacing %s with %s...\n", patch->gen_name,
592 patch->fix_name ? "NONE" : patch->fix_name);
593
594 /*
595 * Patch the 32 bits and 64 bits symbols. Note that we do not
596 * patch the "." symbol on 64 bits.
597 * It would be easy to do, but doesn't seem to be necessary,
598 * patching the OPD symbol is enough.
599 */
600 vdso_do_func_patch32(v32, v64, patch->gen_name,
601 patch->fix_name);
602#ifdef CONFIG_PPC64
603 vdso_do_func_patch64(v32, v64, patch->gen_name,
604 patch->fix_name);
605#endif /* CONFIG_PPC64 */
606 }
607
608 return 0;
609}
610
611
612static __init int vdso_setup(void)
613{
614 struct lib32_elfinfo v32;
615 struct lib64_elfinfo v64;
616
617 v32.hdr = vdso32_kbase;
618#ifdef CONFIG_PPC64
619 v64.hdr = vdso64_kbase;
620#endif
621 if (vdso_do_find_sections(&v32, &v64))
622 return -1;
623
624 if (vdso_fixup_datapage(&v32, &v64))
625 return -1;
626
627 if (vdso_fixup_alt_funcs(&v32, &v64))
628 return -1;
629
630 vdso_setup_trampolines(&v32, &v64);
631
632 return 0;
633}
634
635/*
636 * Called from setup_arch to initialize the bitmap of available
637 * syscalls in the systemcfg page
638 */
639static void __init vdso_setup_syscall_map(void)
640{
641 unsigned int i;
642 extern unsigned long *sys_call_table;
643 extern unsigned long sys_ni_syscall;
644
645
646 for (i = 0; i < __NR_syscalls; i++) {
647#ifdef CONFIG_PPC64
648 if (sys_call_table[i*2] != sys_ni_syscall)
649 vdso_data->syscall_map_64[i >> 5] |=
650 0x80000000UL >> (i & 0x1f);
651 if (sys_call_table[i*2+1] != sys_ni_syscall)
652 vdso_data->syscall_map_32[i >> 5] |=
653 0x80000000UL >> (i & 0x1f);
654#else /* CONFIG_PPC64 */
655 if (sys_call_table[i] != sys_ni_syscall)
656 vdso_data->syscall_map_32[i >> 5] |=
657 0x80000000UL >> (i & 0x1f);
658#endif /* CONFIG_PPC64 */
659 }
660}
661
662
663void __init vdso_init(void)
664{
665 int i;
666
667#ifdef CONFIG_PPC64
668 /*
669 * Fill up the "systemcfg" stuff for backward compatiblity
670 */
671 strcpy(vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
672 vdso_data->version.major = SYSTEMCFG_MAJOR;
673 vdso_data->version.minor = SYSTEMCFG_MINOR;
674 vdso_data->processor = mfspr(SPRN_PVR);
675 vdso_data->platform = _machine;
676 vdso_data->physicalMemorySize = lmb_phys_mem_size();
677 vdso_data->dcache_size = ppc64_caches.dsize;
678 vdso_data->dcache_line_size = ppc64_caches.dline_size;
679 vdso_data->icache_size = ppc64_caches.isize;
680 vdso_data->icache_line_size = ppc64_caches.iline_size;
681
682 /*
683 * Calculate the size of the 64 bits vDSO
684 */
685 vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;
686 DBG("vdso64_kbase: %p, 0x%x pages\n", vdso64_kbase, vdso64_pages);
687#endif /* CONFIG_PPC64 */
688
689
690 /*
691 * Calculate the size of the 32 bits vDSO
692 */
693 vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
694 DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
695
696
697 /*
698 * Setup the syscall map in the vDOS
699 */
700 vdso_setup_syscall_map();
701 /*
702 * Initialize the vDSO images in memory, that is do necessary
703 * fixups of vDSO symbols, locate trampolines, etc...
704 */
705 if (vdso_setup()) {
706 printk(KERN_ERR "vDSO setup failure, not enabled !\n");
707 vdso32_pages = 0;
708#ifdef CONFIG_PPC64
709 vdso64_pages = 0;
710#endif
711 return;
712 }
713
714 /* Make sure pages are in the correct state */
715 for (i = 0; i < vdso32_pages; i++) {
716 struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
717 ClearPageReserved(pg);
718 get_page(pg);
719
720 }
721#ifdef CONFIG_PPC64
722 for (i = 0; i < vdso64_pages; i++) {
723 struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
724 ClearPageReserved(pg);
725 get_page(pg);
726 }
727#endif /* CONFIG_PPC64 */
728
729 get_page(virt_to_page(vdso_data));
730}
731
732int in_gate_area_no_task(unsigned long addr)
733{
734 return 0;
735}
736
737int in_gate_area(struct task_struct *task, unsigned long addr)
738{
739 return 0;
740}
741
742struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
743{
744 return NULL;
745}
746
diff --git a/arch/ppc64/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
index 0b1b0df973eb..8a3bed5f143a 100644
--- a/arch/ppc64/kernel/vdso32/Makefile
+++ b/arch/powerpc/kernel/vdso32/Makefile
@@ -5,6 +5,10 @@ obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
5 5
6# Build rules 6# Build rules
7 7
8ifeq ($(CONFIG_PPC32),y)
9CROSS32CC := $(CC)
10endif
11
8targets := $(obj-vdso32) vdso32.so 12targets := $(obj-vdso32) vdso32.so
9obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) 13obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
10 14
@@ -15,7 +19,7 @@ EXTRA_AFLAGS := -D__VDSO32__ -s
15 19
16obj-y += vdso32_wrapper.o 20obj-y += vdso32_wrapper.o
17extra-y += vdso32.lds 21extra-y += vdso32.lds
18CPPFLAGS_vdso32.lds += -P -C -U$(ARCH) 22CPPFLAGS_vdso32.lds += -P -C -Upowerpc
19 23
20# Force dependency (incbin is bad) 24# Force dependency (incbin is bad)
21$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so 25$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
diff --git a/arch/ppc64/kernel/vdso32/cacheflush.S b/arch/powerpc/kernel/vdso32/cacheflush.S
index c8db993574ee..c8db993574ee 100644
--- a/arch/ppc64/kernel/vdso32/cacheflush.S
+++ b/arch/powerpc/kernel/vdso32/cacheflush.S
diff --git a/arch/ppc64/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index 4f4eb0be3992..a08c26e87835 100644
--- a/arch/ppc64/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -66,3 +66,19 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
66 blr 66 blr
67 .cfi_endproc 67 .cfi_endproc
68V_FUNCTION_END(__kernel_get_syscall_map) 68V_FUNCTION_END(__kernel_get_syscall_map)
69
70/*
71 * void unsigned long long __kernel_get_tbfreq(void);
72 *
73 * returns the timebase frequency in HZ
74 */
75V_FUNCTION_BEGIN(__kernel_get_tbfreq)
76 .cfi_startproc
77 mflr r12
78 .cfi_register lr,r12
79 bl __get_datapage@local
80 lwz r3,CFG_TB_TICKS_PER_SEC(r3)
81 lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
82 mtlr r12
83 .cfi_endproc
84V_FUNCTION_END(__kernel_get_tbfreq)
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
new file mode 100644
index 000000000000..aeb5fc9b87b3
--- /dev/null
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -0,0 +1,315 @@
1/*
2 * Userland implementation of gettimeofday() for 32 bits processes in a
3 * ppc64 kernel for use in the vDSO
4 *
5 * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org,
6 * IBM Corp.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13#include <linux/config.h>
14#include <asm/processor.h>
15#include <asm/ppc_asm.h>
16#include <asm/vdso.h>
17#include <asm/asm-offsets.h>
18#include <asm/unistd.h>
19
20 .text
21/*
22 * Exact prototype of gettimeofday
23 *
24 * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz);
25 *
26 */
27V_FUNCTION_BEGIN(__kernel_gettimeofday)
28 .cfi_startproc
29 mflr r12
30 .cfi_register lr,r12
31
32 mr r10,r3 /* r10 saves tv */
33 mr r11,r4 /* r11 saves tz */
34 bl __get_datapage@local /* get data page */
35 mr r9, r3 /* datapage ptr in r9 */
36 bl __do_get_xsec@local /* get xsec from tb & kernel */
37 bne- 2f /* out of line -> do syscall */
38
39 /* seconds are xsec >> 20 */
40 rlwinm r5,r4,12,20,31
41 rlwimi r5,r3,12,0,19
42 stw r5,TVAL32_TV_SEC(r10)
43
44 /* get remaining xsec and convert to usec. we scale
45 * up remaining xsec by 12 bits and get the top 32 bits
46 * of the multiplication
47 */
48 rlwinm r5,r4,12,0,19
49 lis r6,1000000@h
50 ori r6,r6,1000000@l
51 mulhwu r5,r5,r6
52 stw r5,TVAL32_TV_USEC(r10)
53
54 cmpli cr0,r11,0 /* check if tz is NULL */
55 beq 1f
56 lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */
57 lwz r5,CFG_TZ_DSTTIME(r9)
58 stw r4,TZONE_TZ_MINWEST(r11)
59 stw r5,TZONE_TZ_DSTTIME(r11)
60
611: mtlr r12
62 li r3,0
63 blr
64
652:
66 mtlr r12
67 mr r3,r10
68 mr r4,r11
69 li r0,__NR_gettimeofday
70 sc
71 blr
72 .cfi_endproc
73V_FUNCTION_END(__kernel_gettimeofday)
74
75/*
76 * Exact prototype of clock_gettime()
77 *
78 * int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp);
79 *
80 */
81V_FUNCTION_BEGIN(__kernel_clock_gettime)
82 .cfi_startproc
83 /* Check for supported clock IDs */
84 cmpli cr0,r3,CLOCK_REALTIME
85 cmpli cr1,r3,CLOCK_MONOTONIC
86 cror cr0,cr0,cr1
87 bne cr0,99f
88
89 mflr r12 /* r12 saves lr */
90 .cfi_register lr,r12
91 mr r10,r3 /* r10 saves id */
92 mr r11,r4 /* r11 saves tp */
93 bl __get_datapage@local /* get data page */
94 mr r9, r3 /* datapage ptr in r9 */
95 beq cr1,50f /* if monotonic -> jump there */
96
97 /*
98 * CLOCK_REALTIME
99 */
100
101 bl __do_get_xsec@local /* get xsec from tb & kernel */
102 bne- 98f /* out of line -> do syscall */
103
104 /* seconds are xsec >> 20 */
105 rlwinm r5,r4,12,20,31
106 rlwimi r5,r3,12,0,19
107 stw r5,TSPC32_TV_SEC(r11)
108
109 /* get remaining xsec and convert to nsec. we scale
110 * up remaining xsec by 12 bits and get the top 32 bits
111 * of the multiplication, then we multiply by 1000
112 */
113 rlwinm r5,r4,12,0,19
114 lis r6,1000000@h
115 ori r6,r6,1000000@l
116 mulhwu r5,r5,r6
117 mulli r5,r5,1000
118 stw r5,TSPC32_TV_NSEC(r11)
119 mtlr r12
120 li r3,0
121 blr
122
123 /*
124 * CLOCK_MONOTONIC
125 */
126
12750: bl __do_get_xsec@local /* get xsec from tb & kernel */
128 bne- 98f /* out of line -> do syscall */
129
130 /* seconds are xsec >> 20 */
131 rlwinm r6,r4,12,20,31
132 rlwimi r6,r3,12,0,19
133
134 /* get remaining xsec and convert to nsec. we scale
135 * up remaining xsec by 12 bits and get the top 32 bits
136 * of the multiplication, then we multiply by 1000
137 */
138 rlwinm r7,r4,12,0,19
139 lis r5,1000000@h
140 ori r5,r5,1000000@l
141 mulhwu r7,r7,r5
142 mulli r7,r7,1000
143
144 /* now we must fixup using wall to monotonic. We need to snapshot
145 * that value and do the counter trick again. Fortunately, we still
146 * have the counter value in r8 that was returned by __do_get_xsec.
147 * At this point, r6,r7 contain our sec/nsec values, r3,r4 and r5
148 * can be used
149 */
150
151 lwz r3,WTOM_CLOCK_SEC(r9)
152 lwz r4,WTOM_CLOCK_NSEC(r9)
153
154 /* We now have our result in r3,r4. We create a fake dependency
155 * on that result and re-check the counter
156 */
157 or r5,r4,r3
158 xor r0,r5,r5
159 add r9,r9,r0
160#ifdef CONFIG_PPC64
161 lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9)
162#else
163 lwz r0,(CFG_TB_UPDATE_COUNT)(r9)
164#endif
165 cmpl cr0,r8,r0 /* check if updated */
166 bne- 50b
167
168 /* Calculate and store result. Note that this mimmics the C code,
169 * which may cause funny results if nsec goes negative... is that
170 * possible at all ?
171 */
172 add r3,r3,r6
173 add r4,r4,r7
174 lis r5,NSEC_PER_SEC@h
175 ori r5,r5,NSEC_PER_SEC@l
176 cmpli cr0,r4,r5
177 blt 1f
178 subf r4,r5,r4
179 addi r3,r3,1
1801: stw r3,TSPC32_TV_SEC(r11)
181 stw r4,TSPC32_TV_NSEC(r11)
182
183 mtlr r12
184 li r3,0
185 blr
186
187 /*
188 * syscall fallback
189 */
19098:
191 mtlr r12
192 mr r3,r10
193 mr r4,r11
19499:
195 li r0,__NR_clock_gettime
196 sc
197 blr
198 .cfi_endproc
199V_FUNCTION_END(__kernel_clock_gettime)
200
201
202/*
203 * Exact prototype of clock_getres()
204 *
205 * int __kernel_clock_getres(clockid_t clock_id, struct timespec *res);
206 *
207 */
208V_FUNCTION_BEGIN(__kernel_clock_getres)
209 .cfi_startproc
210 /* Check for supported clock IDs */
211 cmpwi cr0,r3,CLOCK_REALTIME
212 cmpwi cr1,r3,CLOCK_MONOTONIC
213 cror cr0,cr0,cr1
214 bne cr0,99f
215
216 li r3,0
217 cmpli cr0,r4,0
218 beqlr
219 lis r5,CLOCK_REALTIME_RES@h
220 ori r5,r5,CLOCK_REALTIME_RES@l
221 stw r3,TSPC32_TV_SEC(r4)
222 stw r5,TSPC32_TV_NSEC(r4)
223 blr
224
225 /*
226 * syscall fallback
227 */
22899:
229 li r0,__NR_clock_getres
230 sc
231 blr
232 .cfi_endproc
233V_FUNCTION_END(__kernel_clock_getres)
234
235
236/*
237 * This is the core of gettimeofday() & friends, it returns the xsec
238 * value in r3 & r4 and expects the datapage ptr (non clobbered)
239 * in r9. clobbers r0,r4,r5,r6,r7,r8.
240 * When returning, r8 contains the counter value that can be reused
241 * by the monotonic clock implementation
242 */
243__do_get_xsec:
244 .cfi_startproc
245 /* Check for update count & load values. We use the low
246 * order 32 bits of the update count
247 */
248#ifdef CONFIG_PPC64
2491: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9)
250#else
2511: lwz r8,(CFG_TB_UPDATE_COUNT)(r9)
252#endif
253 andi. r0,r8,1 /* pending update ? loop */
254 bne- 1b
255 xor r0,r8,r8 /* create dependency */
256 add r9,r9,r0
257
258 /* Load orig stamp (offset to TB) */
259 lwz r5,CFG_TB_ORIG_STAMP(r9)
260 lwz r6,(CFG_TB_ORIG_STAMP+4)(r9)
261
262 /* Get a stable TB value */
2632: mftbu r3
264 mftbl r4
265 mftbu r0
266 cmpl cr0,r3,r0
267 bne- 2b
268
269 /* Substract tb orig stamp. If the high part is non-zero, we jump to
270 * the slow path which call the syscall.
271 * If it's ok, then we have our 32 bits tb_ticks value in r7
272 */
273 subfc r7,r6,r4
274 subfe. r0,r5,r3
275 bne- 3f
276
277 /* Load scale factor & do multiplication */
278 lwz r5,CFG_TB_TO_XS(r9) /* load values */
279 lwz r6,(CFG_TB_TO_XS+4)(r9)
280 mulhwu r4,r7,r5
281 mulhwu r6,r7,r6
282 mullw r0,r7,r5
283 addc r6,r6,r0
284
285 /* At this point, we have the scaled xsec value in r4 + XER:CA
286 * we load & add the stamp since epoch
287 */
288 lwz r5,CFG_STAMP_XSEC(r9)
289 lwz r6,(CFG_STAMP_XSEC+4)(r9)
290 adde r4,r4,r6
291 addze r3,r5
292
293 /* We now have our result in r3,r4. We create a fake dependency
294 * on that result and re-check the counter
295 */
296 or r6,r4,r3
297 xor r0,r6,r6
298 add r9,r9,r0
299#ifdef CONFIG_PPC64
300 lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9)
301#else
302 lwz r0,(CFG_TB_UPDATE_COUNT)(r9)
303#endif
304 cmpl cr0,r8,r0 /* check if updated */
305 bne- 1b
306
307 /* Warning ! The caller expects CR:EQ to be set to indicate a
308 * successful calculation (so it won't fallback to the syscall
309 * method). We have overriden that CR bit in the counter check,
310 * but fortunately, the loop exit condition _is_ CR:EQ set, so
311 * we can exit safely here. If you change this code, be careful
312 * of that side effect.
313 */
3143: blr
315 .cfi_endproc
diff --git a/arch/ppc64/kernel/vdso32/note.S b/arch/powerpc/kernel/vdso32/note.S
index d4b5be4f3d5f..d4b5be4f3d5f 100644
--- a/arch/ppc64/kernel/vdso32/note.S
+++ b/arch/powerpc/kernel/vdso32/note.S
diff --git a/arch/ppc64/kernel/vdso32/sigtramp.S b/arch/powerpc/kernel/vdso32/sigtramp.S
index e04642781917..e04642781917 100644
--- a/arch/ppc64/kernel/vdso32/sigtramp.S
+++ b/arch/powerpc/kernel/vdso32/sigtramp.S
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 6f87a916a394..f4bad720cb0a 100644
--- a/arch/ppc64/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -102,9 +102,12 @@ VERSION
102{ 102{
103 VDSO_VERSION_STRING { 103 VDSO_VERSION_STRING {
104 global: 104 global:
105 __kernel_datapage_offset; /* Has to be there for the kernel to find it */ 105 __kernel_datapage_offset; /* Has to be there for the kernel to find */
106 __kernel_get_syscall_map; 106 __kernel_get_syscall_map;
107 __kernel_gettimeofday; 107 __kernel_gettimeofday;
108 __kernel_clock_gettime;
109 __kernel_clock_getres;
110 __kernel_get_tbfreq;
108 __kernel_sync_dicache; 111 __kernel_sync_dicache;
109 __kernel_sync_dicache_p5; 112 __kernel_sync_dicache_p5;
110 __kernel_sigtramp32; 113 __kernel_sigtramp32;
diff --git a/arch/ppc64/kernel/vdso32/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S
index 76ca28e09d29..556f0caa5d84 100644
--- a/arch/ppc64/kernel/vdso32/vdso32_wrapper.S
+++ b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S
@@ -6,7 +6,7 @@
6 .globl vdso32_start, vdso32_end 6 .globl vdso32_start, vdso32_end
7 .balign PAGE_SIZE 7 .balign PAGE_SIZE
8vdso32_start: 8vdso32_start:
9 .incbin "arch/ppc64/kernel/vdso32/vdso32.so" 9 .incbin "arch/powerpc/kernel/vdso32/vdso32.so"
10 .balign PAGE_SIZE 10 .balign PAGE_SIZE
11vdso32_end: 11vdso32_end:
12 12
diff --git a/arch/ppc64/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
index ab39988452cc..ab39988452cc 100644
--- a/arch/ppc64/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
diff --git a/arch/ppc64/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S
index d4a0ad28d534..d4a0ad28d534 100644
--- a/arch/ppc64/kernel/vdso64/cacheflush.S
+++ b/arch/powerpc/kernel/vdso64/cacheflush.S
diff --git a/arch/ppc64/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index ed6e599ae824..e67eda0f8cda 100644
--- a/arch/ppc64/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -66,3 +66,19 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
66 blr 66 blr
67 .cfi_endproc 67 .cfi_endproc
68V_FUNCTION_END(__kernel_get_syscall_map) 68V_FUNCTION_END(__kernel_get_syscall_map)
69
70
71/*
72 * void unsigned long __kernel_get_tbfreq(void);
73 *
74 * returns the timebase frequency in HZ
75 */
76V_FUNCTION_BEGIN(__kernel_get_tbfreq)
77 .cfi_startproc
78 mflr r12
79 .cfi_register lr,r12
80 bl V_LOCAL_FUNC(__get_datapage)
81 ld r3,CFG_TB_TICKS_PER_SEC(r3)
82 mtlr r12
83 .cfi_endproc
84V_FUNCTION_END(__kernel_get_tbfreq)
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
new file mode 100644
index 000000000000..d371c02a8c0e
--- /dev/null
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -0,0 +1,242 @@
1/*
2 * Userland implementation of gettimeofday() for 64 bits processes in a
3 * ppc64 kernel for use in the vDSO
4 *
5 * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org),
6 * IBM Corp.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13#include <linux/config.h>
14#include <asm/processor.h>
15#include <asm/ppc_asm.h>
16#include <asm/vdso.h>
17#include <asm/asm-offsets.h>
18#include <asm/unistd.h>
19
20 .text
21/*
22 * Exact prototype of gettimeofday
23 *
24 * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz);
25 *
26 */
27V_FUNCTION_BEGIN(__kernel_gettimeofday)
28 .cfi_startproc
29 mflr r12
30 .cfi_register lr,r12
31
32 mr r11,r3 /* r11 holds tv */
33 mr r10,r4 /* r10 holds tz */
34 bl V_LOCAL_FUNC(__get_datapage) /* get data page */
35 bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
36 lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */
37 ori r7,r7,16960
38 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
39 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
40 std r5,TVAL64_TV_SEC(r11) /* store sec in tv */
41 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
42 mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) /
43 * XSEC_PER_SEC
44 */
45 rldicl r0,r0,44,20
46 cmpldi cr0,r10,0 /* check if tz is NULL */
47 std r0,TVAL64_TV_USEC(r11) /* store usec in tv */
48 beq 1f
49 lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */
50 lwz r5,CFG_TZ_DSTTIME(r3)
51 stw r4,TZONE_TZ_MINWEST(r10)
52 stw r5,TZONE_TZ_DSTTIME(r10)
531: mtlr r12
54 li r3,0 /* always success */
55 blr
56 .cfi_endproc
57V_FUNCTION_END(__kernel_gettimeofday)
58
59
60/*
61 * Exact prototype of clock_gettime()
62 *
63 * int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp);
64 *
65 */
66V_FUNCTION_BEGIN(__kernel_clock_gettime)
67 .cfi_startproc
68 /* Check for supported clock IDs */
69 cmpwi cr0,r3,CLOCK_REALTIME
70 cmpwi cr1,r3,CLOCK_MONOTONIC
71 cror cr0,cr0,cr1
72 bne cr0,99f
73
74 mflr r12 /* r12 saves lr */
75 .cfi_register lr,r12
76 mr r10,r3 /* r10 saves id */
77 mr r11,r4 /* r11 saves tp */
78 bl V_LOCAL_FUNC(__get_datapage) /* get data page */
79 beq cr1,50f /* if monotonic -> jump there */
80
81 /*
82 * CLOCK_REALTIME
83 */
84
85 bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
86
87 lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */
88 ori r7,r7,0xca00
89 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
90 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
91 std r5,TSPC64_TV_SEC(r11) /* store sec in tv */
92 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
93 mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) /
94 * XSEC_PER_SEC
95 */
96 rldicl r0,r0,44,20
97 std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */
98
99 mtlr r12
100 li r3,0
101 blr
102
103 /*
104 * CLOCK_MONOTONIC
105 */
106
10750: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
108
109 lis r7,0x3b9a /* r7 = 1000000000 = NSEC_PER_SEC */
110 ori r7,r7,0xca00
111 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
112 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
113 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
114 mulld r0,r0,r7 /* nsec = (xsec * NSEC_PER_SEC) /
115 * XSEC_PER_SEC
116 */
117 rldicl r6,r0,44,20
118
119 /* now we must fixup using wall to monotonic. We need to snapshot
120 * that value and do the counter trick again. Fortunately, we still
121 * have the counter value in r8 that was returned by __do_get_xsec.
122 * At this point, r5,r6 contain our sec/nsec values.
123 * can be used
124 */
125
126 lwz r4,WTOM_CLOCK_SEC(r9)
127 lwz r7,WTOM_CLOCK_NSEC(r9)
128
129 /* We now have our result in r4,r7. We create a fake dependency
130 * on that result and re-check the counter
131 */
132 or r9,r4,r7
133 xor r0,r9,r9
134 add r3,r3,r0
135 ld r0,CFG_TB_UPDATE_COUNT(r3)
136 cmpld cr0,r0,r8 /* check if updated */
137 bne- 50b
138
139 /* Calculate and store result. Note that this mimmics the C code,
140 * which may cause funny results if nsec goes negative... is that
141 * possible at all ?
142 */
143 add r4,r4,r5
144 add r7,r7,r6
145 lis r9,NSEC_PER_SEC@h
146 ori r9,r9,NSEC_PER_SEC@l
147 cmpli cr0,r7,r9
148 blt 1f
149 subf r7,r9,r7
150 addi r4,r4,1
1511: std r4,TSPC64_TV_SEC(r11)
152 std r7,TSPC64_TV_NSEC(r11)
153
154 mtlr r12
155 li r3,0
156 blr
157
158 /*
159 * syscall fallback
160 */
16198:
162 mtlr r12
163 mr r3,r10
164 mr r4,r11
16599:
166 li r0,__NR_clock_gettime
167 sc
168 blr
169 .cfi_endproc
170V_FUNCTION_END(__kernel_clock_gettime)
171
172
173/*
174 * Exact prototype of clock_getres()
175 *
176 * int __kernel_clock_getres(clockid_t clock_id, struct timespec *res);
177 *
178 */
179V_FUNCTION_BEGIN(__kernel_clock_getres)
180 .cfi_startproc
181 /* Check for supported clock IDs */
182 cmpwi cr0,r3,CLOCK_REALTIME
183 cmpwi cr1,r3,CLOCK_MONOTONIC
184 cror cr0,cr0,cr1
185 bne cr0,99f
186
187 li r3,0
188 cmpli cr0,r4,0
189 beqlr
190 lis r5,CLOCK_REALTIME_RES@h
191 ori r5,r5,CLOCK_REALTIME_RES@l
192 std r3,TSPC64_TV_SEC(r4)
193 std r5,TSPC64_TV_NSEC(r4)
194 blr
195
196 /*
197 * syscall fallback
198 */
19999:
200 li r0,__NR_clock_getres
201 sc
202 blr
203 .cfi_endproc
204V_FUNCTION_END(__kernel_clock_getres)
205
206
207/*
208 * This is the core of gettimeofday(), it returns the xsec
209 * value in r4 and expects the datapage ptr (non clobbered)
210 * in r3. clobbers r0,r4,r5,r6,r7,r8
211 * When returning, r8 contains the counter value that can be reused
212 */
213V_FUNCTION_BEGIN(__do_get_xsec)
214 .cfi_startproc
215 /* check for update count & load values */
2161: ld r8,CFG_TB_UPDATE_COUNT(r3)
217 andi. r0,r4,1 /* pending update ? loop */
218 bne- 1b
219 xor r0,r4,r4 /* create dependency */
220 add r3,r3,r0
221
222 /* Get TB & offset it */
223 mftb r7
224 ld r9,CFG_TB_ORIG_STAMP(r3)
225 subf r7,r9,r7
226
227 /* Scale result */
228 ld r5,CFG_TB_TO_XS(r3)
229 mulhdu r7,r7,r5
230
231 /* Add stamp since epoch */
232 ld r6,CFG_STAMP_XSEC(r3)
233 add r4,r6,r7
234
235 xor r0,r4,r4
236 add r3,r3,r0
237 ld r0,CFG_TB_UPDATE_COUNT(r3)
238 cmpld cr0,r0,r8 /* check if updated */
239 bne- 1b
240 blr
241 .cfi_endproc
242V_FUNCTION_END(__do_get_xsec)
diff --git a/arch/ppc64/kernel/vdso64/note.S b/arch/powerpc/kernel/vdso64/note.S
index dc2a509f7e8a..dc2a509f7e8a 100644
--- a/arch/ppc64/kernel/vdso64/note.S
+++ b/arch/powerpc/kernel/vdso64/note.S
diff --git a/arch/ppc64/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S
index 31b604ab56de..31b604ab56de 100644
--- a/arch/ppc64/kernel/vdso64/sigtramp.S
+++ b/arch/powerpc/kernel/vdso64/sigtramp.S
diff --git a/arch/ppc64/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S
index 9cb28181da80..4bdf224464ab 100644
--- a/arch/ppc64/kernel/vdso64/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S
@@ -102,9 +102,12 @@ VERSION
102{ 102{
103 VDSO_VERSION_STRING { 103 VDSO_VERSION_STRING {
104 global: 104 global:
105 __kernel_datapage_offset; /* Has to be there for the kernel to find it */ 105 __kernel_datapage_offset; /* Has to be there for the kernel to find */
106 __kernel_get_syscall_map; 106 __kernel_get_syscall_map;
107 __kernel_gettimeofday; 107 __kernel_gettimeofday;
108 __kernel_clock_gettime;
109 __kernel_clock_getres;
110 __kernel_get_tbfreq;
108 __kernel_sync_dicache; 111 __kernel_sync_dicache;
109 __kernel_sync_dicache_p5; 112 __kernel_sync_dicache_p5;
110 __kernel_sigtramp_rt64; 113 __kernel_sigtramp_rt64;
diff --git a/arch/ppc64/kernel/vdso64/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S
index 771c2741c492..0529cb9e3b97 100644
--- a/arch/ppc64/kernel/vdso64/vdso64_wrapper.S
+++ b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S
@@ -6,7 +6,7 @@
6 .globl vdso64_start, vdso64_end 6 .globl vdso64_start, vdso64_end
7 .balign PAGE_SIZE 7 .balign PAGE_SIZE
8vdso64_start: 8vdso64_start:
9 .incbin "arch/ppc64/kernel/vdso64/vdso64.so" 9 .incbin "arch/powerpc/kernel/vdso64/vdso64.so"
10 .balign PAGE_SIZE 10 .balign PAGE_SIZE
11vdso64_end: 11vdso64_end:
12 12
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 97082a4203ad..71a6addf9f7f 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -21,6 +21,7 @@
21#include <asm/iommu.h> 21#include <asm/iommu.h>
22#include <asm/dma.h> 22#include <asm/dma.h>
23#include <asm/vio.h> 23#include <asm/vio.h>
24#include <asm/prom.h>
24 25
25static const struct vio_device_id *vio_match_device( 26static const struct vio_device_id *vio_match_device(
26 const struct vio_device_id *, const struct vio_dev *); 27 const struct vio_device_id *, const struct vio_dev *);
@@ -265,7 +266,33 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv)
265 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); 266 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
266} 267}
267 268
269static int vio_hotplug(struct device *dev, char **envp, int num_envp,
270 char *buffer, int buffer_size)
271{
272 const struct vio_dev *vio_dev = to_vio_dev(dev);
273 char *cp;
274 int length;
275
276 if (!num_envp)
277 return -ENOMEM;
278
279 if (!vio_dev->dev.platform_data)
280 return -ENODEV;
281 cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length);
282 if (!cp)
283 return -ENODEV;
284
285 envp[0] = buffer;
286 length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
287 vio_dev->type, cp);
288 if (buffer_size - length <= 0)
289 return -ENOMEM;
290 envp[1] = NULL;
291 return 0;
292}
293
268struct bus_type vio_bus_type = { 294struct bus_type vio_bus_type = {
269 .name = "vio", 295 .name = "vio",
296 .hotplug = vio_hotplug,
270 .match = vio_bus_match, 297 .match = vio_bus_match,
271}; 298};
diff --git a/arch/powerpc/lib/bitops.c b/arch/powerpc/lib/bitops.c
index b67ce3004ebf..f68ad71a0187 100644
--- a/arch/powerpc/lib/bitops.c
+++ b/arch/powerpc/lib/bitops.c
@@ -41,7 +41,7 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
41 tmp = *p; 41 tmp = *p;
42 42
43found_first: 43found_first:
44 tmp &= (~0UL >> (64 - size)); 44 tmp &= (~0UL >> (BITS_PER_LONG - size));
45 if (tmp == 0UL) /* Are any bits set? */ 45 if (tmp == 0UL) /* Are any bits set? */
46 return result + size; /* Nope. */ 46 return result + size; /* Nope. */
47found_middle: 47found_middle:
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 22e474876133..706e8a63ced9 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -84,10 +84,11 @@
84extern unsigned long dart_tablebase; 84extern unsigned long dart_tablebase;
85#endif /* CONFIG_U3_DART */ 85#endif /* CONFIG_U3_DART */
86 86
87static unsigned long _SDR1;
88struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
89
87hpte_t *htab_address; 90hpte_t *htab_address;
88unsigned long htab_hash_mask; 91unsigned long htab_hash_mask;
89unsigned long _SDR1;
90struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
91int mmu_linear_psize = MMU_PAGE_4K; 92int mmu_linear_psize = MMU_PAGE_4K;
92int mmu_virtual_psize = MMU_PAGE_4K; 93int mmu_virtual_psize = MMU_PAGE_4K;
93#ifdef CONFIG_HUGETLB_PAGE 94#ifdef CONFIG_HUGETLB_PAGE
@@ -165,7 +166,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
165 * normal insert callback here. 166 * normal insert callback here.
166 */ 167 */
167#ifdef CONFIG_PPC_ISERIES 168#ifdef CONFIG_PPC_ISERIES
168 if (systemcfg->platform == PLATFORM_ISERIES_LPAR) 169 if (_machine == PLATFORM_ISERIES_LPAR)
169 ret = iSeries_hpte_insert(hpteg, va, 170 ret = iSeries_hpte_insert(hpteg, va,
170 virt_to_abs(paddr), 171 virt_to_abs(paddr),
171 tmp_mode, 172 tmp_mode,
@@ -174,7 +175,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
174 else 175 else
175#endif 176#endif
176#ifdef CONFIG_PPC_PSERIES 177#ifdef CONFIG_PPC_PSERIES
177 if (systemcfg->platform & PLATFORM_LPAR) 178 if (_machine & PLATFORM_LPAR)
178 ret = pSeries_lpar_hpte_insert(hpteg, va, 179 ret = pSeries_lpar_hpte_insert(hpteg, va,
179 virt_to_abs(paddr), 180 virt_to_abs(paddr),
180 tmp_mode, 181 tmp_mode,
@@ -293,7 +294,7 @@ static void __init htab_init_page_sizes(void)
293 * Not in the device-tree, let's fallback on known size 294 * Not in the device-tree, let's fallback on known size
294 * list for 16M capable GP & GR 295 * list for 16M capable GP & GR
295 */ 296 */
296 if ((systemcfg->platform != PLATFORM_ISERIES_LPAR) && 297 if ((_machine != PLATFORM_ISERIES_LPAR) &&
297 cpu_has_feature(CPU_FTR_16M_PAGE)) 298 cpu_has_feature(CPU_FTR_16M_PAGE))
298 memcpy(mmu_psize_defs, mmu_psize_defaults_gp, 299 memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
299 sizeof(mmu_psize_defaults_gp)); 300 sizeof(mmu_psize_defaults_gp));
@@ -364,7 +365,7 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
364 365
365static unsigned long __init htab_get_table_size(void) 366static unsigned long __init htab_get_table_size(void)
366{ 367{
367 unsigned long rnd_mem_size, pteg_count; 368 unsigned long mem_size, rnd_mem_size, pteg_count;
368 369
369 /* If hash size isn't already provided by the platform, we try to 370 /* If hash size isn't already provided by the platform, we try to
370 * retreive it from the device-tree. If it's not there neither, we 371 * retreive it from the device-tree. If it's not there neither, we
@@ -376,8 +377,9 @@ static unsigned long __init htab_get_table_size(void)
376 return 1UL << ppc64_pft_size; 377 return 1UL << ppc64_pft_size;
377 378
378 /* round mem_size up to next power of 2 */ 379 /* round mem_size up to next power of 2 */
379 rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); 380 mem_size = lmb_phys_mem_size();
380 if (rnd_mem_size < systemcfg->physicalMemorySize) 381 rnd_mem_size = 1UL << __ilog2(mem_size);
382 if (rnd_mem_size < mem_size)
381 rnd_mem_size <<= 1; 383 rnd_mem_size <<= 1;
382 384
383 /* # pages / 2 */ 385 /* # pages / 2 */
@@ -386,6 +388,15 @@ static unsigned long __init htab_get_table_size(void)
386 return pteg_count << 7; 388 return pteg_count << 7;
387} 389}
388 390
391#ifdef CONFIG_MEMORY_HOTPLUG
392void create_section_mapping(unsigned long start, unsigned long end)
393{
394 BUG_ON(htab_bolt_mapping(start, end, start,
395 _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
396 mmu_linear_psize));
397}
398#endif /* CONFIG_MEMORY_HOTPLUG */
399
389void __init htab_initialize(void) 400void __init htab_initialize(void)
390{ 401{
391 unsigned long table, htab_size_bytes; 402 unsigned long table, htab_size_bytes;
@@ -410,7 +421,7 @@ void __init htab_initialize(void)
410 421
411 htab_hash_mask = pteg_count - 1; 422 htab_hash_mask = pteg_count - 1;
412 423
413 if (systemcfg->platform & PLATFORM_LPAR) { 424 if (platform_is_lpar()) {
414 /* Using a hypervisor which owns the htab */ 425 /* Using a hypervisor which owns the htab */
415 htab_address = NULL; 426 htab_address = NULL;
416 _SDR1 = 0; 427 _SDR1 = 0;
@@ -431,6 +442,9 @@ void __init htab_initialize(void)
431 442
432 /* Initialize the HPT with no entries */ 443 /* Initialize the HPT with no entries */
433 memset((void *)table, 0, htab_size_bytes); 444 memset((void *)table, 0, htab_size_bytes);
445
446 /* Set SDR1 */
447 mtspr(SPRN_SDR1, _SDR1);
434 } 448 }
435 449
436 mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; 450 mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
@@ -500,6 +514,12 @@ void __init htab_initialize(void)
500#undef KB 514#undef KB
501#undef MB 515#undef MB
502 516
517void __init htab_initialize_secondary(void)
518{
519 if (!platform_is_lpar())
520 mtspr(SPRN_SDR1, _SDR1);
521}
522
503/* 523/*
504 * Called by asm hashtable.S for doing lazy icache flush 524 * Called by asm hashtable.S for doing lazy icache flush
505 */ 525 */
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 4612a79dfb6e..7d4b8b5f0606 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -84,9 +84,6 @@ void MMU_init(void);
84/* XXX should be in current.h -- paulus */ 84/* XXX should be in current.h -- paulus */
85extern struct task_struct *current_set[NR_CPUS]; 85extern struct task_struct *current_set[NR_CPUS];
86 86
87char *klimit = _end;
88struct device_node *memory_node;
89
90extern int init_bootmem_done; 87extern int init_bootmem_done;
91 88
92/* 89/*
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index ce974c83d88a..1134f70f231d 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -20,6 +20,8 @@
20 * 20 *
21 */ 21 */
22 22
23#undef DEBUG
24
23#include <linux/config.h> 25#include <linux/config.h>
24#include <linux/signal.h> 26#include <linux/signal.h>
25#include <linux/sched.h> 27#include <linux/sched.h>
@@ -64,6 +66,12 @@
64#include <asm/vdso.h> 66#include <asm/vdso.h>
65#include <asm/imalloc.h> 67#include <asm/imalloc.h>
66 68
69#ifdef DEBUG
70#define DBG(fmt...) printk(fmt)
71#else
72#define DBG(fmt...)
73#endif
74
67#if PGTABLE_RANGE > USER_VSID_RANGE 75#if PGTABLE_RANGE > USER_VSID_RANGE
68#warning Limited user VSID range means pagetable space is wasted 76#warning Limited user VSID range means pagetable space is wasted
69#endif 77#endif
@@ -72,8 +80,6 @@
72#warning TASK_SIZE is smaller than it needs to be. 80#warning TASK_SIZE is smaller than it needs to be.
73#endif 81#endif
74 82
75unsigned long klimit = (unsigned long)_end;
76
77/* max amount of RAM to use */ 83/* max amount of RAM to use */
78unsigned long __max_memory; 84unsigned long __max_memory;
79 85
@@ -188,14 +194,14 @@ static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
188} 194}
189 195
190#ifdef CONFIG_PPC_64K_PAGES 196#ifdef CONFIG_PPC_64K_PAGES
191static const int pgtable_cache_size[2] = { 197static const unsigned int pgtable_cache_size[3] = {
192 PTE_TABLE_SIZE, PGD_TABLE_SIZE 198 PTE_TABLE_SIZE, PMD_TABLE_SIZE, PGD_TABLE_SIZE
193}; 199};
194static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { 200static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
195 "pte_pmd_cache", "pgd_cache", 201 "pte_pmd_cache", "pmd_cache", "pgd_cache",
196}; 202};
197#else 203#else
198static const int pgtable_cache_size[2] = { 204static const unsigned int pgtable_cache_size[2] = {
199 PTE_TABLE_SIZE, PMD_TABLE_SIZE 205 PTE_TABLE_SIZE, PMD_TABLE_SIZE
200}; 206};
201static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { 207static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
@@ -213,6 +219,8 @@ void pgtable_cache_init(void)
213 int size = pgtable_cache_size[i]; 219 int size = pgtable_cache_size[i];
214 const char *name = pgtable_cache_name[i]; 220 const char *name = pgtable_cache_name[i];
215 221
222 DBG("Allocating page table cache %s (#%d) "
223 "for size: %08x...\n", name, i, size);
216 pgtable_cache[i] = kmem_cache_create(name, 224 pgtable_cache[i] = kmem_cache_create(name,
217 size, size, 225 size, size,
218 SLAB_HWCACHE_ALIGN | 226 SLAB_HWCACHE_ALIGN |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 6f55efd9be95..e2c95fcb8055 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -46,9 +46,7 @@
46#include <asm/prom.h> 46#include <asm/prom.h>
47#include <asm/lmb.h> 47#include <asm/lmb.h>
48#include <asm/sections.h> 48#include <asm/sections.h>
49#ifdef CONFIG_PPC64
50#include <asm/vdso.h> 49#include <asm/vdso.h>
51#endif
52 50
53#include "mmu_decl.h" 51#include "mmu_decl.h"
54 52
@@ -110,6 +108,7 @@ EXPORT_SYMBOL(phys_mem_access_prot);
110void online_page(struct page *page) 108void online_page(struct page *page)
111{ 109{
112 ClearPageReserved(page); 110 ClearPageReserved(page);
111 set_page_count(page, 0);
113 free_cold_page(page); 112 free_cold_page(page);
114 totalram_pages++; 113 totalram_pages++;
115 num_physpages++; 114 num_physpages++;
@@ -127,6 +126,9 @@ int __devinit add_memory(u64 start, u64 size)
127 unsigned long start_pfn = start >> PAGE_SHIFT; 126 unsigned long start_pfn = start >> PAGE_SHIFT;
128 unsigned long nr_pages = size >> PAGE_SHIFT; 127 unsigned long nr_pages = size >> PAGE_SHIFT;
129 128
129 start += KERNELBASE;
130 create_section_mapping(start, start + size);
131
130 /* this should work for most non-highmem platforms */ 132 /* this should work for most non-highmem platforms */
131 zone = pgdata->node_zones; 133 zone = pgdata->node_zones;
132 134
@@ -393,10 +395,8 @@ void __init mem_init(void)
393 395
394 mem_init_done = 1; 396 mem_init_done = 1;
395 397
396#ifdef CONFIG_PPC64
397 /* Initialize the vDSO */ 398 /* Initialize the vDSO */
398 vdso_init(); 399 vdso_init();
399#endif
400} 400}
401 401
402/* 402/*
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index da09ba03c424..bd2cf1336885 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -17,9 +17,8 @@
17#include <linux/nodemask.h> 17#include <linux/nodemask.h>
18#include <linux/cpu.h> 18#include <linux/cpu.h>
19#include <linux/notifier.h> 19#include <linux/notifier.h>
20#include <asm/sparsemem.h>
20#include <asm/lmb.h> 21#include <asm/lmb.h>
21#include <asm/machdep.h>
22#include <asm/abs_addr.h>
23#include <asm/system.h> 22#include <asm/system.h>
24#include <asm/smp.h> 23#include <asm/smp.h>
25 24
@@ -28,45 +27,113 @@ static int numa_enabled = 1;
28static int numa_debug; 27static int numa_debug;
29#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } 28#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
30 29
31#ifdef DEBUG_NUMA 30int numa_cpu_lookup_table[NR_CPUS];
32#define ARRAY_INITIALISER -1
33#else
34#define ARRAY_INITIALISER 0
35#endif
36
37int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] =
38 ARRAY_INITIALISER};
39char *numa_memory_lookup_table;
40cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES]; 31cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
41int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0};
42
43struct pglist_data *node_data[MAX_NUMNODES]; 32struct pglist_data *node_data[MAX_NUMNODES];
44bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES]; 33
34EXPORT_SYMBOL(numa_cpu_lookup_table);
35EXPORT_SYMBOL(numa_cpumask_lookup_table);
36EXPORT_SYMBOL(node_data);
37
38static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
45static int min_common_depth; 39static int min_common_depth;
46 40
47/* 41/*
48 * We need somewhere to store start/span for each node until we have 42 * We need somewhere to store start/end/node for each region until we have
49 * allocated the real node_data structures. 43 * allocated the real node_data structures.
50 */ 44 */
45#define MAX_REGIONS (MAX_LMB_REGIONS*2)
51static struct { 46static struct {
52 unsigned long node_start_pfn; 47 unsigned long start_pfn;
53 unsigned long node_end_pfn; 48 unsigned long end_pfn;
54 unsigned long node_present_pages; 49 int nid;
55} init_node_data[MAX_NUMNODES] __initdata; 50} init_node_data[MAX_REGIONS] __initdata;
56 51
57EXPORT_SYMBOL(node_data); 52int __init early_pfn_to_nid(unsigned long pfn)
58EXPORT_SYMBOL(numa_cpu_lookup_table); 53{
59EXPORT_SYMBOL(numa_memory_lookup_table); 54 unsigned int i;
60EXPORT_SYMBOL(numa_cpumask_lookup_table); 55
61EXPORT_SYMBOL(nr_cpus_in_node); 56 for (i = 0; init_node_data[i].end_pfn; i++) {
57 unsigned long start_pfn = init_node_data[i].start_pfn;
58 unsigned long end_pfn = init_node_data[i].end_pfn;
59
60 if ((start_pfn <= pfn) && (pfn < end_pfn))
61 return init_node_data[i].nid;
62 }
63
64 return -1;
65}
66
67void __init add_region(unsigned int nid, unsigned long start_pfn,
68 unsigned long pages)
69{
70 unsigned int i;
71
72 dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n",
73 nid, start_pfn, pages);
74
75 for (i = 0; init_node_data[i].end_pfn; i++) {
76 if (init_node_data[i].nid != nid)
77 continue;
78 if (init_node_data[i].end_pfn == start_pfn) {
79 init_node_data[i].end_pfn += pages;
80 return;
81 }
82 if (init_node_data[i].start_pfn == (start_pfn + pages)) {
83 init_node_data[i].start_pfn -= pages;
84 return;
85 }
86 }
87
88 /*
89 * Leave last entry NULL so we dont iterate off the end (we use
90 * entry.end_pfn to terminate the walk).
91 */
92 if (i >= (MAX_REGIONS - 1)) {
93 printk(KERN_ERR "WARNING: too many memory regions in "
94 "numa code, truncating\n");
95 return;
96 }
97
98 init_node_data[i].start_pfn = start_pfn;
99 init_node_data[i].end_pfn = start_pfn + pages;
100 init_node_data[i].nid = nid;
101}
102
103/* We assume init_node_data has no overlapping regions */
104void __init get_region(unsigned int nid, unsigned long *start_pfn,
105 unsigned long *end_pfn, unsigned long *pages_present)
106{
107 unsigned int i;
108
109 *start_pfn = -1UL;
110 *end_pfn = *pages_present = 0;
111
112 for (i = 0; init_node_data[i].end_pfn; i++) {
113 if (init_node_data[i].nid != nid)
114 continue;
115
116 *pages_present += init_node_data[i].end_pfn -
117 init_node_data[i].start_pfn;
118
119 if (init_node_data[i].start_pfn < *start_pfn)
120 *start_pfn = init_node_data[i].start_pfn;
121
122 if (init_node_data[i].end_pfn > *end_pfn)
123 *end_pfn = init_node_data[i].end_pfn;
124 }
125
126 /* We didnt find a matching region, return start/end as 0 */
127 if (*start_pfn == -1UL)
128 start_pfn = 0;
129}
62 130
63static inline void map_cpu_to_node(int cpu, int node) 131static inline void map_cpu_to_node(int cpu, int node)
64{ 132{
65 numa_cpu_lookup_table[cpu] = node; 133 numa_cpu_lookup_table[cpu] = node;
66 if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) { 134
135 if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node])))
67 cpu_set(cpu, numa_cpumask_lookup_table[node]); 136 cpu_set(cpu, numa_cpumask_lookup_table[node]);
68 nr_cpus_in_node[node]++;
69 }
70} 137}
71 138
72#ifdef CONFIG_HOTPLUG_CPU 139#ifdef CONFIG_HOTPLUG_CPU
@@ -78,7 +145,6 @@ static void unmap_cpu_from_node(unsigned long cpu)
78 145
79 if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) { 146 if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
80 cpu_clear(cpu, numa_cpumask_lookup_table[node]); 147 cpu_clear(cpu, numa_cpumask_lookup_table[node]);
81 nr_cpus_in_node[node]--;
82 } else { 148 } else {
83 printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n", 149 printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
84 cpu, node); 150 cpu, node);
@@ -86,7 +152,7 @@ static void unmap_cpu_from_node(unsigned long cpu)
86} 152}
87#endif /* CONFIG_HOTPLUG_CPU */ 153#endif /* CONFIG_HOTPLUG_CPU */
88 154
89static struct device_node * __devinit find_cpu_node(unsigned int cpu) 155static struct device_node *find_cpu_node(unsigned int cpu)
90{ 156{
91 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); 157 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
92 struct device_node *cpu_node = NULL; 158 struct device_node *cpu_node = NULL;
@@ -213,7 +279,7 @@ static int __init get_mem_size_cells(void)
213 return rc; 279 return rc;
214} 280}
215 281
216static unsigned long read_n_cells(int n, unsigned int **buf) 282static unsigned long __init read_n_cells(int n, unsigned int **buf)
217{ 283{
218 unsigned long result = 0; 284 unsigned long result = 0;
219 285
@@ -295,7 +361,8 @@ static int cpu_numa_callback(struct notifier_block *nfb,
295 * or zero. If the returned value of size is 0 the region should be 361 * or zero. If the returned value of size is 0 the region should be
296 * discarded as it lies wholy above the memory limit. 362 * discarded as it lies wholy above the memory limit.
297 */ 363 */
298static unsigned long __init numa_enforce_memory_limit(unsigned long start, unsigned long size) 364static unsigned long __init numa_enforce_memory_limit(unsigned long start,
365 unsigned long size)
299{ 366{
300 /* 367 /*
301 * We use lmb_end_of_DRAM() in here instead of memory_limit because 368 * We use lmb_end_of_DRAM() in here instead of memory_limit because
@@ -320,8 +387,7 @@ static int __init parse_numa_properties(void)
320 struct device_node *cpu = NULL; 387 struct device_node *cpu = NULL;
321 struct device_node *memory = NULL; 388 struct device_node *memory = NULL;
322 int addr_cells, size_cells; 389 int addr_cells, size_cells;
323 int max_domain = 0; 390 int max_domain;
324 long entries = lmb_end_of_DRAM() >> MEMORY_INCREMENT_SHIFT;
325 unsigned long i; 391 unsigned long i;
326 392
327 if (numa_enabled == 0) { 393 if (numa_enabled == 0) {
@@ -329,13 +395,6 @@ static int __init parse_numa_properties(void)
329 return -1; 395 return -1;
330 } 396 }
331 397
332 numa_memory_lookup_table =
333 (char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
334 memset(numa_memory_lookup_table, 0, entries * sizeof(char));
335
336 for (i = 0; i < entries ; i++)
337 numa_memory_lookup_table[i] = ARRAY_INITIALISER;
338
339 min_common_depth = find_min_common_depth(); 398 min_common_depth = find_min_common_depth();
340 399
341 dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth); 400 dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
@@ -387,9 +446,6 @@ new_range:
387 start = read_n_cells(addr_cells, &memcell_buf); 446 start = read_n_cells(addr_cells, &memcell_buf);
388 size = read_n_cells(size_cells, &memcell_buf); 447 size = read_n_cells(size_cells, &memcell_buf);
389 448
390 start = _ALIGN_DOWN(start, MEMORY_INCREMENT);
391 size = _ALIGN_UP(size, MEMORY_INCREMENT);
392
393 numa_domain = of_node_numa_domain(memory); 449 numa_domain = of_node_numa_domain(memory);
394 450
395 if (numa_domain >= MAX_NUMNODES) { 451 if (numa_domain >= MAX_NUMNODES) {
@@ -403,44 +459,15 @@ new_range:
403 if (max_domain < numa_domain) 459 if (max_domain < numa_domain)
404 max_domain = numa_domain; 460 max_domain = numa_domain;
405 461
406 if (! (size = numa_enforce_memory_limit(start, size))) { 462 if (!(size = numa_enforce_memory_limit(start, size))) {
407 if (--ranges) 463 if (--ranges)
408 goto new_range; 464 goto new_range;
409 else 465 else
410 continue; 466 continue;
411 } 467 }
412 468
413 /* 469 add_region(numa_domain, start >> PAGE_SHIFT,
414 * Initialize new node struct, or add to an existing one. 470 size >> PAGE_SHIFT);
415 */
416 if (init_node_data[numa_domain].node_end_pfn) {
417 if ((start / PAGE_SIZE) <
418 init_node_data[numa_domain].node_start_pfn)
419 init_node_data[numa_domain].node_start_pfn =
420 start / PAGE_SIZE;
421 if (((start / PAGE_SIZE) + (size / PAGE_SIZE)) >
422 init_node_data[numa_domain].node_end_pfn)
423 init_node_data[numa_domain].node_end_pfn =
424 (start / PAGE_SIZE) +
425 (size / PAGE_SIZE);
426
427 init_node_data[numa_domain].node_present_pages +=
428 size / PAGE_SIZE;
429 } else {
430 node_set_online(numa_domain);
431
432 init_node_data[numa_domain].node_start_pfn =
433 start / PAGE_SIZE;
434 init_node_data[numa_domain].node_end_pfn =
435 init_node_data[numa_domain].node_start_pfn +
436 size / PAGE_SIZE;
437 init_node_data[numa_domain].node_present_pages =
438 size / PAGE_SIZE;
439 }
440
441 for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
442 numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
443 numa_domain;
444 471
445 if (--ranges) 472 if (--ranges)
446 goto new_range; 473 goto new_range;
@@ -456,32 +483,15 @@ static void __init setup_nonnuma(void)
456{ 483{
457 unsigned long top_of_ram = lmb_end_of_DRAM(); 484 unsigned long top_of_ram = lmb_end_of_DRAM();
458 unsigned long total_ram = lmb_phys_mem_size(); 485 unsigned long total_ram = lmb_phys_mem_size();
459 unsigned long i;
460 486
461 printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", 487 printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
462 top_of_ram, total_ram); 488 top_of_ram, total_ram);
463 printk(KERN_INFO "Memory hole size: %ldMB\n", 489 printk(KERN_INFO "Memory hole size: %ldMB\n",
464 (top_of_ram - total_ram) >> 20); 490 (top_of_ram - total_ram) >> 20);
465 491
466 if (!numa_memory_lookup_table) {
467 long entries = top_of_ram >> MEMORY_INCREMENT_SHIFT;
468 numa_memory_lookup_table =
469 (char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
470 memset(numa_memory_lookup_table, 0, entries * sizeof(char));
471 for (i = 0; i < entries ; i++)
472 numa_memory_lookup_table[i] = ARRAY_INITIALISER;
473 }
474
475 map_cpu_to_node(boot_cpuid, 0); 492 map_cpu_to_node(boot_cpuid, 0);
476 493 add_region(0, 0, lmb_end_of_DRAM() >> PAGE_SHIFT);
477 node_set_online(0); 494 node_set_online(0);
478
479 init_node_data[0].node_start_pfn = 0;
480 init_node_data[0].node_end_pfn = lmb_end_of_DRAM() / PAGE_SIZE;
481 init_node_data[0].node_present_pages = total_ram / PAGE_SIZE;
482
483 for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT)
484 numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
485} 495}
486 496
487static void __init dump_numa_topology(void) 497static void __init dump_numa_topology(void)
@@ -499,8 +509,9 @@ static void __init dump_numa_topology(void)
499 509
500 count = 0; 510 count = 0;
501 511
502 for (i = 0; i < lmb_end_of_DRAM(); i += MEMORY_INCREMENT) { 512 for (i = 0; i < lmb_end_of_DRAM();
503 if (numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] == node) { 513 i += (1 << SECTION_SIZE_BITS)) {
514 if (early_pfn_to_nid(i >> PAGE_SHIFT) == node) {
504 if (count == 0) 515 if (count == 0)
505 printk(" 0x%lx", i); 516 printk(" 0x%lx", i);
506 ++count; 517 ++count;
@@ -525,10 +536,12 @@ static void __init dump_numa_topology(void)
525 * 536 *
526 * Returns the physical address of the memory. 537 * Returns the physical address of the memory.
527 */ 538 */
528static unsigned long careful_allocation(int nid, unsigned long size, 539static void __init *careful_allocation(int nid, unsigned long size,
529 unsigned long align, unsigned long end) 540 unsigned long align,
541 unsigned long end_pfn)
530{ 542{
531 unsigned long ret = lmb_alloc_base(size, align, end); 543 int new_nid;
544 unsigned long ret = lmb_alloc_base(size, align, end_pfn << PAGE_SHIFT);
532 545
533 /* retry over all memory */ 546 /* retry over all memory */
534 if (!ret) 547 if (!ret)
@@ -542,28 +555,27 @@ static unsigned long careful_allocation(int nid, unsigned long size,
542 * If the memory came from a previously allocated node, we must 555 * If the memory came from a previously allocated node, we must
543 * retry with the bootmem allocator. 556 * retry with the bootmem allocator.
544 */ 557 */
545 if (pa_to_nid(ret) < nid) { 558 new_nid = early_pfn_to_nid(ret >> PAGE_SHIFT);
546 nid = pa_to_nid(ret); 559 if (new_nid < nid) {
547 ret = (unsigned long)__alloc_bootmem_node(NODE_DATA(nid), 560 ret = (unsigned long)__alloc_bootmem_node(NODE_DATA(new_nid),
548 size, align, 0); 561 size, align, 0);
549 562
550 if (!ret) 563 if (!ret)
551 panic("numa.c: cannot allocate %lu bytes on node %d", 564 panic("numa.c: cannot allocate %lu bytes on node %d",
552 size, nid); 565 size, new_nid);
553 566
554 ret = virt_to_abs(ret); 567 ret = __pa(ret);
555 568
556 dbg("alloc_bootmem %lx %lx\n", ret, size); 569 dbg("alloc_bootmem %lx %lx\n", ret, size);
557 } 570 }
558 571
559 return ret; 572 return (void *)ret;
560} 573}
561 574
562void __init do_init_bootmem(void) 575void __init do_init_bootmem(void)
563{ 576{
564 int nid; 577 int nid;
565 int addr_cells, size_cells; 578 unsigned int i;
566 struct device_node *memory = NULL;
567 static struct notifier_block ppc64_numa_nb = { 579 static struct notifier_block ppc64_numa_nb = {
568 .notifier_call = cpu_numa_callback, 580 .notifier_call = cpu_numa_callback,
569 .priority = 1 /* Must run before sched domains notifier. */ 581 .priority = 1 /* Must run before sched domains notifier. */
@@ -581,99 +593,66 @@ void __init do_init_bootmem(void)
581 register_cpu_notifier(&ppc64_numa_nb); 593 register_cpu_notifier(&ppc64_numa_nb);
582 594
583 for_each_online_node(nid) { 595 for_each_online_node(nid) {
584 unsigned long start_paddr, end_paddr; 596 unsigned long start_pfn, end_pfn, pages_present;
585 int i;
586 unsigned long bootmem_paddr; 597 unsigned long bootmem_paddr;
587 unsigned long bootmap_pages; 598 unsigned long bootmap_pages;
588 599
589 start_paddr = init_node_data[nid].node_start_pfn * PAGE_SIZE; 600 get_region(nid, &start_pfn, &end_pfn, &pages_present);
590 end_paddr = init_node_data[nid].node_end_pfn * PAGE_SIZE;
591 601
592 /* Allocate the node structure node local if possible */ 602 /* Allocate the node structure node local if possible */
593 NODE_DATA(nid) = (struct pglist_data *)careful_allocation(nid, 603 NODE_DATA(nid) = careful_allocation(nid,
594 sizeof(struct pglist_data), 604 sizeof(struct pglist_data),
595 SMP_CACHE_BYTES, end_paddr); 605 SMP_CACHE_BYTES, end_pfn);
596 NODE_DATA(nid) = abs_to_virt(NODE_DATA(nid)); 606 NODE_DATA(nid) = __va(NODE_DATA(nid));
597 memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); 607 memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
598 608
599 dbg("node %d\n", nid); 609 dbg("node %d\n", nid);
600 dbg("NODE_DATA() = %p\n", NODE_DATA(nid)); 610 dbg("NODE_DATA() = %p\n", NODE_DATA(nid));
601 611
602 NODE_DATA(nid)->bdata = &plat_node_bdata[nid]; 612 NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
603 NODE_DATA(nid)->node_start_pfn = 613 NODE_DATA(nid)->node_start_pfn = start_pfn;
604 init_node_data[nid].node_start_pfn; 614 NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
605 NODE_DATA(nid)->node_spanned_pages =
606 end_paddr - start_paddr;
607 615
608 if (NODE_DATA(nid)->node_spanned_pages == 0) 616 if (NODE_DATA(nid)->node_spanned_pages == 0)
609 continue; 617 continue;
610 618
611 dbg("start_paddr = %lx\n", start_paddr); 619 dbg("start_paddr = %lx\n", start_pfn << PAGE_SHIFT);
612 dbg("end_paddr = %lx\n", end_paddr); 620 dbg("end_paddr = %lx\n", end_pfn << PAGE_SHIFT);
613 621
614 bootmap_pages = bootmem_bootmap_pages((end_paddr - start_paddr) >> PAGE_SHIFT); 622 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
623 bootmem_paddr = (unsigned long)careful_allocation(nid,
624 bootmap_pages << PAGE_SHIFT,
625 PAGE_SIZE, end_pfn);
626 memset(__va(bootmem_paddr), 0, bootmap_pages << PAGE_SHIFT);
615 627
616 bootmem_paddr = careful_allocation(nid,
617 bootmap_pages << PAGE_SHIFT,
618 PAGE_SIZE, end_paddr);
619 memset(abs_to_virt(bootmem_paddr), 0,
620 bootmap_pages << PAGE_SHIFT);
621 dbg("bootmap_paddr = %lx\n", bootmem_paddr); 628 dbg("bootmap_paddr = %lx\n", bootmem_paddr);
622 629
623 init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, 630 init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
624 start_paddr >> PAGE_SHIFT, 631 start_pfn, end_pfn);
625 end_paddr >> PAGE_SHIFT);
626 632
627 /* 633 /* Add free regions on this node */
628 * We need to do another scan of all memory sections to 634 for (i = 0; init_node_data[i].end_pfn; i++) {
629 * associate memory with the correct node. 635 unsigned long start, end;
630 */
631 addr_cells = get_mem_addr_cells();
632 size_cells = get_mem_size_cells();
633 memory = NULL;
634 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
635 unsigned long mem_start, mem_size;
636 int numa_domain, ranges;
637 unsigned int *memcell_buf;
638 unsigned int len;
639
640 memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
641 if (!memcell_buf || len <= 0)
642 continue;
643 636
644 ranges = memory->n_addrs; /* ranges in cell */ 637 if (init_node_data[i].nid != nid)
645new_range:
646 mem_start = read_n_cells(addr_cells, &memcell_buf);
647 mem_size = read_n_cells(size_cells, &memcell_buf);
648 if (numa_enabled) {
649 numa_domain = of_node_numa_domain(memory);
650 if (numa_domain >= MAX_NUMNODES)
651 numa_domain = 0;
652 } else
653 numa_domain = 0;
654
655 if (numa_domain != nid)
656 continue; 638 continue;
657 639
658 mem_size = numa_enforce_memory_limit(mem_start, mem_size); 640 start = init_node_data[i].start_pfn << PAGE_SHIFT;
659 if (mem_size) { 641 end = init_node_data[i].end_pfn << PAGE_SHIFT;
660 dbg("free_bootmem %lx %lx\n", mem_start, mem_size);
661 free_bootmem_node(NODE_DATA(nid), mem_start, mem_size);
662 }
663 642
664 if (--ranges) /* process all ranges in cell */ 643 dbg("free_bootmem %lx %lx\n", start, end - start);
665 goto new_range; 644 free_bootmem_node(NODE_DATA(nid), start, end - start);
666 } 645 }
667 646
668 /* 647 /* Mark reserved regions on this node */
669 * Mark reserved regions on this node
670 */
671 for (i = 0; i < lmb.reserved.cnt; i++) { 648 for (i = 0; i < lmb.reserved.cnt; i++) {
672 unsigned long physbase = lmb.reserved.region[i].base; 649 unsigned long physbase = lmb.reserved.region[i].base;
673 unsigned long size = lmb.reserved.region[i].size; 650 unsigned long size = lmb.reserved.region[i].size;
651 unsigned long start_paddr = start_pfn << PAGE_SHIFT;
652 unsigned long end_paddr = end_pfn << PAGE_SHIFT;
674 653
675 if (pa_to_nid(physbase) != nid && 654 if (early_pfn_to_nid(physbase >> PAGE_SHIFT) != nid &&
676 pa_to_nid(physbase+size-1) != nid) 655 early_pfn_to_nid((physbase+size-1) >> PAGE_SHIFT) != nid)
677 continue; 656 continue;
678 657
679 if (physbase < end_paddr && 658 if (physbase < end_paddr &&
@@ -693,46 +672,19 @@ new_range:
693 size); 672 size);
694 } 673 }
695 } 674 }
696 /*
697 * This loop may look famaliar, but we have to do it again
698 * after marking our reserved memory to mark memory present
699 * for sparsemem.
700 */
701 addr_cells = get_mem_addr_cells();
702 size_cells = get_mem_size_cells();
703 memory = NULL;
704 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
705 unsigned long mem_start, mem_size;
706 int numa_domain, ranges;
707 unsigned int *memcell_buf;
708 unsigned int len;
709
710 memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
711 if (!memcell_buf || len <= 0)
712 continue;
713 675
714 ranges = memory->n_addrs; /* ranges in cell */ 676 /* Add regions into sparsemem */
715new_range2: 677 for (i = 0; init_node_data[i].end_pfn; i++) {
716 mem_start = read_n_cells(addr_cells, &memcell_buf); 678 unsigned long start, end;
717 mem_size = read_n_cells(size_cells, &memcell_buf); 679
718 if (numa_enabled) { 680 if (init_node_data[i].nid != nid)
719 numa_domain = of_node_numa_domain(memory);
720 if (numa_domain >= MAX_NUMNODES)
721 numa_domain = 0;
722 } else
723 numa_domain = 0;
724
725 if (numa_domain != nid)
726 continue; 681 continue;
727 682
728 mem_size = numa_enforce_memory_limit(mem_start, mem_size); 683 start = init_node_data[i].start_pfn;
729 memory_present(numa_domain, mem_start >> PAGE_SHIFT, 684 end = init_node_data[i].end_pfn;
730 (mem_start + mem_size) >> PAGE_SHIFT);
731 685
732 if (--ranges) /* process all ranges in cell */ 686 memory_present(nid, start, end);
733 goto new_range2;
734 } 687 }
735
736 } 688 }
737} 689}
738 690
@@ -746,21 +698,18 @@ void __init paging_init(void)
746 memset(zholes_size, 0, sizeof(zholes_size)); 698 memset(zholes_size, 0, sizeof(zholes_size));
747 699
748 for_each_online_node(nid) { 700 for_each_online_node(nid) {
749 unsigned long start_pfn; 701 unsigned long start_pfn, end_pfn, pages_present;
750 unsigned long end_pfn;
751 702
752 start_pfn = init_node_data[nid].node_start_pfn; 703 get_region(nid, &start_pfn, &end_pfn, &pages_present);
753 end_pfn = init_node_data[nid].node_end_pfn;
754 704
755 zones_size[ZONE_DMA] = end_pfn - start_pfn; 705 zones_size[ZONE_DMA] = end_pfn - start_pfn;
756 zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - 706 zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present;
757 init_node_data[nid].node_present_pages;
758 707
759 dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid, 708 dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid,
760 zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]); 709 zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]);
761 710
762 free_area_init_node(nid, NODE_DATA(nid), zones_size, 711 free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn,
763 start_pfn, zholes_size); 712 zholes_size);
764 } 713 }
765} 714}
766 715
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 900842451bd3..c7f7bb6f30b3 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -122,8 +122,11 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
122 * 122 *
123 */ 123 */
124 if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags, 124 if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
125 mmu_virtual_psize)) 125 mmu_virtual_psize)) {
126 panic("Can't map bolted IO mapping"); 126 printk(KERN_ERR "Failed to do bolted mapping IO "
127 "memory at %016lx !\n", pa);
128 return -ENOMEM;
129 }
127 } 130 }
128 return 0; 131 return 0;
129} 132}
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index fa325dbf98fc..cfbb4e1f966b 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -20,6 +20,7 @@
20#include <asm/cputable.h> 20#include <asm/cputable.h>
21#include <asm/lmb.h> 21#include <asm/lmb.h>
22#include <asm/abs_addr.h> 22#include <asm/abs_addr.h>
23#include <asm/firmware.h>
23 24
24struct stab_entry { 25struct stab_entry {
25 unsigned long esid_data; 26 unsigned long esid_data;
@@ -256,7 +257,7 @@ void stabs_alloc(void)
256 257
257 paca[cpu].stab_addr = newstab; 258 paca[cpu].stab_addr = newstab;
258 paca[cpu].stab_real = virt_to_abs(newstab); 259 paca[cpu].stab_real = virt_to_abs(newstab);
259 printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx " 260 printk(KERN_INFO "Segment table for CPU %d at 0x%lx "
260 "virtual, 0x%lx absolute\n", 261 "virtual, 0x%lx absolute\n",
261 cpu, paca[cpu].stab_addr, paca[cpu].stab_real); 262 cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
262 } 263 }
@@ -270,10 +271,28 @@ void stabs_alloc(void)
270void stab_initialize(unsigned long stab) 271void stab_initialize(unsigned long stab)
271{ 272{
272 unsigned long vsid = get_kernel_vsid(KERNELBASE); 273 unsigned long vsid = get_kernel_vsid(KERNELBASE);
274 unsigned long stabreal;
273 275
274 asm volatile("isync; slbia; isync":::"memory"); 276 asm volatile("isync; slbia; isync":::"memory");
275 make_ste(stab, GET_ESID(KERNELBASE), vsid); 277 make_ste(stab, GET_ESID(KERNELBASE), vsid);
276 278
277 /* Order update */ 279 /* Order update */
278 asm volatile("sync":::"memory"); 280 asm volatile("sync":::"memory");
281
282 /* Set ASR */
283 stabreal = get_paca()->stab_real | 0x1ul;
284
285#ifdef CONFIG_PPC_ISERIES
286 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
287 HvCall1(HvCallBaseSetASR, stabreal);
288 return;
289 }
290#endif /* CONFIG_PPC_ISERIES */
291#ifdef CONFIG_PPC_PSERIES
292 if (platform_is_lpar()) {
293 plpar_hcall_norets(H_SET_ASR, stabreal);
294 return;
295 }
296#endif
297 mtspr(SPRN_ASR, stabreal);
279} 298}
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index c4ee5478427b..a3401b46f3ba 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -14,7 +14,6 @@
14#include <asm/system.h> 14#include <asm/system.h>
15#include <asm/processor.h> 15#include <asm/processor.h>
16#include <asm/cputable.h> 16#include <asm/cputable.h>
17#include <asm/systemcfg.h>
18#include <asm/rtas.h> 17#include <asm/rtas.h>
19#include <asm/oprofile_impl.h> 18#include <asm/oprofile_impl.h>
20#include <asm/reg.h> 19#include <asm/reg.h>
@@ -233,8 +232,7 @@ static unsigned long get_pc(struct pt_regs *regs)
233 mmcra = mfspr(SPRN_MMCRA); 232 mmcra = mfspr(SPRN_MMCRA);
234 233
235 /* Were we in the hypervisor? */ 234 /* Were we in the hypervisor? */
236 if ((systemcfg->platform == PLATFORM_PSERIES_LPAR) && 235 if (platform_is_lpar() && (mmcra & MMCRA_SIHV))
237 (mmcra & MMCRA_SIHV))
238 /* function descriptor madness */ 236 /* function descriptor madness */
239 return *((unsigned long *)hypervisor_bucket); 237 return *((unsigned long *)hypervisor_bucket);
240 238
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index ecd32d5d85f4..4099ddab9205 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -361,7 +361,9 @@ static void __init chrp_find_openpic(void)
361 printk(KERN_INFO "OpenPIC at %lx\n", opaddr); 361 printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
362 362
363 irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */ 363 irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
364 prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS - 4); 364 prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4);
365 /* i8259 cascade is always positive level */
366 init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE;
365 367
366 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); 368 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
367 if (iranges == NULL) 369 if (iranges == NULL)
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index a06603d84a45..01090e9ce0cf 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -103,6 +103,9 @@ static void intReceived(struct XmPciLpEvent *eventParm,
103 struct pt_regs *regsParm) 103 struct pt_regs *regsParm)
104{ 104{
105 int irq; 105 int irq;
106#ifdef CONFIG_IRQSTACKS
107 struct thread_info *curtp, *irqtp;
108#endif
106 109
107 ++Pci_Interrupt_Count; 110 ++Pci_Interrupt_Count;
108 111
@@ -110,7 +113,20 @@ static void intReceived(struct XmPciLpEvent *eventParm,
110 case XmPciLpEvent_SlotInterrupt: 113 case XmPciLpEvent_SlotInterrupt:
111 irq = eventParm->hvLpEvent.xCorrelationToken; 114 irq = eventParm->hvLpEvent.xCorrelationToken;
112 /* Dispatch the interrupt handlers for this irq */ 115 /* Dispatch the interrupt handlers for this irq */
113 ppc_irq_dispatch_handler(regsParm, irq); 116#ifdef CONFIG_IRQSTACKS
117 /* Switch to the irq stack to handle this */
118 curtp = current_thread_info();
119 irqtp = hardirq_ctx[smp_processor_id()];
120 if (curtp != irqtp) {
121 irqtp->task = curtp->task;
122 irqtp->flags = 0;
123 call___do_IRQ(irq, regsParm, irqtp);
124 irqtp->task = NULL;
125 if (irqtp->flags)
126 set_bits(irqtp->flags, &curtp->flags);
127 } else
128#endif
129 __do_IRQ(irq, regsParm);
114 HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, 130 HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
115 eventParm->eventData.slotInterrupt.subBusNumber, 131 eventParm->eventData.slotInterrupt.subBusNumber,
116 eventParm->eventData.slotInterrupt.deviceId); 132 eventParm->eventData.slotInterrupt.deviceId);
@@ -310,10 +326,8 @@ static void iSeries_disable_IRQ(unsigned int irq)
310} 326}
311 327
312/* 328/*
313 * Need to define this so ppc_irq_dispatch_handler will NOT call 329 * This does nothing because there is not enough information
314 * enable_IRQ at the end of interrupt handling. However, this does 330 * provided to do the EOI HvCall. This is done by XmPciLpEvent.c
315 * nothing because there is not enough information provided to do
316 * the EOI HvCall. This is done by XmPciLpEvent.c
317 */ 331 */
318static void iSeries_end_IRQ(unsigned int irq) 332static void iSeries_end_IRQ(unsigned int irq)
319{ 333{
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S
index 09f14522e176..dfe7aa1ba098 100644
--- a/arch/powerpc/platforms/iseries/misc.S
+++ b/arch/powerpc/platforms/iseries/misc.S
@@ -15,6 +15,7 @@
15 15
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <asm/asm-offsets.h> 17#include <asm/asm-offsets.h>
18#include <asm/ppc_asm.h>
18 19
19 .text 20 .text
20 21
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index d3e4bf756c83..6a29f301436b 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -39,7 +39,8 @@
39#include <asm/sections.h> 39#include <asm/sections.h>
40#include <asm/iommu.h> 40#include <asm/iommu.h>
41#include <asm/firmware.h> 41#include <asm/firmware.h>
42 42#include <asm/systemcfg.h>
43#include <asm/system.h>
43#include <asm/time.h> 44#include <asm/time.h>
44#include <asm/paca.h> 45#include <asm/paca.h>
45#include <asm/cache.h> 46#include <asm/cache.h>
@@ -71,7 +72,7 @@ extern void hvlog(char *fmt, ...);
71#endif 72#endif
72 73
73/* Function Prototypes */ 74/* Function Prototypes */
74static void build_iSeries_Memory_Map(void); 75static unsigned long build_iSeries_Memory_Map(void);
75static void iseries_shared_idle(void); 76static void iseries_shared_idle(void);
76static void iseries_dedicated_idle(void); 77static void iseries_dedicated_idle(void);
77#ifdef CONFIG_PCI 78#ifdef CONFIG_PCI
@@ -84,7 +85,6 @@ static void iSeries_pci_final_fixup(void) { }
84int piranha_simulator; 85int piranha_simulator;
85 86
86extern int rd_size; /* Defined in drivers/block/rd.c */ 87extern int rd_size; /* Defined in drivers/block/rd.c */
87extern unsigned long klimit;
88extern unsigned long embedded_sysmap_start; 88extern unsigned long embedded_sysmap_start;
89extern unsigned long embedded_sysmap_end; 89extern unsigned long embedded_sysmap_end;
90 90
@@ -403,9 +403,11 @@ void mschunks_alloc(unsigned long num_chunks)
403 * a table used to translate Linux's physical addresses to these 403 * a table used to translate Linux's physical addresses to these
404 * absolute addresses. Absolute addresses are needed when 404 * absolute addresses. Absolute addresses are needed when
405 * communicating with the hypervisor (e.g. to build HPT entries) 405 * communicating with the hypervisor (e.g. to build HPT entries)
406 *
407 * Returns the physical memory size
406 */ 408 */
407 409
408static void __init build_iSeries_Memory_Map(void) 410static unsigned long __init build_iSeries_Memory_Map(void)
409{ 411{
410 u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize; 412 u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;
411 u32 nextPhysChunk; 413 u32 nextPhysChunk;
@@ -538,7 +540,7 @@ static void __init build_iSeries_Memory_Map(void)
538 * which should be equal to 540 * which should be equal to
539 * nextPhysChunk 541 * nextPhysChunk
540 */ 542 */
541 systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk); 543 return chunk_to_addr(nextPhysChunk);
542} 544}
543 545
544/* 546/*
@@ -564,8 +566,8 @@ static void __init iSeries_setup_arch(void)
564 printk("Max physical processors = %d\n", 566 printk("Max physical processors = %d\n",
565 itVpdAreas.xSlicMaxPhysicalProcs); 567 itVpdAreas.xSlicMaxPhysicalProcs);
566 568
567 systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; 569 _systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
568 printk("Processor version = %x\n", systemcfg->processor); 570 printk("Processor version = %x\n", _systemcfg->processor);
569} 571}
570 572
571static void iSeries_show_cpuinfo(struct seq_file *m) 573static void iSeries_show_cpuinfo(struct seq_file *m)
@@ -694,20 +696,18 @@ static void iseries_shared_idle(void)
694 if (hvlpevent_is_pending()) 696 if (hvlpevent_is_pending())
695 process_iSeries_events(); 697 process_iSeries_events();
696 698
699 preempt_enable_no_resched();
697 schedule(); 700 schedule();
701 preempt_disable();
698 } 702 }
699} 703}
700 704
701static void iseries_dedicated_idle(void) 705static void iseries_dedicated_idle(void)
702{ 706{
703 long oldval; 707 set_thread_flag(TIF_POLLING_NRFLAG);
704 708
705 while (1) { 709 while (1) {
706 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 710 if (!need_resched()) {
707
708 if (!oldval) {
709 set_thread_flag(TIF_POLLING_NRFLAG);
710
711 while (!need_resched()) { 711 while (!need_resched()) {
712 ppc64_runlatch_off(); 712 ppc64_runlatch_off();
713 HMT_low(); 713 HMT_low();
@@ -720,13 +720,12 @@ static void iseries_dedicated_idle(void)
720 } 720 }
721 721
722 HMT_medium(); 722 HMT_medium();
723 clear_thread_flag(TIF_POLLING_NRFLAG);
724 } else {
725 set_need_resched();
726 } 723 }
727 724
728 ppc64_runlatch_on(); 725 ppc64_runlatch_on();
726 preempt_enable_no_resched();
729 schedule(); 727 schedule();
728 preempt_disable();
730 } 729 }
731} 730}
732 731
@@ -931,7 +930,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
931 dt_end_node(dt); 930 dt_end_node(dt);
932} 931}
933 932
934void build_flat_dt(struct iseries_flat_dt *dt) 933void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
935{ 934{
936 u64 tmp[2]; 935 u64 tmp[2];
937 936
@@ -947,7 +946,7 @@ void build_flat_dt(struct iseries_flat_dt *dt)
947 dt_prop_str(dt, "name", "memory"); 946 dt_prop_str(dt, "name", "memory");
948 dt_prop_str(dt, "device_type", "memory"); 947 dt_prop_str(dt, "device_type", "memory");
949 tmp[0] = 0; 948 tmp[0] = 0;
950 tmp[1] = systemcfg->physicalMemorySize; 949 tmp[1] = phys_mem_size;
951 dt_prop_u64_list(dt, "reg", tmp, 2); 950 dt_prop_u64_list(dt, "reg", tmp, 2);
952 dt_end_node(dt); 951 dt_end_node(dt);
953 952
@@ -967,13 +966,15 @@ void build_flat_dt(struct iseries_flat_dt *dt)
967 966
968void * __init iSeries_early_setup(void) 967void * __init iSeries_early_setup(void)
969{ 968{
969 unsigned long phys_mem_size;
970
970 iSeries_fixup_klimit(); 971 iSeries_fixup_klimit();
971 972
972 /* 973 /*
973 * Initialize the table which translate Linux physical addresses to 974 * Initialize the table which translate Linux physical addresses to
974 * AS/400 absolute addresses 975 * AS/400 absolute addresses
975 */ 976 */
976 build_iSeries_Memory_Map(); 977 phys_mem_size = build_iSeries_Memory_Map();
977 978
978 iSeries_get_cmdline(); 979 iSeries_get_cmdline();
979 980
@@ -983,7 +984,7 @@ void * __init iSeries_early_setup(void)
983 /* Parse early parameters, in particular mem=x */ 984 /* Parse early parameters, in particular mem=x */
984 parse_early_param(); 985 parse_early_param();
985 986
986 build_flat_dt(&iseries_dt); 987 build_flat_dt(&iseries_dt, phys_mem_size);
987 988
988 return (void *) __pa(&iseries_dt); 989 return (void *) __pa(&iseries_dt);
989} 990}
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 340c21caeae2..895aeb3f75d0 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -380,9 +380,6 @@ void __init maple_pcibios_fixup(void)
380 for_each_pci_dev(dev) 380 for_each_pci_dev(dev)
381 pci_read_irq_line(dev); 381 pci_read_irq_line(dev);
382 382
383 /* Do the mapping of the IO space */
384 phbs_remap_io();
385
386 DBG(" <- maple_pcibios_fixup\n"); 383 DBG(" <- maple_pcibios_fixup\n");
387} 384}
388 385
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 8f818d092e2b..dfd41b9781a9 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -918,9 +918,6 @@ void __init pmac_pci_init(void)
918 PCI_DN(np)->busno = 0xf0; 918 PCI_DN(np)->busno = 0xf0;
919 } 919 }
920 920
921 /* map in PCI I/O space */
922 phbs_remap_io();
923
924 /* pmac_check_ht_link(); */ 921 /* pmac_check_ht_link(); */
925 922
926 /* Tell pci.c to not use the common resource allocation mechanism */ 923 /* Tell pci.c to not use the common resource allocation mechanism */
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 83a49e80ac29..90040c49494d 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -74,6 +74,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock);
74#define GATWICK_IRQ_POOL_SIZE 10 74#define GATWICK_IRQ_POOL_SIZE 10
75static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; 75static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
76 76
77#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
78static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
79
77/* 80/*
78 * Mark an irq as "lost". This is only used on the pmac 81 * Mark an irq as "lost". This is only used on the pmac
79 * since it can lose interrupts (see pmac_set_irq_mask). 82 * since it can lose interrupts (see pmac_set_irq_mask).
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index e1f9443cc872..957b09103422 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void)
305 psurge_start = ioremap(PSURGE_START, 4); 305 psurge_start = ioremap(PSURGE_START, 4);
306 psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); 306 psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
307 307
308 /* this is not actually strictly necessary -- paulus. */ 308 /*
309 for (i = 1; i < ncpus; ++i) 309 * This is necessary because OF doesn't know about the
310 smp_hw_index[i] = i; 310 * secondary cpu(s), and thus there aren't nodes in the
311 * device tree for them, and smp_setup_cpu_maps hasn't
312 * set their bits in cpu_possible_map and cpu_present_map.
313 */
314 if (ncpus > NR_CPUS)
315 ncpus = NR_CPUS;
316 for (i = 1; i < ncpus ; ++i) {
317 cpu_set(i, cpu_present_map);
318 cpu_set(i, cpu_possible_map);
319 set_hard_smp_processor_id(i, i);
320 }
311 321
312 if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); 322 if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
313 323
@@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
348 int t; 358 int t;
349 359
350 set_dec(tb_ticks_per_jiffy); 360 set_dec(tb_ticks_per_jiffy);
361 /* XXX fixme */
351 set_tb(0, 0); 362 set_tb(0, 0);
352 last_jiffy_stamp(cpu_nr) = 0; 363 last_jiffy_stamp(cpu_nr) = 0;
353 364
@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
363 374
364 /* now interrupt the secondary, starting both TBs */ 375 /* now interrupt the secondary, starting both TBs */
365 psurge_set_ipi(1); 376 psurge_set_ipi(1);
366
367 smp_tb_synchronized = 1;
368} 377}
369 378
370static struct irqaction psurge_irqaction = { 379static struct irqaction psurge_irqaction = {
@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void)
625 for (t = 100000; t > 0 && sec_tb_reset; --t) 634 for (t = 100000; t > 0 && sec_tb_reset; --t)
626 udelay(10); 635 udelay(10);
627 if (sec_tb_reset) 636 if (sec_tb_reset)
637 /* XXX BUG_ON here? */
628 printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); 638 printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
629 else
630 smp_tb_synchronized = 1;
631 639
632 /* Now, restart the timebase by leaving the GPIO to an open collector */ 640 /* Now, restart the timebase by leaving the GPIO to an open collector */
633 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); 641 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
@@ -810,19 +818,9 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
810} 818}
811 819
812 820
813/* Core99 Macs (dual G4s and G5s) */
814struct smp_ops_t core99_smp_ops = {
815 .message_pass = smp_mpic_message_pass,
816 .probe = smp_core99_probe,
817 .kick_cpu = smp_core99_kick_cpu,
818 .setup_cpu = smp_core99_setup_cpu,
819 .give_timebase = smp_core99_give_timebase,
820 .take_timebase = smp_core99_take_timebase,
821};
822
823#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) 821#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
824 822
825int __cpu_disable(void) 823int smp_core99_cpu_disable(void)
826{ 824{
827 cpu_clear(smp_processor_id(), cpu_online_map); 825 cpu_clear(smp_processor_id(), cpu_online_map);
828 826
@@ -846,7 +844,7 @@ void cpu_die(void)
846 low_cpu_die(); 844 low_cpu_die();
847} 845}
848 846
849void __cpu_die(unsigned int cpu) 847void smp_core99_cpu_die(unsigned int cpu)
850{ 848{
851 int timeout; 849 int timeout;
852 850
@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu)
858 } 856 }
859 msleep(1); 857 msleep(1);
860 } 858 }
861 cpu_callin_map[cpu] = 0;
862 cpu_dead[cpu] = 0; 859 cpu_dead[cpu] = 0;
863} 860}
864 861
865#endif 862#endif
863
864/* Core99 Macs (dual G4s and G5s) */
865struct smp_ops_t core99_smp_ops = {
866 .message_pass = smp_mpic_message_pass,
867 .probe = smp_core99_probe,
868 .kick_cpu = smp_core99_kick_cpu,
869 .setup_cpu = smp_core99_setup_cpu,
870 .give_timebase = smp_core99_give_timebase,
871 .take_timebase = smp_core99_take_timebase,
872#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
873 .cpu_disable = smp_core99_cpu_disable,
874 .cpu_die = smp_core99_cpu_die,
875#endif
876};
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index b9938fece781..e7ca5b1f591e 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -3,3 +3,5 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
3obj-$(CONFIG_SMP) += smp.o 3obj-$(CONFIG_SMP) += smp.o
4obj-$(CONFIG_IBMVIO) += vio.o 4obj-$(CONFIG_IBMVIO) += vio.o
5obj-$(CONFIG_XICS) += xics.o 5obj-$(CONFIG_XICS) += xics.o
6obj-$(CONFIG_SCANLOG) += scanlog.o
7obj-$(CONFIG_EEH) += eeh.o eeh_event.o
diff --git a/arch/ppc64/kernel/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 035d1b14a207..79de2310e70b 100644
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1,39 +1,37 @@
1/* 1/*
2 * eeh.c 2 * eeh.c
3 * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation 3 * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or 7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version. 8 * (at your option) any later version.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 19
20#include <linux/bootmem.h> 20#include <linux/delay.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/mm.h>
24#include <linux/notifier.h>
25#include <linux/pci.h> 23#include <linux/pci.h>
26#include <linux/proc_fs.h> 24#include <linux/proc_fs.h>
27#include <linux/rbtree.h> 25#include <linux/rbtree.h>
28#include <linux/seq_file.h> 26#include <linux/seq_file.h>
29#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <asm/atomic.h>
30#include <asm/eeh.h> 29#include <asm/eeh.h>
30#include <asm/eeh_event.h>
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/machdep.h> 32#include <asm/machdep.h>
33#include <asm/rtas.h>
34#include <asm/atomic.h>
35#include <asm/systemcfg.h>
36#include <asm/ppc-pci.h> 33#include <asm/ppc-pci.h>
34#include <asm/rtas.h>
37 35
38#undef DEBUG 36#undef DEBUG
39 37
@@ -49,8 +47,8 @@
49 * were "empty": all reads return 0xff's and all writes are silently 47 * were "empty": all reads return 0xff's and all writes are silently
50 * ignored. EEH slot isolation events can be triggered by parity 48 * ignored. EEH slot isolation events can be triggered by parity
51 * errors on the address or data busses (e.g. during posted writes), 49 * errors on the address or data busses (e.g. during posted writes),
52 * which in turn might be caused by dust, vibration, humidity, 50 * which in turn might be caused by low voltage on the bus, dust,
53 * radioactivity or plain-old failed hardware. 51 * vibration, humidity, radioactivity or plain-old failed hardware.
54 * 52 *
55 * Note, however, that one of the leading causes of EEH slot 53 * Note, however, that one of the leading causes of EEH slot
56 * freeze events are buggy device drivers, buggy device microcode, 54 * freeze events are buggy device drivers, buggy device microcode,
@@ -71,26 +69,15 @@
71 * and sent out for processing. 69 * and sent out for processing.
72 */ 70 */
73 71
74/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */ 72/* If a device driver keeps reading an MMIO register in an interrupt
75#define BUID_HI(buid) ((buid) >> 32)
76#define BUID_LO(buid) ((buid) & 0xffffffff)
77
78/* EEH event workqueue setup. */
79static DEFINE_SPINLOCK(eeh_eventlist_lock);
80LIST_HEAD(eeh_eventlist);
81static void eeh_event_handler(void *);
82DECLARE_WORK(eeh_event_wq, eeh_event_handler, NULL);
83
84static struct notifier_block *eeh_notifier_chain;
85
86/*
87 * If a device driver keeps reading an MMIO register in an interrupt
88 * handler after a slot isolation event has occurred, we assume it 73 * handler after a slot isolation event has occurred, we assume it
89 * is broken and panic. This sets the threshold for how many read 74 * is broken and panic. This sets the threshold for how many read
90 * attempts we allow before panicking. 75 * attempts we allow before panicking.
91 */ 76 */
92#define EEH_MAX_FAILS 1000 77#define EEH_MAX_FAILS 100000
93static atomic_t eeh_fail_count; 78
79/* Misc forward declaraions */
80static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn);
94 81
95/* RTAS tokens */ 82/* RTAS tokens */
96static int ibm_set_eeh_option; 83static int ibm_set_eeh_option;
@@ -101,12 +88,19 @@ static int ibm_slot_error_detail;
101 88
102static int eeh_subsystem_enabled; 89static int eeh_subsystem_enabled;
103 90
91/* Lock to avoid races due to multiple reports of an error */
92static DEFINE_SPINLOCK(confirm_error_lock);
93
104/* Buffer for reporting slot-error-detail rtas calls */ 94/* Buffer for reporting slot-error-detail rtas calls */
105static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX]; 95static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
106static DEFINE_SPINLOCK(slot_errbuf_lock); 96static DEFINE_SPINLOCK(slot_errbuf_lock);
107static int eeh_error_buf_size; 97static int eeh_error_buf_size;
108 98
109/* System monitoring statistics */ 99/* System monitoring statistics */
100static DEFINE_PER_CPU(unsigned long, no_device);
101static DEFINE_PER_CPU(unsigned long, no_dn);
102static DEFINE_PER_CPU(unsigned long, no_cfg_addr);
103static DEFINE_PER_CPU(unsigned long, ignored_check);
110static DEFINE_PER_CPU(unsigned long, total_mmio_ffs); 104static DEFINE_PER_CPU(unsigned long, total_mmio_ffs);
111static DEFINE_PER_CPU(unsigned long, false_positives); 105static DEFINE_PER_CPU(unsigned long, false_positives);
112static DEFINE_PER_CPU(unsigned long, ignored_failures); 106static DEFINE_PER_CPU(unsigned long, ignored_failures);
@@ -224,9 +218,9 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
224 while (*p) { 218 while (*p) {
225 parent = *p; 219 parent = *p;
226 piar = rb_entry(parent, struct pci_io_addr_range, rb_node); 220 piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
227 if (alo < piar->addr_lo) { 221 if (ahi < piar->addr_lo) {
228 p = &parent->rb_left; 222 p = &parent->rb_left;
229 } else if (ahi > piar->addr_hi) { 223 } else if (alo > piar->addr_hi) {
230 p = &parent->rb_right; 224 p = &parent->rb_right;
231 } else { 225 } else {
232 if (dev != piar->pcidev || 226 if (dev != piar->pcidev ||
@@ -245,6 +239,11 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
245 piar->pcidev = dev; 239 piar->pcidev = dev;
246 piar->flags = flags; 240 piar->flags = flags;
247 241
242#ifdef DEBUG
243 printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n",
244 alo, ahi, pci_name (dev));
245#endif
246
248 rb_link_node(&piar->rb_node, parent, p); 247 rb_link_node(&piar->rb_node, parent, p);
249 rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root); 248 rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
250 249
@@ -260,18 +259,17 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
260 259
261 dn = pci_device_to_OF_node(dev); 260 dn = pci_device_to_OF_node(dev);
262 if (!dn) { 261 if (!dn) {
263 printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", 262 printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev));
264 pci_name(dev));
265 return; 263 return;
266 } 264 }
267 265
268 /* Skip any devices for which EEH is not enabled. */ 266 /* Skip any devices for which EEH is not enabled. */
269 pdn = dn->data; 267 pdn = PCI_DN(dn);
270 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || 268 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
271 pdn->eeh_mode & EEH_MODE_NOCHECK) { 269 pdn->eeh_mode & EEH_MODE_NOCHECK) {
272#ifdef DEBUG 270#ifdef DEBUG
273 printk(KERN_INFO "PCI: skip building address cache for=%s\n", 271 printk(KERN_INFO "PCI: skip building address cache for=%s - %s\n",
274 pci_name(dev)); 272 pci_name(dev), pdn->node->full_name);
275#endif 273#endif
276 return; 274 return;
277 } 275 }
@@ -307,7 +305,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
307 * we maintain a cache of devices that can be quickly searched. 305 * we maintain a cache of devices that can be quickly searched.
308 * This routine adds a device to that cache. 306 * This routine adds a device to that cache.
309 */ 307 */
310void pci_addr_cache_insert_device(struct pci_dev *dev) 308static void pci_addr_cache_insert_device(struct pci_dev *dev)
311{ 309{
312 unsigned long flags; 310 unsigned long flags;
313 311
@@ -350,7 +348,7 @@ restart:
350 * the tree multiple times (once per resource). 348 * the tree multiple times (once per resource).
351 * But so what; device removal doesn't need to be that fast. 349 * But so what; device removal doesn't need to be that fast.
352 */ 350 */
353void pci_addr_cache_remove_device(struct pci_dev *dev) 351static void pci_addr_cache_remove_device(struct pci_dev *dev)
354{ 352{
355 unsigned long flags; 353 unsigned long flags;
356 354
@@ -370,8 +368,12 @@ void pci_addr_cache_remove_device(struct pci_dev *dev)
370 */ 368 */
371void __init pci_addr_cache_build(void) 369void __init pci_addr_cache_build(void)
372{ 370{
371 struct device_node *dn;
373 struct pci_dev *dev = NULL; 372 struct pci_dev *dev = NULL;
374 373
374 if (!eeh_subsystem_enabled)
375 return;
376
375 spin_lock_init(&pci_io_addr_cache_root.piar_lock); 377 spin_lock_init(&pci_io_addr_cache_root.piar_lock);
376 378
377 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 379 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
@@ -380,6 +382,10 @@ void __init pci_addr_cache_build(void)
380 continue; 382 continue;
381 } 383 }
382 pci_addr_cache_insert_device(dev); 384 pci_addr_cache_insert_device(dev);
385
386 /* Save the BAR's; firmware doesn't restore these after EEH reset */
387 dn = pci_device_to_OF_node(dev);
388 eeh_save_bars(dev, PCI_DN(dn));
383 } 389 }
384 390
385#ifdef DEBUG 391#ifdef DEBUG
@@ -391,22 +397,26 @@ void __init pci_addr_cache_build(void)
391/* --------------------------------------------------------------- */ 397/* --------------------------------------------------------------- */
392/* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */ 398/* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */
393 399
394/** 400void eeh_slot_error_detail (struct pci_dn *pdn, int severity)
395 * eeh_register_notifier - Register to find out about EEH events.
396 * @nb: notifier block to callback on events
397 */
398int eeh_register_notifier(struct notifier_block *nb)
399{ 401{
400 return notifier_chain_register(&eeh_notifier_chain, nb); 402 unsigned long flags;
401} 403 int rc;
402 404
403/** 405 /* Log the error with the rtas logger */
404 * eeh_unregister_notifier - Unregister to an EEH event notifier. 406 spin_lock_irqsave(&slot_errbuf_lock, flags);
405 * @nb: notifier block to callback on events 407 memset(slot_errbuf, 0, eeh_error_buf_size);
406 */ 408
407int eeh_unregister_notifier(struct notifier_block *nb) 409 rc = rtas_call(ibm_slot_error_detail,
408{ 410 8, 1, NULL, pdn->eeh_config_addr,
409 return notifier_chain_unregister(&eeh_notifier_chain, nb); 411 BUID_HI(pdn->phb->buid),
412 BUID_LO(pdn->phb->buid), NULL, 0,
413 virt_to_phys(slot_errbuf),
414 eeh_error_buf_size,
415 severity);
416
417 if (rc == 0)
418 log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
419 spin_unlock_irqrestore(&slot_errbuf_lock, flags);
410} 420}
411 421
412/** 422/**
@@ -414,16 +424,16 @@ int eeh_unregister_notifier(struct notifier_block *nb)
414 * @dn: device node to read 424 * @dn: device node to read
415 * @rets: array to return results in 425 * @rets: array to return results in
416 */ 426 */
417static int read_slot_reset_state(struct device_node *dn, int rets[]) 427static int read_slot_reset_state(struct pci_dn *pdn, int rets[])
418{ 428{
419 int token, outputs; 429 int token, outputs;
420 struct pci_dn *pdn = dn->data;
421 430
422 if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { 431 if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
423 token = ibm_read_slot_reset_state2; 432 token = ibm_read_slot_reset_state2;
424 outputs = 4; 433 outputs = 4;
425 } else { 434 } else {
426 token = ibm_read_slot_reset_state; 435 token = ibm_read_slot_reset_state;
436 rets[2] = 0; /* fake PE Unavailable info */
427 outputs = 3; 437 outputs = 3;
428 } 438 }
429 439
@@ -432,87 +442,84 @@ static int read_slot_reset_state(struct device_node *dn, int rets[])
432} 442}
433 443
434/** 444/**
435 * eeh_panic - call panic() for an eeh event that cannot be handled. 445 * eeh_token_to_phys - convert EEH address token to phys address
436 * The philosophy of this routine is that it is better to panic and 446 * @token i/o token, should be address in the form 0xA....
437 * halt the OS than it is to risk possible data corruption by
438 * oblivious device drivers that don't know better.
439 *
440 * @dev pci device that had an eeh event
441 * @reset_state current reset state of the device slot
442 */ 447 */
443static void eeh_panic(struct pci_dev *dev, int reset_state) 448static inline unsigned long eeh_token_to_phys(unsigned long token)
444{ 449{
445 /* 450 pte_t *ptep;
446 * XXX We should create a separate sysctl for this. 451 unsigned long pa;
447 * 452
448 * Since the panic_on_oops sysctl is used to halt the system 453 ptep = find_linux_pte(init_mm.pgd, token);
449 * in light of potential corruption, we can use it here. 454 if (!ptep)
450 */ 455 return token;
451 if (panic_on_oops) 456 pa = pte_pfn(*ptep) << PAGE_SHIFT;
452 panic("EEH: MMIO failure (%d) on device:%s\n", reset_state, 457
453 pci_name(dev)); 458 return pa | (token & (PAGE_SIZE-1));
454 else {
455 __get_cpu_var(ignored_failures)++;
456 printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
457 reset_state, pci_name(dev));
458 }
459} 459}
460 460
461/** 461/**
462 * eeh_event_handler - dispatch EEH events. The detection of a frozen 462 * Return the "partitionable endpoint" (pe) under which this device lies
463 * slot can occur inside an interrupt, where it can be hard to do
464 * anything about it. The goal of this routine is to pull these
465 * detection events out of the context of the interrupt handler, and
466 * re-dispatch them for processing at a later time in a normal context.
467 *
468 * @dummy - unused
469 */ 463 */
470static void eeh_event_handler(void *dummy) 464static struct device_node * find_device_pe(struct device_node *dn)
471{ 465{
472 unsigned long flags; 466 while ((dn->parent) && PCI_DN(dn->parent) &&
473 struct eeh_event *event; 467 (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
474 468 dn = dn->parent;
475 while (1) { 469 }
476 spin_lock_irqsave(&eeh_eventlist_lock, flags); 470 return dn;
477 event = NULL; 471}
478 if (!list_empty(&eeh_eventlist)) {
479 event = list_entry(eeh_eventlist.next, struct eeh_event, list);
480 list_del(&event->list);
481 }
482 spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
483 if (event == NULL)
484 break;
485
486 printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device "
487 "%s\n", event->reset_state,
488 pci_name(event->dev));
489 472
490 atomic_set(&eeh_fail_count, 0); 473/** Mark all devices that are peers of this device as failed.
491 notifier_call_chain (&eeh_notifier_chain, 474 * Mark the device driver too, so that it can see the failure
492 EEH_NOTIFY_FREEZE, event); 475 * immediately; this is critical, since some drivers poll
476 * status registers in interrupts ... If a driver is polling,
477 * and the slot is frozen, then the driver can deadlock in
478 * an interrupt context, which is bad.
479 */
493 480
494 __get_cpu_var(slot_resets)++; 481static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
482{
483 while (dn) {
484 if (PCI_DN(dn)) {
485 PCI_DN(dn)->eeh_mode |= mode_flag;
495 486
496 pci_dev_put(event->dev); 487 if (dn->child)
497 kfree(event); 488 __eeh_mark_slot (dn->child, mode_flag);
489 }
490 dn = dn->sibling;
498 } 491 }
499} 492}
500 493
501/** 494void eeh_mark_slot (struct device_node *dn, int mode_flag)
502 * eeh_token_to_phys - convert EEH address token to phys address
503 * @token i/o token, should be address in the form 0xE....
504 */
505static inline unsigned long eeh_token_to_phys(unsigned long token)
506{ 495{
507 pte_t *ptep; 496 dn = find_device_pe (dn);
508 unsigned long pa; 497 PCI_DN(dn)->eeh_mode |= mode_flag;
498 __eeh_mark_slot (dn->child, mode_flag);
499}
509 500
510 ptep = find_linux_pte(init_mm.pgd, token); 501static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
511 if (!ptep) 502{
512 return token; 503 while (dn) {
513 pa = pte_pfn(*ptep) << PAGE_SHIFT; 504 if (PCI_DN(dn)) {
505 PCI_DN(dn)->eeh_mode &= ~mode_flag;
506 PCI_DN(dn)->eeh_check_count = 0;
507 if (dn->child)
508 __eeh_clear_slot (dn->child, mode_flag);
509 }
510 dn = dn->sibling;
511 }
512}
514 513
515 return pa | (token & (PAGE_SIZE-1)); 514void eeh_clear_slot (struct device_node *dn, int mode_flag)
515{
516 unsigned long flags;
517 spin_lock_irqsave(&confirm_error_lock, flags);
518 dn = find_device_pe (dn);
519 PCI_DN(dn)->eeh_mode &= ~mode_flag;
520 PCI_DN(dn)->eeh_check_count = 0;
521 __eeh_clear_slot (dn->child, mode_flag);
522 spin_unlock_irqrestore(&confirm_error_lock, flags);
516} 523}
517 524
518/** 525/**
@@ -526,7 +533,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
526 * will query firmware for the EEH status. 533 * will query firmware for the EEH status.
527 * 534 *
528 * Returns 0 if there has not been an EEH error; otherwise returns 535 * Returns 0 if there has not been an EEH error; otherwise returns
529 * a non-zero value and queues up a solt isolation event notification. 536 * a non-zero value and queues up a slot isolation event notification.
530 * 537 *
531 * It is safe to call this routine in an interrupt context. 538 * It is safe to call this routine in an interrupt context.
532 */ 539 */
@@ -535,42 +542,59 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
535 int ret; 542 int ret;
536 int rets[3]; 543 int rets[3];
537 unsigned long flags; 544 unsigned long flags;
538 int rc, reset_state;
539 struct eeh_event *event;
540 struct pci_dn *pdn; 545 struct pci_dn *pdn;
546 int rc = 0;
541 547
542 __get_cpu_var(total_mmio_ffs)++; 548 __get_cpu_var(total_mmio_ffs)++;
543 549
544 if (!eeh_subsystem_enabled) 550 if (!eeh_subsystem_enabled)
545 return 0; 551 return 0;
546 552
547 if (!dn) 553 if (!dn) {
554 __get_cpu_var(no_dn)++;
548 return 0; 555 return 0;
549 pdn = dn->data; 556 }
557 pdn = PCI_DN(dn);
550 558
551 /* Access to IO BARs might get this far and still not want checking. */ 559 /* Access to IO BARs might get this far and still not want checking. */
552 if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) || 560 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
553 pdn->eeh_mode & EEH_MODE_NOCHECK) { 561 pdn->eeh_mode & EEH_MODE_NOCHECK) {
562 __get_cpu_var(ignored_check)++;
563#ifdef DEBUG
564 printk ("EEH:ignored check (%x) for %s %s\n",
565 pdn->eeh_mode, pci_name (dev), dn->full_name);
566#endif
554 return 0; 567 return 0;
555 } 568 }
556 569
557 if (!pdn->eeh_config_addr) { 570 if (!pdn->eeh_config_addr) {
571 __get_cpu_var(no_cfg_addr)++;
558 return 0; 572 return 0;
559 } 573 }
560 574
561 /* 575 /* If we already have a pending isolation event for this
562 * If we already have a pending isolation event for this 576 * slot, we know it's bad already, we don't need to check.
563 * slot, we know it's bad already, we don't need to check... 577 * Do this checking under a lock; as multiple PCI devices
578 * in one slot might report errors simultaneously, and we
579 * only want one error recovery routine running.
564 */ 580 */
581 spin_lock_irqsave(&confirm_error_lock, flags);
582 rc = 1;
565 if (pdn->eeh_mode & EEH_MODE_ISOLATED) { 583 if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
566 atomic_inc(&eeh_fail_count); 584 pdn->eeh_check_count ++;
567 if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { 585 if (pdn->eeh_check_count >= EEH_MAX_FAILS) {
586 printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n",
587 pdn->eeh_check_count);
588 dump_stack();
589
568 /* re-read the slot reset state */ 590 /* re-read the slot reset state */
569 if (read_slot_reset_state(dn, rets) != 0) 591 if (read_slot_reset_state(pdn, rets) != 0)
570 rets[0] = -1; /* reset state unknown */ 592 rets[0] = -1; /* reset state unknown */
571 eeh_panic(dev, rets[0]); 593
594 /* If we are here, then we hit an infinite loop. Stop. */
595 panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], pci_name(dev));
572 } 596 }
573 return 0; 597 goto dn_unlock;
574 } 598 }
575 599
576 /* 600 /*
@@ -580,66 +604,69 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
580 * function zero of a multi-function device. 604 * function zero of a multi-function device.
581 * In any case they must share a common PHB. 605 * In any case they must share a common PHB.
582 */ 606 */
583 ret = read_slot_reset_state(dn, rets); 607 ret = read_slot_reset_state(pdn, rets);
584 if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) { 608
609 /* If the call to firmware failed, punt */
610 if (ret != 0) {
611 printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n",
612 ret, dn->full_name);
585 __get_cpu_var(false_positives)++; 613 __get_cpu_var(false_positives)++;
586 return 0; 614 rc = 0;
615 goto dn_unlock;
587 } 616 }
588 617
589 /* prevent repeated reports of this failure */ 618 /* If EEH is not supported on this device, punt. */
590 pdn->eeh_mode |= EEH_MODE_ISOLATED; 619 if (rets[1] != 1) {
591 620 printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n",
592 reset_state = rets[0]; 621 ret, dn->full_name);
593 622 __get_cpu_var(false_positives)++;
594 spin_lock_irqsave(&slot_errbuf_lock, flags); 623 rc = 0;
595 memset(slot_errbuf, 0, eeh_error_buf_size); 624 goto dn_unlock;
596 625 }
597 rc = rtas_call(ibm_slot_error_detail,
598 8, 1, NULL, pdn->eeh_config_addr,
599 BUID_HI(pdn->phb->buid),
600 BUID_LO(pdn->phb->buid), NULL, 0,
601 virt_to_phys(slot_errbuf),
602 eeh_error_buf_size,
603 1 /* Temporary Error */);
604
605 if (rc == 0)
606 log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0);
607 spin_unlock_irqrestore(&slot_errbuf_lock, flags);
608 626
609 printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n", 627 /* If not the kind of error we know about, punt. */
610 rets[0], dn->name, dn->full_name); 628 if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) {
611 event = kmalloc(sizeof(*event), GFP_ATOMIC); 629 __get_cpu_var(false_positives)++;
612 if (event == NULL) { 630 rc = 0;
613 eeh_panic(dev, reset_state); 631 goto dn_unlock;
614 return 1; 632 }
615 }
616 633
617 event->dev = dev; 634 /* Note that config-io to empty slots may fail;
618 event->dn = dn; 635 * we recognize empty because they don't have children. */
619 event->reset_state = reset_state; 636 if ((rets[0] == 5) && (dn->child == NULL)) {
637 __get_cpu_var(false_positives)++;
638 rc = 0;
639 goto dn_unlock;
640 }
620 641
621 /* We may or may not be called in an interrupt context */ 642 __get_cpu_var(slot_resets)++;
622 spin_lock_irqsave(&eeh_eventlist_lock, flags); 643
623 list_add(&event->list, &eeh_eventlist); 644 /* Avoid repeated reports of this failure, including problems
624 spin_unlock_irqrestore(&eeh_eventlist_lock, flags); 645 * with other functions on this device, and functions under
646 * bridges. */
647 eeh_mark_slot (dn, EEH_MODE_ISOLATED);
648 spin_unlock_irqrestore(&confirm_error_lock, flags);
625 649
650 eeh_send_failure_event (dn, dev, rets[0], rets[2]);
651
626 /* Most EEH events are due to device driver bugs. Having 652 /* Most EEH events are due to device driver bugs. Having
627 * a stack trace will help the device-driver authors figure 653 * a stack trace will help the device-driver authors figure
628 * out what happened. So print that out. */ 654 * out what happened. So print that out. */
629 dump_stack(); 655 if (rets[0] != 5) dump_stack();
630 schedule_work(&eeh_event_wq); 656 return 1;
631 657
632 return 0; 658dn_unlock:
659 spin_unlock_irqrestore(&confirm_error_lock, flags);
660 return rc;
633} 661}
634 662
635EXPORT_SYMBOL(eeh_dn_check_failure); 663EXPORT_SYMBOL_GPL(eeh_dn_check_failure);
636 664
637/** 665/**
638 * eeh_check_failure - check if all 1's data is due to EEH slot freeze 666 * eeh_check_failure - check if all 1's data is due to EEH slot freeze
639 * @token i/o token, should be address in the form 0xA.... 667 * @token i/o token, should be address in the form 0xA....
640 * @val value, should be all 1's (XXX why do we need this arg??) 668 * @val value, should be all 1's (XXX why do we need this arg??)
641 * 669 *
642 * Check for an eeh failure at the given token address.
643 * Check for an EEH failure at the given token address. Call this 670 * Check for an EEH failure at the given token address. Call this
644 * routine if the result of a read was all 0xff's and you want to 671 * routine if the result of a read was all 0xff's and you want to
645 * find out if this is due to an EEH slot freeze event. This routine 672 * find out if this is due to an EEH slot freeze event. This routine
@@ -656,8 +683,10 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon
656 /* Finding the phys addr + pci device; this is pretty quick. */ 683 /* Finding the phys addr + pci device; this is pretty quick. */
657 addr = eeh_token_to_phys((unsigned long __force) token); 684 addr = eeh_token_to_phys((unsigned long __force) token);
658 dev = pci_get_device_by_addr(addr); 685 dev = pci_get_device_by_addr(addr);
659 if (!dev) 686 if (!dev) {
687 __get_cpu_var(no_device)++;
660 return val; 688 return val;
689 }
661 690
662 dn = pci_device_to_OF_node(dev); 691 dn = pci_device_to_OF_node(dev);
663 eeh_dn_check_failure (dn, dev); 692 eeh_dn_check_failure (dn, dev);
@@ -668,6 +697,217 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon
668 697
669EXPORT_SYMBOL(eeh_check_failure); 698EXPORT_SYMBOL(eeh_check_failure);
670 699
700/* ------------------------------------------------------------- */
701/* The code below deals with error recovery */
702
703/** Return negative value if a permanent error, else return
704 * a number of milliseconds to wait until the PCI slot is
705 * ready to be used.
706 */
707static int
708eeh_slot_availability(struct pci_dn *pdn)
709{
710 int rc;
711 int rets[3];
712
713 rc = read_slot_reset_state(pdn, rets);
714
715 if (rc) return rc;
716
717 if (rets[1] == 0) return -1; /* EEH is not supported */
718 if (rets[0] == 0) return 0; /* Oll Korrect */
719 if (rets[0] == 5) {
720 if (rets[2] == 0) return -1; /* permanently unavailable */
721 return rets[2]; /* number of millisecs to wait */
722 }
723 return -1;
724}
725
726/** rtas_pci_slot_reset raises/lowers the pci #RST line
727 * state: 1/0 to raise/lower the #RST
728 *
729 * Clear the EEH-frozen condition on a slot. This routine
730 * asserts the PCI #RST line if the 'state' argument is '1',
731 * and drops the #RST line if 'state is '0'. This routine is
732 * safe to call in an interrupt context.
733 *
734 */
735
736static void
737rtas_pci_slot_reset(struct pci_dn *pdn, int state)
738{
739 int rc;
740
741 BUG_ON (pdn==NULL);
742
743 if (!pdn->phb) {
744 printk (KERN_WARNING "EEH: in slot reset, device node %s has no phb\n",
745 pdn->node->full_name);
746 return;
747 }
748
749 rc = rtas_call(ibm_set_slot_reset,4,1, NULL,
750 pdn->eeh_config_addr,
751 BUID_HI(pdn->phb->buid),
752 BUID_LO(pdn->phb->buid),
753 state);
754 if (rc) {
755 printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n",
756 rc, state, pdn->node->full_name);
757 return;
758 }
759}
760
761/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
762 * dn -- device node to be reset.
763 */
764
765void
766rtas_set_slot_reset(struct pci_dn *pdn)
767{
768 int i, rc;
769
770 rtas_pci_slot_reset (pdn, 1);
771
772 /* The PCI bus requires that the reset be held high for at least
773 * a 100 milliseconds. We wait a bit longer 'just in case'. */
774
775#define PCI_BUS_RST_HOLD_TIME_MSEC 250
776 msleep (PCI_BUS_RST_HOLD_TIME_MSEC);
777
778 /* We might get hit with another EEH freeze as soon as the
779 * pci slot reset line is dropped. Make sure we don't miss
780 * these, and clear the flag now. */
781 eeh_clear_slot (pdn->node, EEH_MODE_ISOLATED);
782
783 rtas_pci_slot_reset (pdn, 0);
784
785 /* After a PCI slot has been reset, the PCI Express spec requires
786 * a 1.5 second idle time for the bus to stabilize, before starting
787 * up traffic. */
788#define PCI_BUS_SETTLE_TIME_MSEC 1800
789 msleep (PCI_BUS_SETTLE_TIME_MSEC);
790
791 /* Now double check with the firmware to make sure the device is
792 * ready to be used; if not, wait for recovery. */
793 for (i=0; i<10; i++) {
794 rc = eeh_slot_availability (pdn);
795 if (rc <= 0) break;
796
797 msleep (rc+100);
798 }
799}
800
801/* ------------------------------------------------------- */
802/** Save and restore of PCI BARs
803 *
804 * Although firmware will set up BARs during boot, it doesn't
805 * set up device BAR's after a device reset, although it will,
806 * if requested, set up bridge configuration. Thus, we need to
807 * configure the PCI devices ourselves.
808 */
809
810/**
811 * __restore_bars - Restore the Base Address Registers
812 * Loads the PCI configuration space base address registers,
813 * the expansion ROM base address, the latency timer, and etc.
814 * from the saved values in the device node.
815 */
816static inline void __restore_bars (struct pci_dn *pdn)
817{
818 int i;
819
820 if (NULL==pdn->phb) return;
821 for (i=4; i<10; i++) {
822 rtas_write_config(pdn, i*4, 4, pdn->config_space[i]);
823 }
824
825 /* 12 == Expansion ROM Address */
826 rtas_write_config(pdn, 12*4, 4, pdn->config_space[12]);
827
828#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
829#define SAVED_BYTE(OFF) (((u8 *)(pdn->config_space))[BYTE_SWAP(OFF)])
830
831 rtas_write_config (pdn, PCI_CACHE_LINE_SIZE, 1,
832 SAVED_BYTE(PCI_CACHE_LINE_SIZE));
833
834 rtas_write_config (pdn, PCI_LATENCY_TIMER, 1,
835 SAVED_BYTE(PCI_LATENCY_TIMER));
836
837 /* max latency, min grant, interrupt pin and line */
838 rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]);
839}
840
841/**
842 * eeh_restore_bars - restore the PCI config space info
843 *
844 * This routine performs a recursive walk to the children
845 * of this device as well.
846 */
847void eeh_restore_bars(struct pci_dn *pdn)
848{
849 struct device_node *dn;
850 if (!pdn)
851 return;
852
853 if (! pdn->eeh_is_bridge)
854 __restore_bars (pdn);
855
856 dn = pdn->node->child;
857 while (dn) {
858 eeh_restore_bars (PCI_DN(dn));
859 dn = dn->sibling;
860 }
861}
862
863/**
864 * eeh_save_bars - save device bars
865 *
866 * Save the values of the device bars. Unlike the restore
867 * routine, this routine is *not* recursive. This is because
868 * PCI devices are added individuallly; but, for the restore,
869 * an entire slot is reset at a time.
870 */
871static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn)
872{
873 int i;
874
875 if (!pdev || !pdn )
876 return;
877
878 for (i = 0; i < 16; i++)
879 pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]);
880
881 if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
882 pdn->eeh_is_bridge = 1;
883}
884
885void
886rtas_configure_bridge(struct pci_dn *pdn)
887{
888 int token = rtas_token ("ibm,configure-bridge");
889 int rc;
890
891 if (token == RTAS_UNKNOWN_SERVICE)
892 return;
893 rc = rtas_call(token,3,1, NULL,
894 pdn->eeh_config_addr,
895 BUID_HI(pdn->phb->buid),
896 BUID_LO(pdn->phb->buid));
897 if (rc) {
898 printk (KERN_WARNING "EEH: Unable to configure device bridge (%d) for %s\n",
899 rc, pdn->node->full_name);
900 }
901}
902
903/* ------------------------------------------------------------- */
904/* The code below deals with enabling EEH for devices during the
905 * early boot sequence. EEH must be enabled before any PCI probing
906 * can be done.
907 */
908
909#define EEH_ENABLE 1
910
671struct eeh_early_enable_info { 911struct eeh_early_enable_info {
672 unsigned int buid_hi; 912 unsigned int buid_hi;
673 unsigned int buid_lo; 913 unsigned int buid_lo;
@@ -684,9 +924,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
684 u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); 924 u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
685 u32 *regs; 925 u32 *regs;
686 int enable; 926 int enable;
687 struct pci_dn *pdn = dn->data; 927 struct pci_dn *pdn = PCI_DN(dn);
688 928
689 pdn->eeh_mode = 0; 929 pdn->eeh_mode = 0;
930 pdn->eeh_check_count = 0;
931 pdn->eeh_freeze_count = 0;
690 932
691 if (status && strcmp(status, "ok") != 0) 933 if (status && strcmp(status, "ok") != 0)
692 return NULL; /* ignore devices with bad status */ 934 return NULL; /* ignore devices with bad status */
@@ -723,8 +965,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
723 /* First register entry is addr (00BBSS00) */ 965 /* First register entry is addr (00BBSS00) */
724 /* Try to enable eeh */ 966 /* Try to enable eeh */
725 ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL, 967 ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
726 regs[0], info->buid_hi, info->buid_lo, 968 regs[0], info->buid_hi, info->buid_lo,
727 EEH_ENABLE); 969 EEH_ENABLE);
970
728 if (ret == 0) { 971 if (ret == 0) {
729 eeh_subsystem_enabled = 1; 972 eeh_subsystem_enabled = 1;
730 pdn->eeh_mode |= EEH_MODE_SUPPORTED; 973 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
@@ -736,7 +979,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
736 979
737 /* This device doesn't support EEH, but it may have an 980 /* This device doesn't support EEH, but it may have an
738 * EEH parent, in which case we mark it as supported. */ 981 * EEH parent, in which case we mark it as supported. */
739 if (dn->parent && dn->parent->data 982 if (dn->parent && PCI_DN(dn->parent)
740 && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) { 983 && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
741 /* Parent supports EEH. */ 984 /* Parent supports EEH. */
742 pdn->eeh_mode |= EEH_MODE_SUPPORTED; 985 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
@@ -749,7 +992,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
749 dn->full_name); 992 dn->full_name);
750 } 993 }
751 994
752 return NULL; 995 return NULL;
753} 996}
754 997
755/* 998/*
@@ -770,6 +1013,9 @@ void __init eeh_init(void)
770 struct device_node *phb, *np; 1013 struct device_node *phb, *np;
771 struct eeh_early_enable_info info; 1014 struct eeh_early_enable_info info;
772 1015
1016 spin_lock_init(&confirm_error_lock);
1017 spin_lock_init(&slot_errbuf_lock);
1018
773 np = of_find_node_by_path("/rtas"); 1019 np = of_find_node_by_path("/rtas");
774 if (np == NULL) 1020 if (np == NULL)
775 return; 1021 return;
@@ -797,13 +1043,11 @@ void __init eeh_init(void)
797 for (phb = of_find_node_by_name(NULL, "pci"); phb; 1043 for (phb = of_find_node_by_name(NULL, "pci"); phb;
798 phb = of_find_node_by_name(phb, "pci")) { 1044 phb = of_find_node_by_name(phb, "pci")) {
799 unsigned long buid; 1045 unsigned long buid;
800 struct pci_dn *pci;
801 1046
802 buid = get_phb_buid(phb); 1047 buid = get_phb_buid(phb);
803 if (buid == 0 || phb->data == NULL) 1048 if (buid == 0 || PCI_DN(phb) == NULL)
804 continue; 1049 continue;
805 1050
806 pci = phb->data;
807 info.buid_lo = BUID_LO(buid); 1051 info.buid_lo = BUID_LO(buid);
808 info.buid_hi = BUID_HI(buid); 1052 info.buid_hi = BUID_HI(buid);
809 traverse_pci_devices(phb, early_enable_eeh, &info); 1053 traverse_pci_devices(phb, early_enable_eeh, &info);
@@ -832,11 +1076,13 @@ void eeh_add_device_early(struct device_node *dn)
832 struct pci_controller *phb; 1076 struct pci_controller *phb;
833 struct eeh_early_enable_info info; 1077 struct eeh_early_enable_info info;
834 1078
835 if (!dn || !dn->data) 1079 if (!dn || !PCI_DN(dn))
836 return; 1080 return;
837 phb = PCI_DN(dn)->phb; 1081 phb = PCI_DN(dn)->phb;
838 if (NULL == phb || 0 == phb->buid) { 1082 if (NULL == phb || 0 == phb->buid) {
839 printk(KERN_WARNING "EEH: Expected buid but found none\n"); 1083 printk(KERN_WARNING "EEH: Expected buid but found none for %s\n",
1084 dn->full_name);
1085 dump_stack();
840 return; 1086 return;
841 } 1087 }
842 1088
@@ -844,7 +1090,7 @@ void eeh_add_device_early(struct device_node *dn)
844 info.buid_lo = BUID_LO(phb->buid); 1090 info.buid_lo = BUID_LO(phb->buid);
845 early_enable_eeh(dn, &info); 1091 early_enable_eeh(dn, &info);
846} 1092}
847EXPORT_SYMBOL(eeh_add_device_early); 1093EXPORT_SYMBOL_GPL(eeh_add_device_early);
848 1094
849/** 1095/**
850 * eeh_add_device_late - perform EEH initialization for the indicated pci device 1096 * eeh_add_device_late - perform EEH initialization for the indicated pci device
@@ -855,6 +1101,9 @@ EXPORT_SYMBOL(eeh_add_device_early);
855 */ 1101 */
856void eeh_add_device_late(struct pci_dev *dev) 1102void eeh_add_device_late(struct pci_dev *dev)
857{ 1103{
1104 struct device_node *dn;
1105 struct pci_dn *pdn;
1106
858 if (!dev || !eeh_subsystem_enabled) 1107 if (!dev || !eeh_subsystem_enabled)
859 return; 1108 return;
860 1109
@@ -862,9 +1111,15 @@ void eeh_add_device_late(struct pci_dev *dev)
862 printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev)); 1111 printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
863#endif 1112#endif
864 1113
1114 pci_dev_get (dev);
1115 dn = pci_device_to_OF_node(dev);
1116 pdn = PCI_DN(dn);
1117 pdn->pcidev = dev;
1118
865 pci_addr_cache_insert_device (dev); 1119 pci_addr_cache_insert_device (dev);
1120 eeh_save_bars(dev, pdn);
866} 1121}
867EXPORT_SYMBOL(eeh_add_device_late); 1122EXPORT_SYMBOL_GPL(eeh_add_device_late);
868 1123
869/** 1124/**
870 * eeh_remove_device - undo EEH setup for the indicated pci device 1125 * eeh_remove_device - undo EEH setup for the indicated pci device
@@ -875,6 +1130,7 @@ EXPORT_SYMBOL(eeh_add_device_late);
875 */ 1130 */
876void eeh_remove_device(struct pci_dev *dev) 1131void eeh_remove_device(struct pci_dev *dev)
877{ 1132{
1133 struct device_node *dn;
878 if (!dev || !eeh_subsystem_enabled) 1134 if (!dev || !eeh_subsystem_enabled)
879 return; 1135 return;
880 1136
@@ -883,20 +1139,29 @@ void eeh_remove_device(struct pci_dev *dev)
883 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); 1139 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
884#endif 1140#endif
885 pci_addr_cache_remove_device(dev); 1141 pci_addr_cache_remove_device(dev);
1142
1143 dn = pci_device_to_OF_node(dev);
1144 PCI_DN(dn)->pcidev = NULL;
1145 pci_dev_put (dev);
886} 1146}
887EXPORT_SYMBOL(eeh_remove_device); 1147EXPORT_SYMBOL_GPL(eeh_remove_device);
888 1148
889static int proc_eeh_show(struct seq_file *m, void *v) 1149static int proc_eeh_show(struct seq_file *m, void *v)
890{ 1150{
891 unsigned int cpu; 1151 unsigned int cpu;
892 unsigned long ffs = 0, positives = 0, failures = 0; 1152 unsigned long ffs = 0, positives = 0, failures = 0;
893 unsigned long resets = 0; 1153 unsigned long resets = 0;
1154 unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0;
894 1155
895 for_each_cpu(cpu) { 1156 for_each_cpu(cpu) {
896 ffs += per_cpu(total_mmio_ffs, cpu); 1157 ffs += per_cpu(total_mmio_ffs, cpu);
897 positives += per_cpu(false_positives, cpu); 1158 positives += per_cpu(false_positives, cpu);
898 failures += per_cpu(ignored_failures, cpu); 1159 failures += per_cpu(ignored_failures, cpu);
899 resets += per_cpu(slot_resets, cpu); 1160 resets += per_cpu(slot_resets, cpu);
1161 no_dev += per_cpu(no_device, cpu);
1162 no_dn += per_cpu(no_dn, cpu);
1163 no_cfg += per_cpu(no_cfg_addr, cpu);
1164 no_check += per_cpu(ignored_check, cpu);
900 } 1165 }
901 1166
902 if (0 == eeh_subsystem_enabled) { 1167 if (0 == eeh_subsystem_enabled) {
@@ -904,13 +1169,17 @@ static int proc_eeh_show(struct seq_file *m, void *v)
904 seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs); 1169 seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs);
905 } else { 1170 } else {
906 seq_printf(m, "EEH Subsystem is enabled\n"); 1171 seq_printf(m, "EEH Subsystem is enabled\n");
907 seq_printf(m, "eeh_total_mmio_ffs=%ld\n" 1172 seq_printf(m,
908 "eeh_false_positives=%ld\n" 1173 "no device=%ld\n"
909 "eeh_ignored_failures=%ld\n" 1174 "no device node=%ld\n"
910 "eeh_slot_resets=%ld\n" 1175 "no config address=%ld\n"
911 "eeh_fail_count=%d\n", 1176 "check not wanted=%ld\n"
912 ffs, positives, failures, resets, 1177 "eeh_total_mmio_ffs=%ld\n"
913 eeh_fail_count.counter); 1178 "eeh_false_positives=%ld\n"
1179 "eeh_ignored_failures=%ld\n"
1180 "eeh_slot_resets=%ld\n",
1181 no_dev, no_dn, no_cfg, no_check,
1182 ffs, positives, failures, resets);
914 } 1183 }
915 1184
916 return 0; 1185 return 0;
@@ -932,7 +1201,7 @@ static int __init eeh_init_proc(void)
932{ 1201{
933 struct proc_dir_entry *e; 1202 struct proc_dir_entry *e;
934 1203
935 if (systemcfg->platform & PLATFORM_PSERIES) { 1204 if (platform_is_pseries()) {
936 e = create_proc_entry("ppc64/eeh", 0, NULL); 1205 e = create_proc_entry("ppc64/eeh", 0, NULL);
937 if (e) 1206 if (e)
938 e->proc_fops = &proc_eeh_operations; 1207 e->proc_fops = &proc_eeh_operations;
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
new file mode 100644
index 000000000000..92497333c2b6
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -0,0 +1,155 @@
1/*
2 * eeh_event.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
19 */
20
21#include <linux/list.h>
22#include <linux/pci.h>
23#include <asm/eeh_event.h>
24
25/** Overview:
26 * EEH error states may be detected within exception handlers;
27 * however, the recovery processing needs to occur asynchronously
28 * in a normal kernel context and not an interrupt context.
29 * This pair of routines creates an event and queues it onto a
30 * work-queue, where a worker thread can drive recovery.
31 */
32
33/* EEH event workqueue setup. */
34static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED;
35LIST_HEAD(eeh_eventlist);
36static void eeh_thread_launcher(void *);
37DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);
38
39/**
40 * eeh_panic - call panic() for an eeh event that cannot be handled.
41 * The philosophy of this routine is that it is better to panic and
42 * halt the OS than it is to risk possible data corruption by
43 * oblivious device drivers that don't know better.
44 *
45 * @dev pci device that had an eeh event
46 * @reset_state current reset state of the device slot
47 */
48static void eeh_panic(struct pci_dev *dev, int reset_state)
49{
50 /*
51 * Since the panic_on_oops sysctl is used to halt the system
52 * in light of potential corruption, we can use it here.
53 */
54 if (panic_on_oops) {
55 panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
56 pci_name(dev));
57 }
58 else {
59 printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
60 reset_state, pci_name(dev));
61 }
62}
63
64/**
65 * eeh_event_handler - dispatch EEH events. The detection of a frozen
66 * slot can occur inside an interrupt, where it can be hard to do
67 * anything about it. The goal of this routine is to pull these
68 * detection events out of the context of the interrupt handler, and
69 * re-dispatch them for processing at a later time in a normal context.
70 *
71 * @dummy - unused
72 */
73static int eeh_event_handler(void * dummy)
74{
75 unsigned long flags;
76 struct eeh_event *event;
77
78 daemonize ("eehd");
79
80 while (1) {
81 set_current_state(TASK_INTERRUPTIBLE);
82
83 spin_lock_irqsave(&eeh_eventlist_lock, flags);
84 event = NULL;
85 if (!list_empty(&eeh_eventlist)) {
86 event = list_entry(eeh_eventlist.next, struct eeh_event, list);
87 list_del(&event->list);
88 }
89 spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
90 if (event == NULL)
91 break;
92
93 printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
94 pci_name(event->dev));
95
96 eeh_panic (event->dev, event->state);
97
98 kfree(event);
99 }
100
101 return 0;
102}
103
104/**
105 * eeh_thread_launcher
106 *
107 * @dummy - unused
108 */
109static void eeh_thread_launcher(void *dummy)
110{
111 if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0)
112 printk(KERN_ERR "Failed to start EEH daemon\n");
113}
114
115/**
116 * eeh_send_failure_event - generate a PCI error event
117 * @dev pci device
118 *
119 * This routine can be called within an interrupt context;
120 * the actual event will be delivered in a normal context
121 * (from a workqueue).
122 */
123int eeh_send_failure_event (struct device_node *dn,
124 struct pci_dev *dev,
125 int state,
126 int time_unavail)
127{
128 unsigned long flags;
129 struct eeh_event *event;
130
131 event = kmalloc(sizeof(*event), GFP_ATOMIC);
132 if (event == NULL) {
133 printk (KERN_ERR "EEH: out of memory, event not handled\n");
134 return 1;
135 }
136
137 if (dev)
138 pci_dev_get(dev);
139
140 event->dn = dn;
141 event->dev = dev;
142 event->state = state;
143 event->time_unavail = time_unavail;
144
145 /* We may or may not be called in an interrupt context */
146 spin_lock_irqsave(&eeh_eventlist_lock, flags);
147 list_add(&event->list, &eeh_eventlist);
148 spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
149
150 schedule_work(&eeh_event_wq);
151
152 return 0;
153}
154
155/********************** END OF FILE ******************************/
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index fcc50bfd43fd..97ba5214417f 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -42,7 +42,6 @@
42#include <asm/machdep.h> 42#include <asm/machdep.h>
43#include <asm/abs_addr.h> 43#include <asm/abs_addr.h>
44#include <asm/pSeries_reconfig.h> 44#include <asm/pSeries_reconfig.h>
45#include <asm/systemcfg.h>
46#include <asm/firmware.h> 45#include <asm/firmware.h>
47#include <asm/tce.h> 46#include <asm/tce.h>
48#include <asm/ppc-pci.h> 47#include <asm/ppc-pci.h>
@@ -582,7 +581,7 @@ void iommu_init_early_pSeries(void)
582 return; 581 return;
583 } 582 }
584 583
585 if (systemcfg->platform & PLATFORM_LPAR) { 584 if (platform_is_lpar()) {
586 if (firmware_has_feature(FW_FEATURE_MULTITCE)) { 585 if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
587 ppc_md.tce_build = tce_buildmulti_pSeriesLP; 586 ppc_md.tce_build = tce_buildmulti_pSeriesLP;
588 ppc_md.tce_free = tce_freemulti_pSeriesLP; 587 ppc_md.tce_free = tce_freemulti_pSeriesLP;
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index c198656a3bb5..999a9620b5ce 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -107,7 +107,6 @@ static void __init pSeries_request_regions(void)
107 107
108void __init pSeries_final_fixup(void) 108void __init pSeries_final_fixup(void)
109{ 109{
110 phbs_remap_io();
111 pSeries_request_regions(); 110 pSeries_request_regions();
112 111
113 pci_addr_cache_build(); 112 pci_addr_cache_build();
@@ -123,7 +122,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
123 int i; 122 int i;
124 unsigned int reg; 123 unsigned int reg;
125 124
126 if (!(systemcfg->platform & PLATFORM_PSERIES)) 125 if (!platform_is_pseries())
127 return; 126 return;
128 127
129 printk("Using INTC for W82c105 IDE controller.\n"); 128 printk("Using INTC for W82c105 IDE controller.\n");
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index d7d400339458..d8864164dbe8 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -408,7 +408,7 @@ static int proc_ppc64_create_ofdt(void)
408{ 408{
409 struct proc_dir_entry *ent; 409 struct proc_dir_entry *ent;
410 410
411 if (!(systemcfg->platform & PLATFORM_PSERIES)) 411 if (!platform_is_pseries())
412 return 0; 412 return 0;
413 413
414 ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); 414 ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index e26b0420b6dd..a6f628d4c9dc 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -27,7 +27,6 @@
27#include <asm/prom.h> 27#include <asm/prom.h>
28#include <asm/nvram.h> 28#include <asm/nvram.h>
29#include <asm/atomic.h> 29#include <asm/atomic.h>
30#include <asm/systemcfg.h>
31 30
32#if 0 31#if 0
33#define DEBUG(A...) printk(KERN_ERR A) 32#define DEBUG(A...) printk(KERN_ERR A)
@@ -482,10 +481,12 @@ static int __init rtas_init(void)
482{ 481{
483 struct proc_dir_entry *entry; 482 struct proc_dir_entry *entry;
484 483
485 /* No RTAS, only warn if we are on a pSeries box */ 484 if (!platform_is_pseries())
485 return 0;
486
487 /* No RTAS */
486 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { 488 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
487 if (systemcfg->platform & PLATFORM_PSERIES) 489 printk(KERN_INFO "rtasd: no event-scan on system\n");
488 printk(KERN_INFO "rtasd: no event-scan on system\n");
489 return 1; 490 return 1;
490 } 491 }
491 492
diff --git a/arch/ppc64/kernel/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 2edc947f7c44..2edc947f7c44 100644
--- a/arch/ppc64/kernel/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index e78c39368841..31990829310c 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -249,7 +249,7 @@ static void __init pSeries_setup_arch(void)
249 ppc_md.idle_loop = default_idle; 249 ppc_md.idle_loop = default_idle;
250 } 250 }
251 251
252 if (systemcfg->platform & PLATFORM_LPAR) 252 if (platform_is_lpar())
253 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; 253 ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
254 else 254 else
255 ppc_md.enable_pmcs = power4_enable_pmcs; 255 ppc_md.enable_pmcs = power4_enable_pmcs;
@@ -306,9 +306,7 @@ static void __init fw_feature_init(void)
306 } 306 }
307 307
308 of_node_put(dn); 308 of_node_put(dn);
309 no_rtas: 309no_rtas:
310 printk(KERN_INFO "firmware_features = 0x%lx\n",
311 ppc64_firmware_features);
312 310
313 DBG(" <- fw_feature_init()\n"); 311 DBG(" <- fw_feature_init()\n");
314} 312}
@@ -378,7 +376,7 @@ static void __init pSeries_init_early(void)
378 376
379 fw_feature_init(); 377 fw_feature_init();
380 378
381 if (systemcfg->platform & PLATFORM_LPAR) 379 if (platform_is_lpar())
382 hpte_init_lpar(); 380 hpte_init_lpar();
383 else { 381 else {
384 hpte_init_native(); 382 hpte_init_native();
@@ -388,7 +386,7 @@ static void __init pSeries_init_early(void)
388 386
389 generic_find_legacy_serial_ports(&physport, &default_speed); 387 generic_find_legacy_serial_ports(&physport, &default_speed);
390 388
391 if (systemcfg->platform & PLATFORM_LPAR) 389 if (platform_is_lpar())
392 find_udbg_vterm(); 390 find_udbg_vterm();
393 else if (physport) { 391 else if (physport) {
394 /* Map the uart for udbg. */ 392 /* Map the uart for udbg. */
@@ -469,6 +467,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
469 * more. 467 * more.
470 */ 468 */
471 clear_thread_flag(TIF_POLLING_NRFLAG); 469 clear_thread_flag(TIF_POLLING_NRFLAG);
470 smp_mb__after_clear_bit();
472 471
473 /* 472 /*
474 * SMT dynamic mode. Cede will result in this thread going 473 * SMT dynamic mode. Cede will result in this thread going
@@ -481,6 +480,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
481 cede_processor(); 480 cede_processor();
482 else 481 else
483 local_irq_enable(); 482 local_irq_enable();
483 set_thread_flag(TIF_POLLING_NRFLAG);
484 } else { 484 } else {
485 /* 485 /*
486 * Give the HV an opportunity at the processor, since we are 486 * Give the HV an opportunity at the processor, since we are
@@ -492,11 +492,11 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
492 492
493static void pseries_dedicated_idle(void) 493static void pseries_dedicated_idle(void)
494{ 494{
495 long oldval;
496 struct paca_struct *lpaca = get_paca(); 495 struct paca_struct *lpaca = get_paca();
497 unsigned int cpu = smp_processor_id(); 496 unsigned int cpu = smp_processor_id();
498 unsigned long start_snooze; 497 unsigned long start_snooze;
499 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); 498 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
499 set_thread_flag(TIF_POLLING_NRFLAG);
500 500
501 while (1) { 501 while (1) {
502 /* 502 /*
@@ -505,10 +505,7 @@ static void pseries_dedicated_idle(void)
505 */ 505 */
506 lpaca->lppaca.idle = 1; 506 lpaca->lppaca.idle = 1;
507 507
508 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 508 if (!need_resched()) {
509 if (!oldval) {
510 set_thread_flag(TIF_POLLING_NRFLAG);
511
512 start_snooze = __get_tb() + 509 start_snooze = __get_tb() +
513 *smt_snooze_delay * tb_ticks_per_usec; 510 *smt_snooze_delay * tb_ticks_per_usec;
514 511
@@ -531,15 +528,14 @@ static void pseries_dedicated_idle(void)
531 } 528 }
532 529
533 HMT_medium(); 530 HMT_medium();
534 clear_thread_flag(TIF_POLLING_NRFLAG);
535 } else {
536 set_need_resched();
537 } 531 }
538 532
539 lpaca->lppaca.idle = 0; 533 lpaca->lppaca.idle = 0;
540 ppc64_runlatch_on(); 534 ppc64_runlatch_on();
541 535
536 preempt_enable_no_resched();
542 schedule(); 537 schedule();
538 preempt_disable();
543 539
544 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 540 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
545 cpu_die(); 541 cpu_die();
@@ -583,7 +579,9 @@ static void pseries_shared_idle(void)
583 lpaca->lppaca.idle = 0; 579 lpaca->lppaca.idle = 0;
584 ppc64_runlatch_on(); 580 ppc64_runlatch_on();
585 581
582 preempt_enable_no_resched();
586 schedule(); 583 schedule();
584 preempt_disable();
587 585
588 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 586 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
589 cpu_die(); 587 cpu_die();
@@ -592,7 +590,7 @@ static void pseries_shared_idle(void)
592 590
593static int pSeries_pci_probe_mode(struct pci_bus *bus) 591static int pSeries_pci_probe_mode(struct pci_bus *bus)
594{ 592{
595 if (systemcfg->platform & PLATFORM_LPAR) 593 if (platform_is_lpar())
596 return PCI_PROBE_DEVTREE; 594 return PCI_PROBE_DEVTREE;
597 return PCI_PROBE_NORMAL; 595 return PCI_PROBE_NORMAL;
598} 596}
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 7a243e8ccd7e..5800cde7d5ad 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -46,6 +46,7 @@
46#include <asm/rtas.h> 46#include <asm/rtas.h>
47#include <asm/pSeries_reconfig.h> 47#include <asm/pSeries_reconfig.h>
48#include <asm/mpic.h> 48#include <asm/mpic.h>
49#include <asm/vdso_datapage.h>
49 50
50#include "plpar_wrappers.h" 51#include "plpar_wrappers.h"
51 52
@@ -96,7 +97,7 @@ int pSeries_cpu_disable(void)
96 int cpu = smp_processor_id(); 97 int cpu = smp_processor_id();
97 98
98 cpu_clear(cpu, cpu_online_map); 99 cpu_clear(cpu, cpu_online_map);
99 systemcfg->processorCount--; 100 vdso_data->processorCount--;
100 101
101 /*fix boot_cpuid here*/ 102 /*fix boot_cpuid here*/
102 if (cpu == boot_cpuid) 103 if (cpu == boot_cpuid)
@@ -441,7 +442,7 @@ void __init smp_init_pSeries(void)
441 smp_ops->cpu_die = pSeries_cpu_die; 442 smp_ops->cpu_die = pSeries_cpu_die;
442 443
443 /* Processors can be added/removed only on LPAR */ 444 /* Processors can be added/removed only on LPAR */
444 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) 445 if (platform_is_lpar())
445 pSeries_reconfig_notifier_register(&pSeries_smp_nb); 446 pSeries_reconfig_notifier_register(&pSeries_smp_nb);
446#endif 447#endif
447 448
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index c72c86f05cb6..72ac18067ece 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -545,7 +545,9 @@ nextnode:
545 of_node_put(np); 545 of_node_put(np);
546 } 546 }
547 547
548 if (systemcfg->platform == PLATFORM_PSERIES) { 548 if (platform_is_lpar())
549 ops = &pSeriesLP_ops;
550 else {
549#ifdef CONFIG_SMP 551#ifdef CONFIG_SMP
550 for_each_cpu(i) { 552 for_each_cpu(i) {
551 int hard_id; 553 int hard_id;
@@ -561,12 +563,11 @@ nextnode:
561#else 563#else
562 xics_per_cpu[0] = ioremap(intr_base, intr_size); 564 xics_per_cpu[0] = ioremap(intr_base, intr_size);
563#endif /* CONFIG_SMP */ 565#endif /* CONFIG_SMP */
564 } else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
565 ops = &pSeriesLP_ops;
566 } 566 }
567 567
568 xics_8259_pic.enable = i8259_pic.enable; 568 xics_8259_pic.enable = i8259_pic.enable;
569 xics_8259_pic.disable = i8259_pic.disable; 569 xics_8259_pic.disable = i8259_pic.disable;
570 xics_8259_pic.end = i8259_pic.end;
570 for (i = 0; i < 16; ++i) 571 for (i = 0; i < 16; ++i)
571 get_irq_desc(i)->handler = &xics_8259_pic; 572 get_irq_desc(i)->handler = &xics_8259_pic;
572 for (; i < NR_IRQS; ++i) 573 for (; i < NR_IRQS; ++i)
diff --git a/arch/powerpc/sysdev/u3_iommu.c b/arch/powerpc/sysdev/u3_iommu.c
index 543d65909812..f32baf7f4693 100644
--- a/arch/powerpc/sysdev/u3_iommu.c
+++ b/arch/powerpc/sysdev/u3_iommu.c
@@ -226,7 +226,7 @@ static void iommu_table_u3_setup(void)
226 iommu_table_u3.it_busno = 0; 226 iommu_table_u3.it_busno = 0;
227 iommu_table_u3.it_offset = 0; 227 iommu_table_u3.it_offset = 0;
228 /* it_size is in number of entries */ 228 /* it_size is in number of entries */
229 iommu_table_u3.it_size = dart_tablesize / sizeof(u32); 229 iommu_table_u3.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR;
230 230
231 /* Initialize the common IOMMU code */ 231 /* Initialize the common IOMMU code */
232 iommu_table_u3.it_base = (unsigned long)dart_vbase; 232 iommu_table_u3.it_base = (unsigned long)dart_vbase;
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index 79a784f0e7a9..b20312e5ed27 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -8,4 +8,4 @@ obj-$(CONFIG_8xx) += start_8xx.o
8obj-$(CONFIG_6xx) += start_32.o 8obj-$(CONFIG_6xx) += start_32.o
9obj-$(CONFIG_4xx) += start_32.o 9obj-$(CONFIG_4xx) += start_32.o
10obj-$(CONFIG_PPC64) += start_64.o 10obj-$(CONFIG_PPC64) += start_64.o
11obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o 11obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c
new file mode 100644
index 000000000000..78765833f4c0
--- /dev/null
+++ b/arch/powerpc/xmon/nonstdio.c
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 1996-2005 Paul Mackerras.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <linux/string.h>
10#include <asm/time.h>
11#include "nonstdio.h"
12
13int xmon_putchar(int c)
14{
15 char ch = c;
16
17 if (c == '\n')
18 xmon_putchar('\r');
19 return xmon_write(&ch, 1) == 1? c: -1;
20}
21
22static char line[256];
23static char *lineptr;
24static int lineleft;
25
26int xmon_expect(const char *str, unsigned long timeout)
27{
28 int c;
29 unsigned long t0;
30
31 /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
32 timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
33 t0 = get_tbl();
34 do {
35 lineptr = line;
36 for (;;) {
37 c = xmon_read_poll();
38 if (c == -1) {
39 if (get_tbl() - t0 > timeout)
40 return 0;
41 continue;
42 }
43 if (c == '\n')
44 break;
45 if (c != '\r' && lineptr < &line[sizeof(line) - 1])
46 *lineptr++ = c;
47 }
48 *lineptr = 0;
49 } while (strstr(line, str) == NULL);
50 return 1;
51}
52
53int xmon_getchar(void)
54{
55 int c;
56
57 if (lineleft == 0) {
58 lineptr = line;
59 for (;;) {
60 c = xmon_readchar();
61 if (c == -1 || c == 4)
62 break;
63 if (c == '\r' || c == '\n') {
64 *lineptr++ = '\n';
65 xmon_putchar('\n');
66 break;
67 }
68 switch (c) {
69 case 0177:
70 case '\b':
71 if (lineptr > line) {
72 xmon_putchar('\b');
73 xmon_putchar(' ');
74 xmon_putchar('\b');
75 --lineptr;
76 }
77 break;
78 case 'U' & 0x1F:
79 while (lineptr > line) {
80 xmon_putchar('\b');
81 xmon_putchar(' ');
82 xmon_putchar('\b');
83 --lineptr;
84 }
85 break;
86 default:
87 if (lineptr >= &line[sizeof(line) - 1])
88 xmon_putchar('\a');
89 else {
90 xmon_putchar(c);
91 *lineptr++ = c;
92 }
93 }
94 }
95 lineleft = lineptr - line;
96 lineptr = line;
97 }
98 if (lineleft == 0)
99 return -1;
100 --lineleft;
101 return *lineptr++;
102}
103
104char *xmon_gets(char *str, int nb)
105{
106 char *p;
107 int c;
108
109 for (p = str; p < str + nb - 1; ) {
110 c = xmon_getchar();
111 if (c == -1) {
112 if (p == str)
113 return NULL;
114 break;
115 }
116 *p++ = c;
117 if (c == '\n')
118 break;
119 }
120 *p = 0;
121 return str;
122}
123
124void xmon_printf(const char *format, ...)
125{
126 va_list args;
127 int n;
128 static char xmon_outbuf[1024];
129
130 va_start(args, format);
131 n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
132 va_end(args);
133 xmon_write(xmon_outbuf, n);
134}
diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h
index 84211a21c6f4..47cebbd2b1b1 100644
--- a/arch/powerpc/xmon/nonstdio.h
+++ b/arch/powerpc/xmon/nonstdio.h
@@ -1,22 +1,14 @@
1typedef int FILE;
2extern FILE *xmon_stdin, *xmon_stdout;
3#define EOF (-1) 1#define EOF (-1)
4#define stdin xmon_stdin 2
5#define stdout xmon_stdout
6#define printf xmon_printf 3#define printf xmon_printf
7#define fprintf xmon_fprintf
8#define fputs xmon_fputs
9#define fgets xmon_fgets
10#define putchar xmon_putchar 4#define putchar xmon_putchar
11#define getchar xmon_getchar
12#define putc xmon_putc
13#define getc xmon_getc
14#define fopen(n, m) NULL
15#define fflush(f) do {} while (0)
16#define fclose(f) do {} while (0)
17extern char *fgets(char *, int, void *);
18extern void xmon_printf(const char *, ...);
19extern void xmon_fprintf(void *, const char *, ...);
20extern void xmon_sprintf(char *, const char *, ...);
21 5
22#define perror(s) printf("%s: no files!\n", (s)) 6extern int xmon_putchar(int c);
7extern int xmon_getchar(void);
8extern char *xmon_gets(char *, int);
9extern void xmon_printf(const char *, ...);
10extern void xmon_map_scc(void);
11extern int xmon_expect(const char *str, unsigned long timeout);
12extern int xmon_write(void *ptr, int nb);
13extern int xmon_readchar(void);
14extern int xmon_read_poll(void);
diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S
index f8e40dfd2bff..96a91f10e2ec 100644
--- a/arch/powerpc/xmon/setjmp.S
+++ b/arch/powerpc/xmon/setjmp.S
@@ -14,61 +14,61 @@
14 14
15_GLOBAL(xmon_setjmp) 15_GLOBAL(xmon_setjmp)
16 mflr r0 16 mflr r0
17 STL r0,0(r3) 17 PPC_STL r0,0(r3)
18 STL r1,SZL(r3) 18 PPC_STL r1,SZL(r3)
19 STL r2,2*SZL(r3) 19 PPC_STL r2,2*SZL(r3)
20 mfcr r0 20 mfcr r0
21 STL r0,3*SZL(r3) 21 PPC_STL r0,3*SZL(r3)
22 STL r13,4*SZL(r3) 22 PPC_STL r13,4*SZL(r3)
23 STL r14,5*SZL(r3) 23 PPC_STL r14,5*SZL(r3)
24 STL r15,6*SZL(r3) 24 PPC_STL r15,6*SZL(r3)
25 STL r16,7*SZL(r3) 25 PPC_STL r16,7*SZL(r3)
26 STL r17,8*SZL(r3) 26 PPC_STL r17,8*SZL(r3)
27 STL r18,9*SZL(r3) 27 PPC_STL r18,9*SZL(r3)
28 STL r19,10*SZL(r3) 28 PPC_STL r19,10*SZL(r3)
29 STL r20,11*SZL(r3) 29 PPC_STL r20,11*SZL(r3)
30 STL r21,12*SZL(r3) 30 PPC_STL r21,12*SZL(r3)
31 STL r22,13*SZL(r3) 31 PPC_STL r22,13*SZL(r3)
32 STL r23,14*SZL(r3) 32 PPC_STL r23,14*SZL(r3)
33 STL r24,15*SZL(r3) 33 PPC_STL r24,15*SZL(r3)
34 STL r25,16*SZL(r3) 34 PPC_STL r25,16*SZL(r3)
35 STL r26,17*SZL(r3) 35 PPC_STL r26,17*SZL(r3)
36 STL r27,18*SZL(r3) 36 PPC_STL r27,18*SZL(r3)
37 STL r28,19*SZL(r3) 37 PPC_STL r28,19*SZL(r3)
38 STL r29,20*SZL(r3) 38 PPC_STL r29,20*SZL(r3)
39 STL r30,21*SZL(r3) 39 PPC_STL r30,21*SZL(r3)
40 STL r31,22*SZL(r3) 40 PPC_STL r31,22*SZL(r3)
41 li r3,0 41 li r3,0
42 blr 42 blr
43 43
44_GLOBAL(xmon_longjmp) 44_GLOBAL(xmon_longjmp)
45 CMPI r4,0 45 PPC_LCMPI r4,0
46 bne 1f 46 bne 1f
47 li r4,1 47 li r4,1
481: LDL r13,4*SZL(r3) 481: PPC_LL r13,4*SZL(r3)
49 LDL r14,5*SZL(r3) 49 PPC_LL r14,5*SZL(r3)
50 LDL r15,6*SZL(r3) 50 PPC_LL r15,6*SZL(r3)
51 LDL r16,7*SZL(r3) 51 PPC_LL r16,7*SZL(r3)
52 LDL r17,8*SZL(r3) 52 PPC_LL r17,8*SZL(r3)
53 LDL r18,9*SZL(r3) 53 PPC_LL r18,9*SZL(r3)
54 LDL r19,10*SZL(r3) 54 PPC_LL r19,10*SZL(r3)
55 LDL r20,11*SZL(r3) 55 PPC_LL r20,11*SZL(r3)
56 LDL r21,12*SZL(r3) 56 PPC_LL r21,12*SZL(r3)
57 LDL r22,13*SZL(r3) 57 PPC_LL r22,13*SZL(r3)
58 LDL r23,14*SZL(r3) 58 PPC_LL r23,14*SZL(r3)
59 LDL r24,15*SZL(r3) 59 PPC_LL r24,15*SZL(r3)
60 LDL r25,16*SZL(r3) 60 PPC_LL r25,16*SZL(r3)
61 LDL r26,17*SZL(r3) 61 PPC_LL r26,17*SZL(r3)
62 LDL r27,18*SZL(r3) 62 PPC_LL r27,18*SZL(r3)
63 LDL r28,19*SZL(r3) 63 PPC_LL r28,19*SZL(r3)
64 LDL r29,20*SZL(r3) 64 PPC_LL r29,20*SZL(r3)
65 LDL r30,21*SZL(r3) 65 PPC_LL r30,21*SZL(r3)
66 LDL r31,22*SZL(r3) 66 PPC_LL r31,22*SZL(r3)
67 LDL r0,3*SZL(r3) 67 PPC_LL r0,3*SZL(r3)
68 mtcrf 0x38,r0 68 mtcrf 0x38,r0
69 LDL r0,0(r3) 69 PPC_LL r0,0(r3)
70 LDL r1,SZL(r3) 70 PPC_LL r1,SZL(r3)
71 LDL r2,2*SZL(r3) 71 PPC_LL r2,2*SZL(r3)
72 mtlr r0 72 mtlr r0
73 mr r3,r4 73 mr r3,r4
74 blr 74 blr
@@ -84,52 +84,52 @@ _GLOBAL(xmon_longjmp)
84 * different ABIs, though). 84 * different ABIs, though).
85 */ 85 */
86_GLOBAL(xmon_save_regs) 86_GLOBAL(xmon_save_regs)
87 STL r0,0*SZL(r3) 87 PPC_STL r0,0*SZL(r3)
88 STL r2,2*SZL(r3) 88 PPC_STL r2,2*SZL(r3)
89 STL r3,3*SZL(r3) 89 PPC_STL r3,3*SZL(r3)
90 STL r4,4*SZL(r3) 90 PPC_STL r4,4*SZL(r3)
91 STL r5,5*SZL(r3) 91 PPC_STL r5,5*SZL(r3)
92 STL r6,6*SZL(r3) 92 PPC_STL r6,6*SZL(r3)
93 STL r7,7*SZL(r3) 93 PPC_STL r7,7*SZL(r3)
94 STL r8,8*SZL(r3) 94 PPC_STL r8,8*SZL(r3)
95 STL r9,9*SZL(r3) 95 PPC_STL r9,9*SZL(r3)
96 STL r10,10*SZL(r3) 96 PPC_STL r10,10*SZL(r3)
97 STL r11,11*SZL(r3) 97 PPC_STL r11,11*SZL(r3)
98 STL r12,12*SZL(r3) 98 PPC_STL r12,12*SZL(r3)
99 STL r13,13*SZL(r3) 99 PPC_STL r13,13*SZL(r3)
100 STL r14,14*SZL(r3) 100 PPC_STL r14,14*SZL(r3)
101 STL r15,15*SZL(r3) 101 PPC_STL r15,15*SZL(r3)
102 STL r16,16*SZL(r3) 102 PPC_STL r16,16*SZL(r3)
103 STL r17,17*SZL(r3) 103 PPC_STL r17,17*SZL(r3)
104 STL r18,18*SZL(r3) 104 PPC_STL r18,18*SZL(r3)
105 STL r19,19*SZL(r3) 105 PPC_STL r19,19*SZL(r3)
106 STL r20,20*SZL(r3) 106 PPC_STL r20,20*SZL(r3)
107 STL r21,21*SZL(r3) 107 PPC_STL r21,21*SZL(r3)
108 STL r22,22*SZL(r3) 108 PPC_STL r22,22*SZL(r3)
109 STL r23,23*SZL(r3) 109 PPC_STL r23,23*SZL(r3)
110 STL r24,24*SZL(r3) 110 PPC_STL r24,24*SZL(r3)
111 STL r25,25*SZL(r3) 111 PPC_STL r25,25*SZL(r3)
112 STL r26,26*SZL(r3) 112 PPC_STL r26,26*SZL(r3)
113 STL r27,27*SZL(r3) 113 PPC_STL r27,27*SZL(r3)
114 STL r28,28*SZL(r3) 114 PPC_STL r28,28*SZL(r3)
115 STL r29,29*SZL(r3) 115 PPC_STL r29,29*SZL(r3)
116 STL r30,30*SZL(r3) 116 PPC_STL r30,30*SZL(r3)
117 STL r31,31*SZL(r3) 117 PPC_STL r31,31*SZL(r3)
118 /* go up one stack frame for SP */ 118 /* go up one stack frame for SP */
119 LDL r4,0(r1) 119 PPC_LL r4,0(r1)
120 STL r4,1*SZL(r3) 120 PPC_STL r4,1*SZL(r3)
121 /* get caller's LR */ 121 /* get caller's LR */
122 LDL r0,LRSAVE(r4) 122 PPC_LL r0,LRSAVE(r4)
123 STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) 123 PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3)
124 STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) 124 PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3)
125 mfmsr r0 125 mfmsr r0
126 STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) 126 PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3)
127 mfctr r0 127 mfctr r0
128 STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) 128 PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3)
129 mfxer r0 129 mfxer r0
130 STL r0,_XER-STACK_FRAME_OVERHEAD(r3) 130 PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3)
131 mfcr r0 131 mfcr r0
132 STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) 132 PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3)
133 li r0,0 133 li r0,0
134 STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) 134 PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
135 blr 135 blr
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
index 69b658c0f760..c2464df4217e 100644
--- a/arch/powerpc/xmon/start_32.c
+++ b/arch/powerpc/xmon/start_32.c
@@ -11,7 +11,6 @@
11#include <linux/cuda.h> 11#include <linux/cuda.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/sysrq.h>
15#include <linux/bitops.h> 14#include <linux/bitops.h>
16#include <asm/xmon.h> 15#include <asm/xmon.h>
17#include <asm/prom.h> 16#include <asm/prom.h>
@@ -22,10 +21,11 @@
22#include <asm/processor.h> 21#include <asm/processor.h>
23#include <asm/delay.h> 22#include <asm/delay.h>
24#include <asm/btext.h> 23#include <asm/btext.h>
24#include <asm/time.h>
25#include "nonstdio.h"
25 26
26static volatile unsigned char __iomem *sccc, *sccd; 27static volatile unsigned char __iomem *sccc, *sccd;
27unsigned int TXRDY, RXRDY, DLAB; 28unsigned int TXRDY, RXRDY, DLAB;
28static int xmon_expect(const char *str, unsigned int timeout);
29 29
30static int use_serial; 30static int use_serial;
31static int use_screen; 31static int use_screen;
@@ -33,16 +33,6 @@ static int via_modem;
33static int xmon_use_sccb; 33static int xmon_use_sccb;
34static struct device_node *channel_node; 34static struct device_node *channel_node;
35 35
36#define TB_SPEED 25000000
37
38static inline unsigned int readtb(void)
39{
40 unsigned int ret;
41
42 asm volatile("mftb %0" : "=r" (ret) :);
43 return ret;
44}
45
46void buf_access(void) 36void buf_access(void)
47{ 37{
48 if (DLAB) 38 if (DLAB)
@@ -91,23 +81,7 @@ static unsigned long chrp_find_phys_io_base(void)
91} 81}
92#endif /* CONFIG_PPC_CHRP */ 82#endif /* CONFIG_PPC_CHRP */
93 83
94#ifdef CONFIG_MAGIC_SYSRQ 84void xmon_map_scc(void)
95static void sysrq_handle_xmon(int key, struct pt_regs *regs,
96 struct tty_struct *tty)
97{
98 xmon(regs);
99}
100
101static struct sysrq_key_op sysrq_xmon_op =
102{
103 .handler = sysrq_handle_xmon,
104 .help_msg = "Xmon",
105 .action_msg = "Entering xmon",
106};
107#endif
108
109void
110xmon_map_scc(void)
111{ 85{
112#ifdef CONFIG_PPC_MULTIPLATFORM 86#ifdef CONFIG_PPC_MULTIPLATFORM
113 volatile unsigned char __iomem *base; 87 volatile unsigned char __iomem *base;
@@ -217,8 +191,6 @@ xmon_map_scc(void)
217 RXRDY = 1; 191 RXRDY = 1;
218 DLAB = 0x80; 192 DLAB = 0x80;
219#endif /* platform */ 193#endif /* platform */
220
221 register_sysrq_key('x', &sysrq_xmon_op);
222} 194}
223 195
224static int scc_initialized = 0; 196static int scc_initialized = 0;
@@ -238,8 +210,7 @@ static inline void do_poll_adb(void)
238#endif /* CONFIG_ADB_CUDA */ 210#endif /* CONFIG_ADB_CUDA */
239} 211}
240 212
241int 213int xmon_write(void *ptr, int nb)
242xmon_write(void *handle, void *ptr, int nb)
243{ 214{
244 char *p = ptr; 215 char *p = ptr;
245 int i, c, ct; 216 int i, c, ct;
@@ -311,8 +282,7 @@ static unsigned char xmon_shift_keytab[128] =
311 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ 282 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
312 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ 283 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
313 284
314static int 285static int xmon_get_adb_key(void)
315xmon_get_adb_key(void)
316{ 286{
317 int k, t, on; 287 int k, t, on;
318 288
@@ -350,32 +320,21 @@ xmon_get_adb_key(void)
350} 320}
351#endif /* CONFIG_BOOTX_TEXT */ 321#endif /* CONFIG_BOOTX_TEXT */
352 322
353int 323int xmon_readchar(void)
354xmon_read(void *handle, void *ptr, int nb)
355{ 324{
356 char *p = ptr;
357 int i;
358
359#ifdef CONFIG_BOOTX_TEXT 325#ifdef CONFIG_BOOTX_TEXT
360 if (use_screen) { 326 if (use_screen)
361 for (i = 0; i < nb; ++i) 327 return xmon_get_adb_key();
362 *p++ = xmon_get_adb_key();
363 return i;
364 }
365#endif 328#endif
366 if (!scc_initialized) 329 if (!scc_initialized)
367 xmon_init_scc(); 330 xmon_init_scc();
368 for (i = 0; i < nb; ++i) {
369 while ((*sccc & RXRDY) == 0) 331 while ((*sccc & RXRDY) == 0)
370 do_poll_adb(); 332 do_poll_adb();
371 buf_access(); 333 buf_access();
372 *p++ = *sccd; 334 return *sccd;
373 }
374 return i;
375} 335}
376 336
377int 337int xmon_read_poll(void)
378xmon_read_poll(void)
379{ 338{
380 if ((*sccc & RXRDY) == 0) { 339 if ((*sccc & RXRDY) == 0) {
381 do_poll_adb(); 340 do_poll_adb();
@@ -395,8 +354,7 @@ static unsigned char scc_inittab[] = {
395 3, 0xc1, /* rx enable, 8 bits */ 354 3, 0xc1, /* rx enable, 8 bits */
396}; 355};
397 356
398void 357void xmon_init_scc(void)
399xmon_init_scc(void)
400{ 358{
401 if ( _machine == _MACH_chrp ) 359 if ( _machine == _MACH_chrp )
402 { 360 {
@@ -410,6 +368,7 @@ xmon_init_scc(void)
410 else if ( _machine == _MACH_Pmac ) 368 else if ( _machine == _MACH_Pmac )
411 { 369 {
412 int i, x; 370 int i, x;
371 unsigned long timeout;
413 372
414 if (channel_node != 0) 373 if (channel_node != 0)
415 pmac_call_feature( 374 pmac_call_feature(
@@ -424,8 +383,12 @@ xmon_init_scc(void)
424 PMAC_FTR_MODEM_ENABLE, 383 PMAC_FTR_MODEM_ENABLE,
425 channel_node, 0, 1); 384 channel_node, 0, 1);
426 printk(KERN_INFO "Modem powered up by debugger !\n"); 385 printk(KERN_INFO "Modem powered up by debugger !\n");
427 t0 = readtb(); 386 t0 = get_tbl();
428 while (readtb() - t0 < 3*TB_SPEED) 387 timeout = 3 * tb_ticks_per_sec;
388 if (timeout == 0)
389 /* assume 25MHz if tb_ticks_per_sec not set */
390 timeout = 75000000;
391 while (get_tbl() - t0 < timeout)
429 eieio(); 392 eieio();
430 } 393 }
431 /* use the B channel if requested */ 394 /* use the B channel if requested */
@@ -447,164 +410,19 @@ xmon_init_scc(void)
447 scc_initialized = 1; 410 scc_initialized = 1;
448 if (via_modem) { 411 if (via_modem) {
449 for (;;) { 412 for (;;) {
450 xmon_write(NULL, "ATE1V1\r", 7); 413 xmon_write("ATE1V1\r", 7);
451 if (xmon_expect("OK", 5)) { 414 if (xmon_expect("OK", 5)) {
452 xmon_write(NULL, "ATA\r", 4); 415 xmon_write("ATA\r", 4);
453 if (xmon_expect("CONNECT", 40)) 416 if (xmon_expect("CONNECT", 40))
454 break; 417 break;
455 } 418 }
456 xmon_write(NULL, "+++", 3); 419 xmon_write("+++", 3);
457 xmon_expect("OK", 3); 420 xmon_expect("OK", 3);
458 } 421 }
459 } 422 }
460} 423}
461 424
462void *xmon_stdin; 425void xmon_enter(void)
463void *xmon_stdout;
464void *xmon_stderr;
465
466int xmon_putc(int c, void *f)
467{
468 char ch = c;
469
470 if (c == '\n')
471 xmon_putc('\r', f);
472 return xmon_write(f, &ch, 1) == 1? c: -1;
473}
474
475int xmon_putchar(int c)
476{
477 return xmon_putc(c, xmon_stdout);
478}
479
480int xmon_fputs(char *str, void *f)
481{
482 int n = strlen(str);
483
484 return xmon_write(f, str, n) == n? 0: -1;
485}
486
487int
488xmon_readchar(void)
489{
490 char ch;
491
492 for (;;) {
493 switch (xmon_read(xmon_stdin, &ch, 1)) {
494 case 1:
495 return ch;
496 case -1:
497 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
498 return -1;
499 }
500 }
501}
502
503static char line[256];
504static char *lineptr;
505static int lineleft;
506
507int xmon_expect(const char *str, unsigned int timeout)
508{
509 int c;
510 unsigned int t0;
511
512 timeout *= TB_SPEED;
513 t0 = readtb();
514 do {
515 lineptr = line;
516 for (;;) {
517 c = xmon_read_poll();
518 if (c == -1) {
519 if (readtb() - t0 > timeout)
520 return 0;
521 continue;
522 }
523 if (c == '\n')
524 break;
525 if (c != '\r' && lineptr < &line[sizeof(line) - 1])
526 *lineptr++ = c;
527 }
528 *lineptr = 0;
529 } while (strstr(line, str) == NULL);
530 return 1;
531}
532
533int
534xmon_getchar(void)
535{
536 int c;
537
538 if (lineleft == 0) {
539 lineptr = line;
540 for (;;) {
541 c = xmon_readchar();
542 if (c == -1 || c == 4)
543 break;
544 if (c == '\r' || c == '\n') {
545 *lineptr++ = '\n';
546 xmon_putchar('\n');
547 break;
548 }
549 switch (c) {
550 case 0177:
551 case '\b':
552 if (lineptr > line) {
553 xmon_putchar('\b');
554 xmon_putchar(' ');
555 xmon_putchar('\b');
556 --lineptr;
557 }
558 break;
559 case 'U' & 0x1F:
560 while (lineptr > line) {
561 xmon_putchar('\b');
562 xmon_putchar(' ');
563 xmon_putchar('\b');
564 --lineptr;
565 }
566 break;
567 default:
568 if (lineptr >= &line[sizeof(line) - 1])
569 xmon_putchar('\a');
570 else {
571 xmon_putchar(c);
572 *lineptr++ = c;
573 }
574 }
575 }
576 lineleft = lineptr - line;
577 lineptr = line;
578 }
579 if (lineleft == 0)
580 return -1;
581 --lineleft;
582 return *lineptr++;
583}
584
585char *
586xmon_fgets(char *str, int nb, void *f)
587{
588 char *p;
589 int c;
590
591 for (p = str; p < str + nb - 1; ) {
592 c = xmon_getchar();
593 if (c == -1) {
594 if (p == str)
595 return NULL;
596 break;
597 }
598 *p++ = c;
599 if (c == '\n')
600 break;
601 }
602 *p = 0;
603 return str;
604}
605
606void
607xmon_enter(void)
608{ 426{
609#ifdef CONFIG_ADB_PMU 427#ifdef CONFIG_ADB_PMU
610 if (_machine == _MACH_Pmac) { 428 if (_machine == _MACH_Pmac) {
@@ -613,8 +431,7 @@ xmon_enter(void)
613#endif 431#endif
614} 432}
615 433
616void 434void xmon_leave(void)
617xmon_leave(void)
618{ 435{
619#ifdef CONFIG_ADB_PMU 436#ifdef CONFIG_ADB_PMU
620 if (_machine == _MACH_Pmac) { 437 if (_machine == _MACH_Pmac) {
diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start_64.c
index e50c158191e1..712552c4f242 100644
--- a/arch/powerpc/xmon/start_64.c
+++ b/arch/powerpc/xmon/start_64.c
@@ -6,182 +6,29 @@
6 * as published by the Free Software Foundation; either version 6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 */ 8 */
9#include <linux/config.h>
10#include <linux/string.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/sysrq.h>
14#include <linux/init.h>
15#include <asm/machdep.h> 9#include <asm/machdep.h>
16#include <asm/io.h>
17#include <asm/page.h>
18#include <asm/prom.h>
19#include <asm/processor.h>
20#include <asm/udbg.h> 10#include <asm/udbg.h>
21#include <asm/system.h>
22#include "nonstdio.h" 11#include "nonstdio.h"
23 12
24#ifdef CONFIG_MAGIC_SYSRQ 13void xmon_map_scc(void)
25
26static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
27 struct tty_struct *tty)
28{
29 /* ensure xmon is enabled */
30 xmon_init(1);
31 debugger(pt_regs);
32}
33
34static struct sysrq_key_op sysrq_xmon_op =
35{ 14{
36 .handler = sysrq_handle_xmon,
37 .help_msg = "Xmon",
38 .action_msg = "Entering xmon",
39};
40
41static int __init setup_xmon_sysrq(void)
42{
43 register_sysrq_key('x', &sysrq_xmon_op);
44 return 0;
45} 15}
46__initcall(setup_xmon_sysrq);
47#endif /* CONFIG_MAGIC_SYSRQ */
48 16
49int 17int xmon_write(void *ptr, int nb)
50xmon_write(void *handle, void *ptr, int nb)
51{ 18{
52 return udbg_write(ptr, nb); 19 return udbg_write(ptr, nb);
53} 20}
54 21
55int 22int xmon_readchar(void)
56xmon_read(void *handle, void *ptr, int nb)
57{ 23{
58 return udbg_read(ptr, nb); 24 if (udbg_getc)
25 return udbg_getc();
26 return -1;
59} 27}
60 28
61int 29int xmon_read_poll(void)
62xmon_read_poll(void)
63{ 30{
64 if (udbg_getc_poll) 31 if (udbg_getc_poll)
65 return udbg_getc_poll(); 32 return udbg_getc_poll();
66 return -1; 33 return -1;
67} 34}
68
69FILE *xmon_stdin;
70FILE *xmon_stdout;
71
72int
73xmon_putc(int c, void *f)
74{
75 char ch = c;
76
77 if (c == '\n')
78 xmon_putc('\r', f);
79 return xmon_write(f, &ch, 1) == 1? c: -1;
80}
81
82int
83xmon_putchar(int c)
84{
85 return xmon_putc(c, xmon_stdout);
86}
87
88int
89xmon_fputs(char *str, void *f)
90{
91 int n = strlen(str);
92
93 return xmon_write(f, str, n) == n? 0: -1;
94}
95
96int
97xmon_readchar(void)
98{
99 char ch;
100
101 for (;;) {
102 switch (xmon_read(xmon_stdin, &ch, 1)) {
103 case 1:
104 return ch;
105 case -1:
106 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
107 return -1;
108 }
109 }
110}
111
112static char line[256];
113static char *lineptr;
114static int lineleft;
115
116int
117xmon_getchar(void)
118{
119 int c;
120
121 if (lineleft == 0) {
122 lineptr = line;
123 for (;;) {
124 c = xmon_readchar();
125 if (c == -1 || c == 4)
126 break;
127 if (c == '\r' || c == '\n') {
128 *lineptr++ = '\n';
129 xmon_putchar('\n');
130 break;
131 }
132 switch (c) {
133 case 0177:
134 case '\b':
135 if (lineptr > line) {
136 xmon_putchar('\b');
137 xmon_putchar(' ');
138 xmon_putchar('\b');
139 --lineptr;
140 }
141 break;
142 case 'U' & 0x1F:
143 while (lineptr > line) {
144 xmon_putchar('\b');
145 xmon_putchar(' ');
146 xmon_putchar('\b');
147 --lineptr;
148 }
149 break;
150 default:
151 if (lineptr >= &line[sizeof(line) - 1])
152 xmon_putchar('\a');
153 else {
154 xmon_putchar(c);
155 *lineptr++ = c;
156 }
157 }
158 }
159 lineleft = lineptr - line;
160 lineptr = line;
161 }
162 if (lineleft == 0)
163 return -1;
164 --lineleft;
165 return *lineptr++;
166}
167
168char *
169xmon_fgets(char *str, int nb, void *f)
170{
171 char *p;
172 int c;
173
174 for (p = str; p < str + nb - 1; ) {
175 c = xmon_getchar();
176 if (c == -1) {
177 if (p == str)
178 return NULL;
179 break;
180 }
181 *p++ = c;
182 if (c == '\n')
183 break;
184 }
185 *p = 0;
186 return str;
187}
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
index a48bd594cf61..4c17b0486ad5 100644
--- a/arch/powerpc/xmon/start_8xx.c
+++ b/arch/powerpc/xmon/start_8xx.c
@@ -15,273 +15,30 @@
15#include <asm/8xx_immap.h> 15#include <asm/8xx_immap.h>
16#include <asm/mpc8xx.h> 16#include <asm/mpc8xx.h>
17#include <asm/commproc.h> 17#include <asm/commproc.h>
18#include "nonstdio.h"
18 19
19extern void xmon_printf(const char *fmt, ...);
20extern int xmon_8xx_write(char *str, int nb); 20extern int xmon_8xx_write(char *str, int nb);
21extern int xmon_8xx_read_poll(void); 21extern int xmon_8xx_read_poll(void);
22extern int xmon_8xx_read_char(void); 22extern int xmon_8xx_read_char(void);
23void prom_drawhex(uint);
24void prom_drawstring(const char *str);
25 23
26static int use_screen = 1; /* default */ 24void xmon_map_scc(void)
27
28#define TB_SPEED 25000000
29
30static inline unsigned int readtb(void)
31{
32 unsigned int ret;
33
34 asm volatile("mftb %0" : "=r" (ret) :);
35 return ret;
36}
37
38void buf_access(void)
39{
40}
41
42void
43xmon_map_scc(void)
44{ 25{
45
46 cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); 26 cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
47 use_screen = 0;
48
49 prom_drawstring("xmon uses serial port\n");
50} 27}
51 28
52static int scc_initialized = 0;
53
54void xmon_init_scc(void); 29void xmon_init_scc(void);
55 30
56int 31int xmon_write(void *ptr, int nb)
57xmon_write(void *handle, void *ptr, int nb)
58{ 32{
59 char *p = ptr;
60 int i, c, ct;
61
62 if (!scc_initialized)
63 xmon_init_scc();
64
65 return(xmon_8xx_write(ptr, nb)); 33 return(xmon_8xx_write(ptr, nb));
66} 34}
67 35
68int xmon_wants_key; 36int xmon_readchar(void)
69
70int
71xmon_read(void *handle, void *ptr, int nb)
72{ 37{
73 char *p = ptr; 38 return xmon_8xx_read_char();
74 int i;
75
76 if (!scc_initialized)
77 xmon_init_scc();
78
79 for (i = 0; i < nb; ++i) {
80 *p++ = xmon_8xx_read_char();
81 }
82 return i;
83} 39}
84 40
85int 41int xmon_read_poll(void)
86xmon_read_poll(void)
87{ 42{
88 return(xmon_8xx_read_poll()); 43 return(xmon_8xx_read_poll());
89} 44}
90
91void
92xmon_init_scc()
93{
94 scc_initialized = 1;
95}
96
97#if 0
98extern int (*prom_entry)(void *);
99
100int
101xmon_exit(void)
102{
103 struct prom_args {
104 char *service;
105 } args;
106
107 for (;;) {
108 args.service = "exit";
109 (*prom_entry)(&args);
110 }
111}
112#endif
113
114void *xmon_stdin;
115void *xmon_stdout;
116void *xmon_stderr;
117
118void
119xmon_init(void)
120{
121}
122
123int
124xmon_putc(int c, void *f)
125{
126 char ch = c;
127
128 if (c == '\n')
129 xmon_putc('\r', f);
130 return xmon_write(f, &ch, 1) == 1? c: -1;
131}
132
133int
134xmon_putchar(int c)
135{
136 return xmon_putc(c, xmon_stdout);
137}
138
139int
140xmon_fputs(char *str, void *f)
141{
142 int n = strlen(str);
143
144 return xmon_write(f, str, n) == n? 0: -1;
145}
146
147int
148xmon_readchar(void)
149{
150 char ch;
151
152 for (;;) {
153 switch (xmon_read(xmon_stdin, &ch, 1)) {
154 case 1:
155 return ch;
156 case -1:
157 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
158 return -1;
159 }
160 }
161}
162
163static char line[256];
164static char *lineptr;
165static int lineleft;
166
167#if 0
168int xmon_expect(const char *str, unsigned int timeout)
169{
170 int c;
171 unsigned int t0;
172
173 timeout *= TB_SPEED;
174 t0 = readtb();
175 do {
176 lineptr = line;
177 for (;;) {
178 c = xmon_read_poll();
179 if (c == -1) {
180 if (readtb() - t0 > timeout)
181 return 0;
182 continue;
183 }
184 if (c == '\n')
185 break;
186 if (c != '\r' && lineptr < &line[sizeof(line) - 1])
187 *lineptr++ = c;
188 }
189 *lineptr = 0;
190 } while (strstr(line, str) == NULL);
191 return 1;
192}
193#endif
194
195int
196xmon_getchar(void)
197{
198 int c;
199
200 if (lineleft == 0) {
201 lineptr = line;
202 for (;;) {
203 c = xmon_readchar();
204 if (c == -1 || c == 4)
205 break;
206 if (c == '\r' || c == '\n') {
207 *lineptr++ = '\n';
208 xmon_putchar('\n');
209 break;
210 }
211 switch (c) {
212 case 0177:
213 case '\b':
214 if (lineptr > line) {
215 xmon_putchar('\b');
216 xmon_putchar(' ');
217 xmon_putchar('\b');
218 --lineptr;
219 }
220 break;
221 case 'U' & 0x1F:
222 while (lineptr > line) {
223 xmon_putchar('\b');
224 xmon_putchar(' ');
225 xmon_putchar('\b');
226 --lineptr;
227 }
228 break;
229 default:
230 if (lineptr >= &line[sizeof(line) - 1])
231 xmon_putchar('\a');
232 else {
233 xmon_putchar(c);
234 *lineptr++ = c;
235 }
236 }
237 }
238 lineleft = lineptr - line;
239 lineptr = line;
240 }
241 if (lineleft == 0)
242 return -1;
243 --lineleft;
244 return *lineptr++;
245}
246
247char *
248xmon_fgets(char *str, int nb, void *f)
249{
250 char *p;
251 int c;
252
253 for (p = str; p < str + nb - 1; ) {
254 c = xmon_getchar();
255 if (c == -1) {
256 if (p == str)
257 return 0;
258 break;
259 }
260 *p++ = c;
261 if (c == '\n')
262 break;
263 }
264 *p = 0;
265 return str;
266}
267
268void
269prom_drawhex(uint val)
270{
271 unsigned char buf[10];
272
273 int i;
274 for (i = 7; i >= 0; i--)
275 {
276 buf[i] = "0123456789abcdef"[val & 0x0f];
277 val >>= 4;
278 }
279 buf[8] = '\0';
280 xmon_fputs(buf, xmon_stdout);
281}
282
283void
284prom_drawstring(const char *str)
285{
286 xmon_fputs(str, xmon_stdout);
287}
diff --git a/arch/powerpc/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c
deleted file mode 100644
index b48738c6dd33..000000000000
--- a/arch/powerpc/xmon/subr_prf.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * Written by Cort Dougan to replace the version originally used
3 * by Paul Mackerras, which came from NetBSD and thus had copyright
4 * conflicts with Linux.
5 *
6 * This file makes liberal use of the standard linux utility
7 * routines to reduce the size of the binary. We assume we can
8 * trust some parts of Linux inside the debugger.
9 * -- Cort (cort@cs.nmt.edu)
10 *
11 * Copyright (C) 1999 Cort Dougan.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version.
17 */
18
19#include <linux/kernel.h>
20#include <linux/string.h>
21#include <linux/module.h>
22#include <stdarg.h>
23#include "nonstdio.h"
24
25extern int xmon_write(void *, void *, int);
26
27void xmon_vfprintf(void *f, const char *fmt, va_list ap)
28{
29 static char xmon_buf[2048];
30 int n;
31
32 n = vsprintf(xmon_buf, fmt, ap);
33 xmon_write(f, xmon_buf, n);
34}
35
36void xmon_printf(const char *fmt, ...)
37{
38 va_list ap;
39
40 va_start(ap, fmt);
41 xmon_vfprintf(stdout, fmt, ap);
42 va_end(ap);
43}
44EXPORT_SYMBOL(xmon_printf);
45
46void xmon_fprintf(void *f, const char *fmt, ...)
47{
48 va_list ap;
49
50 va_start(ap, fmt);
51 xmon_vfprintf(f, fmt, ap);
52 va_end(ap);
53}
54
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 1124f1146202..ef4356b29a97 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Routines providing a simple monitor for use on the PowerMac. 2 * Routines providing a simple monitor for use on the PowerMac.
3 * 3 *
4 * Copyright (C) 1996 Paul Mackerras. 4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -18,6 +18,7 @@
18#include <linux/kallsyms.h> 18#include <linux/kallsyms.h>
19#include <linux/cpumask.h> 19#include <linux/cpumask.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/sysrq.h>
21 22
22#include <asm/ptrace.h> 23#include <asm/ptrace.h>
23#include <asm/string.h> 24#include <asm/string.h>
@@ -144,15 +145,10 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
144static const char *getvecname(unsigned long vec); 145static const char *getvecname(unsigned long vec);
145 146
146extern int print_insn_powerpc(unsigned long, unsigned long, int); 147extern int print_insn_powerpc(unsigned long, unsigned long, int);
147extern void printf(const char *fmt, ...);
148extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
149extern int xmon_putc(int c, void *f);
150extern int putchar(int ch);
151 148
152extern void xmon_enter(void); 149extern void xmon_enter(void);
153extern void xmon_leave(void); 150extern void xmon_leave(void);
154 151
155extern int xmon_read_poll(void);
156extern long setjmp(long *); 152extern long setjmp(long *);
157extern void longjmp(long *, long); 153extern void longjmp(long *, long);
158extern void xmon_save_regs(struct pt_regs *); 154extern void xmon_save_regs(struct pt_regs *);
@@ -748,7 +744,6 @@ cmds(struct pt_regs *excp)
748 printf("%x:", smp_processor_id()); 744 printf("%x:", smp_processor_id());
749#endif /* CONFIG_SMP */ 745#endif /* CONFIG_SMP */
750 printf("mon> "); 746 printf("mon> ");
751 fflush(stdout);
752 flush_input(); 747 flush_input();
753 termch = 0; 748 termch = 0;
754 cmd = skipbl(); 749 cmd = skipbl();
@@ -1472,17 +1467,23 @@ read_spr(int n)
1472{ 1467{
1473 unsigned int instrs[2]; 1468 unsigned int instrs[2];
1474 unsigned long (*code)(void); 1469 unsigned long (*code)(void);
1475 unsigned long opd[3];
1476 unsigned long ret = -1UL; 1470 unsigned long ret = -1UL;
1471#ifdef CONFIG_PPC64
1472 unsigned long opd[3];
1477 1473
1478 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1479 instrs[1] = 0x4e800020;
1480 opd[0] = (unsigned long)instrs; 1474 opd[0] = (unsigned long)instrs;
1481 opd[1] = 0; 1475 opd[1] = 0;
1482 opd[2] = 0; 1476 opd[2] = 0;
1477 code = (unsigned long (*)(void)) opd;
1478#else
1479 code = (unsigned long (*)(void)) instrs;
1480#endif
1481
1482 /* mfspr r3,n; blr */
1483 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1484 instrs[1] = 0x4e800020;
1483 store_inst(instrs); 1485 store_inst(instrs);
1484 store_inst(instrs+1); 1486 store_inst(instrs+1);
1485 code = (unsigned long (*)(void)) opd;
1486 1487
1487 if (setjmp(bus_error_jmp) == 0) { 1488 if (setjmp(bus_error_jmp) == 0) {
1488 catch_memory_errors = 1; 1489 catch_memory_errors = 1;
@@ -1504,16 +1505,21 @@ write_spr(int n, unsigned long val)
1504{ 1505{
1505 unsigned int instrs[2]; 1506 unsigned int instrs[2];
1506 unsigned long (*code)(unsigned long); 1507 unsigned long (*code)(unsigned long);
1508#ifdef CONFIG_PPC64
1507 unsigned long opd[3]; 1509 unsigned long opd[3];
1508 1510
1509 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1510 instrs[1] = 0x4e800020;
1511 opd[0] = (unsigned long)instrs; 1511 opd[0] = (unsigned long)instrs;
1512 opd[1] = 0; 1512 opd[1] = 0;
1513 opd[2] = 0; 1513 opd[2] = 0;
1514 code = (unsigned long (*)(unsigned long)) opd;
1515#else
1516 code = (unsigned long (*)(unsigned long)) instrs;
1517#endif
1518
1519 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1520 instrs[1] = 0x4e800020;
1514 store_inst(instrs); 1521 store_inst(instrs);
1515 store_inst(instrs+1); 1522 store_inst(instrs+1);
1516 code = (unsigned long (*)(unsigned long)) opd;
1517 1523
1518 if (setjmp(bus_error_jmp) == 0) { 1524 if (setjmp(bus_error_jmp) == 0) {
1519 catch_memory_errors = 1; 1525 catch_memory_errors = 1;
@@ -1797,7 +1803,7 @@ memex(void)
1797 for(;;){ 1803 for(;;){
1798 if (!mnoread) 1804 if (!mnoread)
1799 n = mread(adrs, val, size); 1805 n = mread(adrs, val, size);
1800 printf("%.16x%c", adrs, brev? 'r': ' '); 1806 printf(REG"%c", adrs, brev? 'r': ' ');
1801 if (!mnoread) { 1807 if (!mnoread) {
1802 if (brev) 1808 if (brev)
1803 byterev(val, size); 1809 byterev(val, size);
@@ -1976,17 +1982,18 @@ prdump(unsigned long adrs, long ndump)
1976 nr = mread(adrs, temp, r); 1982 nr = mread(adrs, temp, r);
1977 adrs += nr; 1983 adrs += nr;
1978 for (m = 0; m < r; ++m) { 1984 for (m = 0; m < r; ++m) {
1979 if ((m & 7) == 0 && m > 0) 1985 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
1980 putchar(' '); 1986 putchar(' ');
1981 if (m < nr) 1987 if (m < nr)
1982 printf("%.2x", temp[m]); 1988 printf("%.2x", temp[m]);
1983 else 1989 else
1984 printf("%s", fault_chars[fault_type]); 1990 printf("%s", fault_chars[fault_type]);
1985 } 1991 }
1986 if (m <= 8) 1992 for (; m < 16; ++m) {
1987 printf(" "); 1993 if ((m & (sizeof(long) - 1)) == 0)
1988 for (; m < 16; ++m) 1994 putchar(' ');
1989 printf(" "); 1995 printf(" ");
1996 }
1990 printf(" |"); 1997 printf(" |");
1991 for (m = 0; m < r; ++m) { 1998 for (m = 0; m < r; ++m) {
1992 if (m < nr) { 1999 if (m < nr) {
@@ -2151,7 +2158,6 @@ memzcan(void)
2151 ok = mread(a, &v, 1); 2158 ok = mread(a, &v, 1);
2152 if (ok && !ook) { 2159 if (ok && !ook) {
2153 printf("%.8x .. ", a); 2160 printf("%.8x .. ", a);
2154 fflush(stdout);
2155 } else if (!ok && ook) 2161 } else if (!ok && ook)
2156 printf("%.8x\n", a - mskip); 2162 printf("%.8x\n", a - mskip);
2157 ook = ok; 2163 ook = ok;
@@ -2372,7 +2378,7 @@ int
2372inchar(void) 2378inchar(void)
2373{ 2379{
2374 if (lineptr == NULL || *lineptr == 0) { 2380 if (lineptr == NULL || *lineptr == 0) {
2375 if (fgets(line, sizeof(line), stdin) == NULL) { 2381 if (xmon_gets(line, sizeof(line)) == NULL) {
2376 lineptr = NULL; 2382 lineptr = NULL;
2377 return EOF; 2383 return EOF;
2378 } 2384 }
@@ -2526,4 +2532,29 @@ void xmon_init(int enable)
2526 __debugger_dabr_match = NULL; 2532 __debugger_dabr_match = NULL;
2527 __debugger_fault_handler = NULL; 2533 __debugger_fault_handler = NULL;
2528 } 2534 }
2535 xmon_map_scc();
2536}
2537
2538#ifdef CONFIG_MAGIC_SYSRQ
2539static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2540 struct tty_struct *tty)
2541{
2542 /* ensure xmon is enabled */
2543 xmon_init(1);
2544 debugger(pt_regs);
2545}
2546
2547static struct sysrq_key_op sysrq_xmon_op =
2548{
2549 .handler = sysrq_handle_xmon,
2550 .help_msg = "Xmon",
2551 .action_msg = "Entering xmon",
2552};
2553
2554static int __init setup_xmon_sysrq(void)
2555{
2556 register_sysrq_key('x', &sysrq_xmon_op);
2557 return 0;
2529} 2558}
2559__initcall(setup_xmon_sysrq);
2560#endif /* CONFIG_MAGIC_SYSRQ */
diff --git a/arch/ppc/boot/include/of1275.h b/arch/ppc/boot/include/of1275.h
index 69173df76db0..4ed88acfa73a 100644
--- a/arch/ppc/boot/include/of1275.h
+++ b/arch/ppc/boot/include/of1275.h
@@ -19,6 +19,9 @@ extern prom_entry of_prom_entry;
19 19
20/* function declarations */ 20/* function declarations */
21 21
22int call_prom(const char *service, int nargs, int nret, ...);
23int call_prom_ret(const char *service, int nargs, int nret,
24 unsigned int *rets, ...);
22void * claim(unsigned int virt, unsigned int size, unsigned int align); 25void * claim(unsigned int virt, unsigned int size, unsigned int align);
23int map(unsigned int phys, unsigned int virt, unsigned int size); 26int map(unsigned int phys, unsigned int virt, unsigned int size);
24void enter(void); 27void enter(void);
diff --git a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile
index 02e6f235d7cb..0b979c004972 100644
--- a/arch/ppc/boot/of1275/Makefile
+++ b/arch/ppc/boot/of1275/Makefile
@@ -3,4 +3,4 @@
3# 3#
4 4
5lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ 5lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \
6 ofstdio.o read.o release.o write.o map.o 6 ofstdio.o read.o release.o write.o map.o call_prom.o
diff --git a/arch/ppc/boot/of1275/call_prom.c b/arch/ppc/boot/of1275/call_prom.c
new file mode 100644
index 000000000000..9479a3a2b8c7
--- /dev/null
+++ b/arch/ppc/boot/of1275/call_prom.c
@@ -0,0 +1,74 @@
1/*
2 * Copyright (C) 1996-2005 Paul Mackerras.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include "of1275.h"
11#include <stdarg.h>
12
13int call_prom(const char *service, int nargs, int nret, ...)
14{
15 int i;
16 struct prom_args {
17 const char *service;
18 int nargs;
19 int nret;
20 unsigned int args[12];
21 } args;
22 va_list list;
23
24 args.service = service;
25 args.nargs = nargs;
26 args.nret = nret;
27
28 va_start(list, nret);
29 for (i = 0; i < nargs; i++)
30 args.args[i] = va_arg(list, unsigned int);
31 va_end(list);
32
33 for (i = 0; i < nret; i++)
34 args.args[nargs+i] = 0;
35
36 if (of_prom_entry(&args) < 0)
37 return -1;
38
39 return (nret > 0)? args.args[nargs]: 0;
40}
41
42int call_prom_ret(const char *service, int nargs, int nret,
43 unsigned int *rets, ...)
44{
45 int i;
46 struct prom_args {
47 const char *service;
48 int nargs;
49 int nret;
50 unsigned int args[12];
51 } args;
52 va_list list;
53
54 args.service = service;
55 args.nargs = nargs;
56 args.nret = nret;
57
58 va_start(list, rets);
59 for (i = 0; i < nargs; i++)
60 args.args[i] = va_arg(list, unsigned int);
61 va_end(list);
62
63 for (i = 0; i < nret; i++)
64 args.args[nargs+i] = 0;
65
66 if (of_prom_entry(&args) < 0)
67 return -1;
68
69 if (rets != (void *) 0)
70 for (i = 1; i < nret; ++i)
71 rets[i-1] = args.args[nargs+i];
72
73 return (nret > 0)? args.args[nargs]: 0;
74}
diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c
index 13169a5c4339..1ed3aeeff8ae 100644
--- a/arch/ppc/boot/of1275/claim.c
+++ b/arch/ppc/boot/of1275/claim.c
@@ -9,27 +9,84 @@
9 */ 9 */
10 10
11#include "of1275.h" 11#include "of1275.h"
12#include "nonstdio.h"
12 13
13void * 14/*
14claim(unsigned int virt, unsigned int size, unsigned int align) 15 * Older OF's require that when claiming a specific range of addresses,
16 * we claim the physical space in the /memory node and the virtual
17 * space in the chosen mmu node, and then do a map operation to
18 * map virtual to physical.
19 */
20static int need_map = -1;
21static ihandle chosen_mmu;
22static phandle memory;
23
24/* returns true if s2 is a prefix of s1 */
25static int string_match(const char *s1, const char *s2)
26{
27 for (; *s2; ++s2)
28 if (*s1++ != *s2)
29 return 0;
30 return 1;
31}
32
33static int check_of_version(void)
34{
35 phandle oprom, chosen;
36 char version[64];
37
38 oprom = finddevice("/openprom");
39 if (oprom == OF_INVALID_HANDLE)
40 return 0;
41 if (getprop(oprom, "model", version, sizeof(version)) <= 0)
42 return 0;
43 version[sizeof(version)-1] = 0;
44 printf("OF version = '%s'\n", version);
45 if (!string_match(version, "Open Firmware, 1.")
46 && !string_match(version, "FirmWorks,3."))
47 return 0;
48 chosen = finddevice("/chosen");
49 if (chosen == OF_INVALID_HANDLE) {
50 chosen = finddevice("/chosen@0");
51 if (chosen == OF_INVALID_HANDLE) {
52 printf("no chosen\n");
53 return 0;
54 }
55 }
56 if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
57 printf("no mmu\n");
58 return 0;
59 }
60 memory = (ihandle) call_prom("open", 1, 1, "/memory");
61 if (memory == OF_INVALID_HANDLE) {
62 memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
63 if (memory == OF_INVALID_HANDLE) {
64 printf("no memory node\n");
65 return 0;
66 }
67 }
68 printf("old OF detected\n");
69 return 1;
70}
71
72void *claim(unsigned int virt, unsigned int size, unsigned int align)
15{ 73{
16 struct prom_args { 74 int ret;
17 char *service; 75 unsigned int result;
18 int nargs;
19 int nret;
20 unsigned int virt;
21 unsigned int size;
22 unsigned int align;
23 void *ret;
24 } args;
25 76
26 args.service = "claim"; 77 if (need_map < 0)
27 args.nargs = 3; 78 need_map = check_of_version();
28 args.nret = 1; 79 if (align || !need_map)
29 args.virt = virt; 80 return (void *) call_prom("claim", 3, 1, virt, size, align);
30 args.size = size; 81
31 args.align = align; 82 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
32 args.ret = (void *) 0; 83 align, size, virt);
33 (*of_prom_entry)(&args); 84 if (ret != 0 || result == -1)
34 return args.ret; 85 return (void *) -1;
86 ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
87 align, size, virt);
88 /* 0x12 == coherent + read/write */
89 ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
90 0x12, size, virt, virt);
91 return virt;
35} 92}
diff --git a/arch/ppc/boot/of1275/finddevice.c b/arch/ppc/boot/of1275/finddevice.c
index 2c0f7cbb793e..0dcb1201b772 100644
--- a/arch/ppc/boot/of1275/finddevice.c
+++ b/arch/ppc/boot/of1275/finddevice.c
@@ -10,22 +10,7 @@
10 10
11#include "of1275.h" 11#include "of1275.h"
12 12
13phandle 13phandle finddevice(const char *name)
14finddevice(const char *name)
15{ 14{
16 struct prom_args { 15 return (phandle) call_prom("finddevice", 1, 1, name);
17 char *service;
18 int nargs;
19 int nret;
20 const char *devspec;
21 phandle device;
22 } args;
23
24 args.service = "finddevice";
25 args.nargs = 1;
26 args.nret = 1;
27 args.devspec = name;
28 args.device = OF_INVALID_HANDLE;
29 (*of_prom_entry)(&args);
30 return args.device;
31} 16}
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
index 03415238fabf..83a6433459ce 100644
--- a/arch/ppc/boot/openfirmware/Makefile
+++ b/arch/ppc/boot/openfirmware/Makefile
@@ -80,8 +80,7 @@ $(obj)/note: $(utils)/mknote FORCE
80 $(call if_changed,mknote) 80 $(call if_changed,mknote)
81 81
82 82
83$(obj)/coffcrt0.o: EXTRA_AFLAGS := -traditional -DXCOFF 83$(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF
84$(obj)/crt0.o: EXTRA_AFLAGS := -traditional
85targets += coffcrt0.o crt0.o 84targets += coffcrt0.o crt0.o
86$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE 85$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
87 $(call if_changed_dep,as_o_S) 86 $(call if_changed_dep,as_o_S)
diff --git a/arch/ppc/configs/mpc834x_sys_defconfig b/arch/ppc/configs/mpc834x_sys_defconfig
index 4a5522ca8207..673dc64ebcb1 100644
--- a/arch/ppc/configs/mpc834x_sys_defconfig
+++ b/arch/ppc/configs/mpc834x_sys_defconfig
@@ -1,16 +1,17 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc4 3# Linux kernel version: 2.6.14
4# Thu Feb 17 16:12:23 2005 4# Mon Nov 7 15:38:29 2005
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y 7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y 8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y 9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_HAVE_DEC_LOCK=y
11CONFIG_PPC=y 10CONFIG_PPC=y
12CONFIG_PPC32=y 11CONFIG_PPC32=y
13CONFIG_GENERIC_NVRAM=y 12CONFIG_GENERIC_NVRAM=y
13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y
14 15
15# 16#
16# Code maturity level options 17# Code maturity level options
@@ -18,23 +19,28 @@ CONFIG_GENERIC_NVRAM=y
18CONFIG_EXPERIMENTAL=y 19CONFIG_EXPERIMENTAL=y
19CONFIG_CLEAN_COMPILE=y 20CONFIG_CLEAN_COMPILE=y
20CONFIG_BROKEN_ON_SMP=y 21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
21 23
22# 24#
23# General setup 25# General setup
24# 26#
25CONFIG_LOCALVERSION="" 27CONFIG_LOCALVERSION=""
28CONFIG_LOCALVERSION_AUTO=y
26CONFIG_SWAP=y 29CONFIG_SWAP=y
27CONFIG_SYSVIPC=y 30CONFIG_SYSVIPC=y
28# CONFIG_POSIX_MQUEUE is not set 31# CONFIG_POSIX_MQUEUE is not set
29# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
30CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set 34# CONFIG_AUDIT is not set
32CONFIG_LOG_BUF_SHIFT=14
33# CONFIG_HOTPLUG is not set 35# CONFIG_HOTPLUG is not set
34CONFIG_KOBJECT_UEVENT=y 36CONFIG_KOBJECT_UEVENT=y
35# CONFIG_IKCONFIG is not set 37# CONFIG_IKCONFIG is not set
38CONFIG_INITRAMFS_SOURCE=""
36CONFIG_EMBEDDED=y 39CONFIG_EMBEDDED=y
37# CONFIG_KALLSYMS is not set 40# CONFIG_KALLSYMS is not set
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_BASE_FULL=y
38CONFIG_FUTEX=y 44CONFIG_FUTEX=y
39# CONFIG_EPOLL is not set 45# CONFIG_EPOLL is not set
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +50,7 @@ CONFIG_CC_ALIGN_LABELS=0
44CONFIG_CC_ALIGN_LOOPS=0 50CONFIG_CC_ALIGN_LOOPS=0
45CONFIG_CC_ALIGN_JUMPS=0 51CONFIG_CC_ALIGN_JUMPS=0
46# CONFIG_TINY_SHMEM is not set 52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
47 54
48# 55#
49# Loadable module support 56# Loadable module support
@@ -59,34 +66,84 @@ CONFIG_6xx=y
59# CONFIG_POWER3 is not set 66# CONFIG_POWER3 is not set
60# CONFIG_POWER4 is not set 67# CONFIG_POWER4 is not set
61# CONFIG_8xx is not set 68# CONFIG_8xx is not set
69# CONFIG_E200 is not set
62# CONFIG_E500 is not set 70# CONFIG_E500 is not set
71CONFIG_PPC_FPU=y
72# CONFIG_KEXEC is not set
63# CONFIG_CPU_FREQ is not set 73# CONFIG_CPU_FREQ is not set
74# CONFIG_WANT_EARLY_SERIAL is not set
64CONFIG_PPC_GEN550=y 75CONFIG_PPC_GEN550=y
65CONFIG_83xx=y
66
67#
68# Freescale 83xx options
69#
70CONFIG_MPC834x_SYS=y
71CONFIG_MPC834x=y
72CONFIG_PPC_STD_MMU=y 76CONFIG_PPC_STD_MMU=y
73 77
74# 78#
75# Platform options 79# Platform options
76# 80#
81# CONFIG_PPC_MULTIPLATFORM is not set
82# CONFIG_APUS is not set
83# CONFIG_KATANA is not set
84# CONFIG_WILLOW is not set
85# CONFIG_CPCI690 is not set
86# CONFIG_POWERPMC250 is not set
87# CONFIG_CHESTNUT is not set
88# CONFIG_SPRUCE is not set
89# CONFIG_HDPU is not set
90# CONFIG_EV64260 is not set
91# CONFIG_LOPEC is not set
92# CONFIG_MVME5100 is not set
93# CONFIG_PPLUS is not set
94# CONFIG_PRPMC750 is not set
95# CONFIG_PRPMC800 is not set
96# CONFIG_SANDPOINT is not set
97# CONFIG_RADSTONE_PPC7D is not set
98# CONFIG_PAL4 is not set
99# CONFIG_GEMINI is not set
100# CONFIG_EST8260 is not set
101# CONFIG_SBC82xx is not set
102# CONFIG_SBS8260 is not set
103# CONFIG_RPX8260 is not set
104# CONFIG_TQM8260 is not set
105# CONFIG_ADS8272 is not set
106# CONFIG_PQ2FADS is not set
107# CONFIG_LITE5200 is not set
108CONFIG_MPC834x_SYS=y
109# CONFIG_EV64360 is not set
110CONFIG_83xx=y
111CONFIG_MPC834x=y
77# CONFIG_SMP is not set 112# CONFIG_SMP is not set
78# CONFIG_PREEMPT is not set
79# CONFIG_HIGHMEM is not set 113# CONFIG_HIGHMEM is not set
114# CONFIG_HZ_100 is not set
115CONFIG_HZ_250=y
116# CONFIG_HZ_1000 is not set
117CONFIG_HZ=250
118CONFIG_PREEMPT_NONE=y
119# CONFIG_PREEMPT_VOLUNTARY is not set
120# CONFIG_PREEMPT is not set
121CONFIG_SELECT_MEMORY_MODEL=y
122CONFIG_FLATMEM_MANUAL=y
123# CONFIG_DISCONTIGMEM_MANUAL is not set
124# CONFIG_SPARSEMEM_MANUAL is not set
125CONFIG_FLATMEM=y
126CONFIG_FLAT_NODE_MEM_MAP=y
127# CONFIG_SPARSEMEM_STATIC is not set
128CONFIG_SPLIT_PTLOCK_CPUS=4
80CONFIG_BINFMT_ELF=y 129CONFIG_BINFMT_ELF=y
81# CONFIG_BINFMT_MISC is not set 130# CONFIG_BINFMT_MISC is not set
82# CONFIG_CMDLINE_BOOL is not set 131# CONFIG_CMDLINE_BOOL is not set
132# CONFIG_PM is not set
133# CONFIG_SOFTWARE_SUSPEND is not set
134CONFIG_SECCOMP=y
135CONFIG_ISA_DMA_API=y
83 136
84# 137#
85# Bus options 138# Bus options
86# 139#
87CONFIG_GENERIC_ISA_DMA=y 140CONFIG_GENERIC_ISA_DMA=y
88# CONFIG_PCI is not set 141# CONFIG_PPC_I8259 is not set
89# CONFIG_PCI_DOMAINS is not set 142CONFIG_PPC_INDIRECT_PCI=y
143CONFIG_PCI=y
144CONFIG_PCI_DOMAINS=y
145# CONFIG_MPC83xx_PCI2 is not set
146CONFIG_PCI_LEGACY_PROC=y
90 147
91# 148#
92# PCCARD (PCMCIA/CardBus) support 149# PCCARD (PCMCIA/CardBus) support
@@ -94,10 +151,6 @@ CONFIG_GENERIC_ISA_DMA=y
94# CONFIG_PCCARD is not set 151# CONFIG_PCCARD is not set
95 152
96# 153#
97# PC-card bridges
98#
99
100#
101# Advanced setup 154# Advanced setup
102# 155#
103# CONFIG_ADVANCED_OPTIONS is not set 156# CONFIG_ADVANCED_OPTIONS is not set
@@ -112,6 +165,75 @@ CONFIG_TASK_SIZE=0x80000000
112CONFIG_BOOT_LOAD=0x00800000 165CONFIG_BOOT_LOAD=0x00800000
113 166
114# 167#
168# Networking
169#
170CONFIG_NET=y
171
172#
173# Networking options
174#
175CONFIG_PACKET=y
176# CONFIG_PACKET_MMAP is not set
177CONFIG_UNIX=y
178# CONFIG_NET_KEY is not set
179CONFIG_INET=y
180CONFIG_IP_MULTICAST=y
181# CONFIG_IP_ADVANCED_ROUTER is not set
182CONFIG_IP_FIB_HASH=y
183CONFIG_IP_PNP=y
184CONFIG_IP_PNP_DHCP=y
185CONFIG_IP_PNP_BOOTP=y
186# CONFIG_IP_PNP_RARP is not set
187# CONFIG_NET_IPIP is not set
188# CONFIG_NET_IPGRE is not set
189# CONFIG_IP_MROUTE is not set
190# CONFIG_ARPD is not set
191CONFIG_SYN_COOKIES=y
192# CONFIG_INET_AH is not set
193# CONFIG_INET_ESP is not set
194# CONFIG_INET_IPCOMP is not set
195# CONFIG_INET_TUNNEL is not set
196CONFIG_INET_DIAG=y
197CONFIG_INET_TCP_DIAG=y
198# CONFIG_TCP_CONG_ADVANCED is not set
199CONFIG_TCP_CONG_BIC=y
200# CONFIG_IPV6 is not set
201# CONFIG_NETFILTER is not set
202
203#
204# DCCP Configuration (EXPERIMENTAL)
205#
206# CONFIG_IP_DCCP is not set
207
208#
209# SCTP Configuration (EXPERIMENTAL)
210#
211# CONFIG_IP_SCTP is not set
212# CONFIG_ATM is not set
213# CONFIG_BRIDGE is not set
214# CONFIG_VLAN_8021Q is not set
215# CONFIG_DECNET is not set
216# CONFIG_LLC2 is not set
217# CONFIG_IPX is not set
218# CONFIG_ATALK is not set
219# CONFIG_X25 is not set
220# CONFIG_LAPB is not set
221# CONFIG_NET_DIVERT is not set
222# CONFIG_ECONET is not set
223# CONFIG_WAN_ROUTER is not set
224# CONFIG_NET_SCHED is not set
225# CONFIG_NET_CLS_ROUTE is not set
226
227#
228# Network testing
229#
230# CONFIG_NET_PKTGEN is not set
231# CONFIG_HAMRADIO is not set
232# CONFIG_IRDA is not set
233# CONFIG_BT is not set
234# CONFIG_IEEE80211 is not set
235
236#
115# Device Drivers 237# Device Drivers
116# 238#
117 239
@@ -123,6 +245,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
123# CONFIG_FW_LOADER is not set 245# CONFIG_FW_LOADER is not set
124 246
125# 247#
248# Connector - unified userspace <-> kernelspace linker
249#
250# CONFIG_CONNECTOR is not set
251
252#
126# Memory Technology Devices (MTD) 253# Memory Technology Devices (MTD)
127# 254#
128# CONFIG_MTD is not set 255# CONFIG_MTD is not set
@@ -140,15 +267,19 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
140# Block devices 267# Block devices
141# 268#
142# CONFIG_BLK_DEV_FD is not set 269# CONFIG_BLK_DEV_FD is not set
270# CONFIG_BLK_CPQ_DA is not set
271# CONFIG_BLK_CPQ_CISS_DA is not set
272# CONFIG_BLK_DEV_DAC960 is not set
273# CONFIG_BLK_DEV_UMEM is not set
143# CONFIG_BLK_DEV_COW_COMMON is not set 274# CONFIG_BLK_DEV_COW_COMMON is not set
144CONFIG_BLK_DEV_LOOP=y 275CONFIG_BLK_DEV_LOOP=y
145# CONFIG_BLK_DEV_CRYPTOLOOP is not set 276# CONFIG_BLK_DEV_CRYPTOLOOP is not set
146# CONFIG_BLK_DEV_NBD is not set 277# CONFIG_BLK_DEV_NBD is not set
278# CONFIG_BLK_DEV_SX8 is not set
147CONFIG_BLK_DEV_RAM=y 279CONFIG_BLK_DEV_RAM=y
148CONFIG_BLK_DEV_RAM_COUNT=16 280CONFIG_BLK_DEV_RAM_COUNT=16
149CONFIG_BLK_DEV_RAM_SIZE=32768 281CONFIG_BLK_DEV_RAM_SIZE=32768
150CONFIG_BLK_DEV_INITRD=y 282CONFIG_BLK_DEV_INITRD=y
151CONFIG_INITRAMFS_SOURCE=""
152# CONFIG_LBD is not set 283# CONFIG_LBD is not set
153# CONFIG_CDROM_PKTCDVD is not set 284# CONFIG_CDROM_PKTCDVD is not set
154 285
@@ -159,6 +290,11 @@ CONFIG_IOSCHED_NOOP=y
159CONFIG_IOSCHED_AS=y 290CONFIG_IOSCHED_AS=y
160CONFIG_IOSCHED_DEADLINE=y 291CONFIG_IOSCHED_DEADLINE=y
161CONFIG_IOSCHED_CFQ=y 292CONFIG_IOSCHED_CFQ=y
293CONFIG_DEFAULT_AS=y
294# CONFIG_DEFAULT_DEADLINE is not set
295# CONFIG_DEFAULT_CFQ is not set
296# CONFIG_DEFAULT_NOOP is not set
297CONFIG_DEFAULT_IOSCHED="anticipatory"
162# CONFIG_ATA_OVER_ETH is not set 298# CONFIG_ATA_OVER_ETH is not set
163 299
164# 300#
@@ -169,6 +305,7 @@ CONFIG_IOSCHED_CFQ=y
169# 305#
170# SCSI device support 306# SCSI device support
171# 307#
308# CONFIG_RAID_ATTRS is not set
172# CONFIG_SCSI is not set 309# CONFIG_SCSI is not set
173 310
174# 311#
@@ -179,110 +316,116 @@ CONFIG_IOSCHED_CFQ=y
179# 316#
180# Fusion MPT device support 317# Fusion MPT device support
181# 318#
319# CONFIG_FUSION is not set
182 320
183# 321#
184# IEEE 1394 (FireWire) support 322# IEEE 1394 (FireWire) support
185# 323#
324# CONFIG_IEEE1394 is not set
186 325
187# 326#
188# I2O device support 327# I2O device support
189# 328#
329# CONFIG_I2O is not set
190 330
191# 331#
192# Macintosh device drivers 332# Macintosh device drivers
193# 333#
194 334
195# 335#
196# Networking support 336# Network device support
197# 337#
198CONFIG_NET=y 338CONFIG_NETDEVICES=y
199 339# CONFIG_DUMMY is not set
200# 340# CONFIG_BONDING is not set
201# Networking options 341# CONFIG_EQUALIZER is not set
202# 342# CONFIG_TUN is not set
203CONFIG_PACKET=y
204# CONFIG_PACKET_MMAP is not set
205# CONFIG_NETLINK_DEV is not set
206CONFIG_UNIX=y
207# CONFIG_NET_KEY is not set
208CONFIG_INET=y
209CONFIG_IP_MULTICAST=y
210# CONFIG_IP_ADVANCED_ROUTER is not set
211CONFIG_IP_PNP=y
212CONFIG_IP_PNP_DHCP=y
213CONFIG_IP_PNP_BOOTP=y
214# CONFIG_IP_PNP_RARP is not set
215# CONFIG_NET_IPIP is not set
216# CONFIG_NET_IPGRE is not set
217# CONFIG_IP_MROUTE is not set
218# CONFIG_ARPD is not set
219CONFIG_SYN_COOKIES=y
220# CONFIG_INET_AH is not set
221# CONFIG_INET_ESP is not set
222# CONFIG_INET_IPCOMP is not set
223# CONFIG_INET_TUNNEL is not set
224CONFIG_IP_TCPDIAG=y
225# CONFIG_IP_TCPDIAG_IPV6 is not set
226# CONFIG_IPV6 is not set
227# CONFIG_NETFILTER is not set
228 343
229# 344#
230# SCTP Configuration (EXPERIMENTAL) 345# ARCnet devices
231# 346#
232# CONFIG_IP_SCTP is not set 347# CONFIG_ARCNET is not set
233# CONFIG_ATM is not set
234# CONFIG_BRIDGE is not set
235# CONFIG_VLAN_8021Q is not set
236# CONFIG_DECNET is not set
237# CONFIG_LLC2 is not set
238# CONFIG_IPX is not set
239# CONFIG_ATALK is not set
240# CONFIG_X25 is not set
241# CONFIG_LAPB is not set
242# CONFIG_NET_DIVERT is not set
243# CONFIG_ECONET is not set
244# CONFIG_WAN_ROUTER is not set
245 348
246# 349#
247# QoS and/or fair queueing 350# PHY device support
248# 351#
249# CONFIG_NET_SCHED is not set 352CONFIG_PHYLIB=y
250# CONFIG_NET_CLS_ROUTE is not set
251 353
252# 354#
253# Network testing 355# MII PHY device drivers
254# 356#
255# CONFIG_NET_PKTGEN is not set 357CONFIG_MARVELL_PHY=y
256# CONFIG_NETPOLL is not set 358# CONFIG_DAVICOM_PHY is not set
257# CONFIG_NET_POLL_CONTROLLER is not set 359# CONFIG_QSEMI_PHY is not set
258# CONFIG_HAMRADIO is not set 360# CONFIG_LXT_PHY is not set
259# CONFIG_IRDA is not set 361# CONFIG_CICADA_PHY is not set
260# CONFIG_BT is not set
261CONFIG_NETDEVICES=y
262# CONFIG_DUMMY is not set
263# CONFIG_BONDING is not set
264# CONFIG_EQUALIZER is not set
265# CONFIG_TUN is not set
266 362
267# 363#
268# Ethernet (10 or 100Mbit) 364# Ethernet (10 or 100Mbit)
269# 365#
270CONFIG_NET_ETHERNET=y 366CONFIG_NET_ETHERNET=y
271CONFIG_MII=y 367CONFIG_MII=y
368# CONFIG_HAPPYMEAL is not set
369# CONFIG_SUNGEM is not set
370# CONFIG_CASSINI is not set
371# CONFIG_NET_VENDOR_3COM is not set
372
373#
374# Tulip family network device support
375#
376# CONFIG_NET_TULIP is not set
377# CONFIG_HP100 is not set
378CONFIG_NET_PCI=y
379# CONFIG_PCNET32 is not set
380# CONFIG_AMD8111_ETH is not set
381# CONFIG_ADAPTEC_STARFIRE is not set
382# CONFIG_B44 is not set
383# CONFIG_FORCEDETH is not set
384# CONFIG_DGRS is not set
385# CONFIG_EEPRO100 is not set
386CONFIG_E100=y
387# CONFIG_FEALNX is not set
388# CONFIG_NATSEMI is not set
389# CONFIG_NE2K_PCI is not set
390# CONFIG_8139CP is not set
391# CONFIG_8139TOO is not set
392# CONFIG_SIS900 is not set
393# CONFIG_EPIC100 is not set
394# CONFIG_SUNDANCE is not set
395# CONFIG_TLAN is not set
396# CONFIG_VIA_RHINE is not set
272 397
273# 398#
274# Ethernet (1000 Mbit) 399# Ethernet (1000 Mbit)
275# 400#
401# CONFIG_ACENIC is not set
402# CONFIG_DL2K is not set
403CONFIG_E1000=y
404# CONFIG_E1000_NAPI is not set
405# CONFIG_NS83820 is not set
406# CONFIG_HAMACHI is not set
407# CONFIG_YELLOWFIN is not set
408# CONFIG_R8169 is not set
409# CONFIG_SIS190 is not set
410# CONFIG_SKGE is not set
411# CONFIG_SK98LIN is not set
412# CONFIG_VIA_VELOCITY is not set
413# CONFIG_TIGON3 is not set
414# CONFIG_BNX2 is not set
276CONFIG_GIANFAR=y 415CONFIG_GIANFAR=y
277# CONFIG_GFAR_NAPI is not set 416# CONFIG_GFAR_NAPI is not set
278 417
279# 418#
280# Ethernet (10000 Mbit) 419# Ethernet (10000 Mbit)
281# 420#
421# CONFIG_CHELSIO_T1 is not set
422# CONFIG_IXGB is not set
423# CONFIG_S2IO is not set
282 424
283# 425#
284# Token Ring devices 426# Token Ring devices
285# 427#
428# CONFIG_TR is not set
286 429
287# 430#
288# Wireless LAN (non-hamradio) 431# Wireless LAN (non-hamradio)
@@ -293,10 +436,14 @@ CONFIG_GIANFAR=y
293# Wan interfaces 436# Wan interfaces
294# 437#
295# CONFIG_WAN is not set 438# CONFIG_WAN is not set
439# CONFIG_FDDI is not set
440# CONFIG_HIPPI is not set
296# CONFIG_PPP is not set 441# CONFIG_PPP is not set
297# CONFIG_SLIP is not set 442# CONFIG_SLIP is not set
298# CONFIG_SHAPER is not set 443# CONFIG_SHAPER is not set
299# CONFIG_NETCONSOLE is not set 444# CONFIG_NETCONSOLE is not set
445# CONFIG_NETPOLL is not set
446# CONFIG_NET_POLL_CONTROLLER is not set
300 447
301# 448#
302# ISDN subsystem 449# ISDN subsystem
@@ -323,14 +470,6 @@ CONFIG_INPUT=y
323# CONFIG_INPUT_EVBUG is not set 470# CONFIG_INPUT_EVBUG is not set
324 471
325# 472#
326# Input I/O drivers
327#
328# CONFIG_GAMEPORT is not set
329CONFIG_SOUND_GAMEPORT=y
330# CONFIG_SERIO is not set
331# CONFIG_SERIO_I8042 is not set
332
333#
334# Input Device Drivers 473# Input Device Drivers
335# 474#
336# CONFIG_INPUT_KEYBOARD is not set 475# CONFIG_INPUT_KEYBOARD is not set
@@ -340,6 +479,12 @@ CONFIG_SOUND_GAMEPORT=y
340# CONFIG_INPUT_MISC is not set 479# CONFIG_INPUT_MISC is not set
341 480
342# 481#
482# Hardware I/O ports
483#
484# CONFIG_SERIO is not set
485# CONFIG_GAMEPORT is not set
486
487#
343# Character devices 488# Character devices
344# 489#
345# CONFIG_VT is not set 490# CONFIG_VT is not set
@@ -358,6 +503,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
358# 503#
359CONFIG_SERIAL_CORE=y 504CONFIG_SERIAL_CORE=y
360CONFIG_SERIAL_CORE_CONSOLE=y 505CONFIG_SERIAL_CORE_CONSOLE=y
506# CONFIG_SERIAL_JSM is not set
361CONFIG_UNIX98_PTYS=y 507CONFIG_UNIX98_PTYS=y
362CONFIG_LEGACY_PTYS=y 508CONFIG_LEGACY_PTYS=y
363CONFIG_LEGACY_PTY_COUNT=256 509CONFIG_LEGACY_PTY_COUNT=256
@@ -376,6 +522,7 @@ CONFIG_GEN_RTC=y
376# CONFIG_GEN_RTC_X is not set 522# CONFIG_GEN_RTC_X is not set
377# CONFIG_DTLK is not set 523# CONFIG_DTLK is not set
378# CONFIG_R3964 is not set 524# CONFIG_R3964 is not set
525# CONFIG_APPLICOM is not set
379 526
380# 527#
381# Ftape, the floppy tape device driver 528# Ftape, the floppy tape device driver
@@ -385,6 +532,12 @@ CONFIG_GEN_RTC=y
385# CONFIG_RAW_DRIVER is not set 532# CONFIG_RAW_DRIVER is not set
386 533
387# 534#
535# TPM devices
536#
537# CONFIG_TCG_TPM is not set
538# CONFIG_TELCLOCK is not set
539
540#
388# I2C support 541# I2C support
389# 542#
390CONFIG_I2C=y 543CONFIG_I2C=y
@@ -400,23 +553,68 @@ CONFIG_I2C_CHARDEV=y
400# 553#
401# I2C Hardware Bus support 554# I2C Hardware Bus support
402# 555#
403# CONFIG_I2C_ISA is not set 556# CONFIG_I2C_ALI1535 is not set
557# CONFIG_I2C_ALI1563 is not set
558# CONFIG_I2C_ALI15X3 is not set
559# CONFIG_I2C_AMD756 is not set
560# CONFIG_I2C_AMD8111 is not set
561# CONFIG_I2C_I801 is not set
562# CONFIG_I2C_I810 is not set
563# CONFIG_I2C_PIIX4 is not set
404CONFIG_I2C_MPC=y 564CONFIG_I2C_MPC=y
565# CONFIG_I2C_NFORCE2 is not set
405# CONFIG_I2C_PARPORT_LIGHT is not set 566# CONFIG_I2C_PARPORT_LIGHT is not set
567# CONFIG_I2C_PROSAVAGE is not set
568# CONFIG_I2C_SAVAGE4 is not set
569# CONFIG_SCx200_ACB is not set
570# CONFIG_I2C_SIS5595 is not set
571# CONFIG_I2C_SIS630 is not set
572# CONFIG_I2C_SIS96X is not set
573# CONFIG_I2C_VIA is not set
574# CONFIG_I2C_VIAPRO is not set
575# CONFIG_I2C_VOODOO3 is not set
406# CONFIG_I2C_PCA_ISA is not set 576# CONFIG_I2C_PCA_ISA is not set
407 577
408# 578#
409# Hardware Sensors Chip support 579# Miscellaneous I2C Chip support
580#
581# CONFIG_SENSORS_DS1337 is not set
582# CONFIG_SENSORS_DS1374 is not set
583# CONFIG_SENSORS_EEPROM is not set
584# CONFIG_SENSORS_PCF8574 is not set
585# CONFIG_SENSORS_PCA9539 is not set
586# CONFIG_SENSORS_PCF8591 is not set
587# CONFIG_SENSORS_RTC8564 is not set
588# CONFIG_SENSORS_M41T00 is not set
589# CONFIG_SENSORS_MAX6875 is not set
590# CONFIG_RTC_X1205_I2C is not set
591# CONFIG_I2C_DEBUG_CORE is not set
592# CONFIG_I2C_DEBUG_ALGO is not set
593# CONFIG_I2C_DEBUG_BUS is not set
594# CONFIG_I2C_DEBUG_CHIP is not set
595
596#
597# Dallas's 1-wire bus
598#
599# CONFIG_W1 is not set
600
601#
602# Hardware Monitoring support
410# 603#
411# CONFIG_I2C_SENSOR is not set 604CONFIG_HWMON=y
605# CONFIG_HWMON_VID is not set
412# CONFIG_SENSORS_ADM1021 is not set 606# CONFIG_SENSORS_ADM1021 is not set
413# CONFIG_SENSORS_ADM1025 is not set 607# CONFIG_SENSORS_ADM1025 is not set
414# CONFIG_SENSORS_ADM1026 is not set 608# CONFIG_SENSORS_ADM1026 is not set
415# CONFIG_SENSORS_ADM1031 is not set 609# CONFIG_SENSORS_ADM1031 is not set
610# CONFIG_SENSORS_ADM9240 is not set
416# CONFIG_SENSORS_ASB100 is not set 611# CONFIG_SENSORS_ASB100 is not set
612# CONFIG_SENSORS_ATXP1 is not set
417# CONFIG_SENSORS_DS1621 is not set 613# CONFIG_SENSORS_DS1621 is not set
418# CONFIG_SENSORS_FSCHER is not set 614# CONFIG_SENSORS_FSCHER is not set
615# CONFIG_SENSORS_FSCPOS is not set
419# CONFIG_SENSORS_GL518SM is not set 616# CONFIG_SENSORS_GL518SM is not set
617# CONFIG_SENSORS_GL520SM is not set
420# CONFIG_SENSORS_IT87 is not set 618# CONFIG_SENSORS_IT87 is not set
421# CONFIG_SENSORS_LM63 is not set 619# CONFIG_SENSORS_LM63 is not set
422# CONFIG_SENSORS_LM75 is not set 620# CONFIG_SENSORS_LM75 is not set
@@ -427,33 +625,26 @@ CONFIG_I2C_MPC=y
427# CONFIG_SENSORS_LM85 is not set 625# CONFIG_SENSORS_LM85 is not set
428# CONFIG_SENSORS_LM87 is not set 626# CONFIG_SENSORS_LM87 is not set
429# CONFIG_SENSORS_LM90 is not set 627# CONFIG_SENSORS_LM90 is not set
628# CONFIG_SENSORS_LM92 is not set
430# CONFIG_SENSORS_MAX1619 is not set 629# CONFIG_SENSORS_MAX1619 is not set
431# CONFIG_SENSORS_PC87360 is not set 630# CONFIG_SENSORS_PC87360 is not set
432# CONFIG_SENSORS_SMSC47B397 is not set 631# CONFIG_SENSORS_SIS5595 is not set
433# CONFIG_SENSORS_SMSC47M1 is not set 632# CONFIG_SENSORS_SMSC47M1 is not set
633# CONFIG_SENSORS_SMSC47B397 is not set
634# CONFIG_SENSORS_VIA686A is not set
434# CONFIG_SENSORS_W83781D is not set 635# CONFIG_SENSORS_W83781D is not set
636# CONFIG_SENSORS_W83792D is not set
435# CONFIG_SENSORS_W83L785TS is not set 637# CONFIG_SENSORS_W83L785TS is not set
436# CONFIG_SENSORS_W83627HF is not set 638# CONFIG_SENSORS_W83627HF is not set
639# CONFIG_SENSORS_W83627EHF is not set
640# CONFIG_HWMON_DEBUG_CHIP is not set
437 641
438# 642#
439# Other I2C Chip support 643# Misc devices
440#
441# CONFIG_SENSORS_EEPROM is not set
442# CONFIG_SENSORS_PCF8574 is not set
443# CONFIG_SENSORS_PCF8591 is not set
444# CONFIG_SENSORS_RTC8564 is not set
445# CONFIG_I2C_DEBUG_CORE is not set
446# CONFIG_I2C_DEBUG_ALGO is not set
447# CONFIG_I2C_DEBUG_BUS is not set
448# CONFIG_I2C_DEBUG_CHIP is not set
449
450#
451# Dallas's 1-wire bus
452# 644#
453# CONFIG_W1 is not set
454 645
455# 646#
456# Misc devices 647# Multimedia Capabilities Port drivers
457# 648#
458 649
459# 650#
@@ -479,11 +670,12 @@ CONFIG_I2C_MPC=y
479# 670#
480# USB support 671# USB support
481# 672#
482# CONFIG_USB_ARCH_HAS_HCD is not set 673CONFIG_USB_ARCH_HAS_HCD=y
483# CONFIG_USB_ARCH_HAS_OHCI is not set 674CONFIG_USB_ARCH_HAS_OHCI=y
675# CONFIG_USB is not set
484 676
485# 677#
486# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 678# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
487# 679#
488 680
489# 681#
@@ -502,10 +694,15 @@ CONFIG_I2C_MPC=y
502# CONFIG_INFINIBAND is not set 694# CONFIG_INFINIBAND is not set
503 695
504# 696#
697# SN Devices
698#
699
700#
505# File systems 701# File systems
506# 702#
507CONFIG_EXT2_FS=y 703CONFIG_EXT2_FS=y
508# CONFIG_EXT2_FS_XATTR is not set 704# CONFIG_EXT2_FS_XATTR is not set
705# CONFIG_EXT2_FS_XIP is not set
509CONFIG_EXT3_FS=y 706CONFIG_EXT3_FS=y
510CONFIG_EXT3_FS_XATTR=y 707CONFIG_EXT3_FS_XATTR=y
511# CONFIG_EXT3_FS_POSIX_ACL is not set 708# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -515,17 +712,16 @@ CONFIG_JBD=y
515CONFIG_FS_MBCACHE=y 712CONFIG_FS_MBCACHE=y
516# CONFIG_REISERFS_FS is not set 713# CONFIG_REISERFS_FS is not set
517# CONFIG_JFS_FS is not set 714# CONFIG_JFS_FS is not set
518 715# CONFIG_FS_POSIX_ACL is not set
519#
520# XFS support
521#
522# CONFIG_XFS_FS is not set 716# CONFIG_XFS_FS is not set
523# CONFIG_MINIX_FS is not set 717# CONFIG_MINIX_FS is not set
524# CONFIG_ROMFS_FS is not set 718# CONFIG_ROMFS_FS is not set
719CONFIG_INOTIFY=y
525# CONFIG_QUOTA is not set 720# CONFIG_QUOTA is not set
526CONFIG_DNOTIFY=y 721CONFIG_DNOTIFY=y
527# CONFIG_AUTOFS_FS is not set 722# CONFIG_AUTOFS_FS is not set
528# CONFIG_AUTOFS4_FS is not set 723# CONFIG_AUTOFS4_FS is not set
724# CONFIG_FUSE_FS is not set
529 725
530# 726#
531# CD-ROM/DVD Filesystems 727# CD-ROM/DVD Filesystems
@@ -546,12 +742,10 @@ CONFIG_DNOTIFY=y
546CONFIG_PROC_FS=y 742CONFIG_PROC_FS=y
547CONFIG_PROC_KCORE=y 743CONFIG_PROC_KCORE=y
548CONFIG_SYSFS=y 744CONFIG_SYSFS=y
549# CONFIG_DEVFS_FS is not set
550# CONFIG_DEVPTS_FS_XATTR is not set
551CONFIG_TMPFS=y 745CONFIG_TMPFS=y
552# CONFIG_TMPFS_XATTR is not set
553# CONFIG_HUGETLB_PAGE is not set 746# CONFIG_HUGETLB_PAGE is not set
554CONFIG_RAMFS=y 747CONFIG_RAMFS=y
748# CONFIG_RELAYFS_FS is not set
555 749
556# 750#
557# Miscellaneous filesystems 751# Miscellaneous filesystems
@@ -580,6 +774,7 @@ CONFIG_NFS_FS=y
580# CONFIG_NFSD is not set 774# CONFIG_NFSD is not set
581CONFIG_ROOT_NFS=y 775CONFIG_ROOT_NFS=y
582CONFIG_LOCKD=y 776CONFIG_LOCKD=y
777CONFIG_NFS_COMMON=y
583CONFIG_SUNRPC=y 778CONFIG_SUNRPC=y
584# CONFIG_RPCSEC_GSS_KRB5 is not set 779# CONFIG_RPCSEC_GSS_KRB5 is not set
585# CONFIG_RPCSEC_GSS_SPKM3 is not set 780# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -588,6 +783,7 @@ CONFIG_SUNRPC=y
588# CONFIG_NCP_FS is not set 783# CONFIG_NCP_FS is not set
589# CONFIG_CODA_FS is not set 784# CONFIG_CODA_FS is not set
590# CONFIG_AFS_FS is not set 785# CONFIG_AFS_FS is not set
786# CONFIG_9P_FS is not set
591 787
592# 788#
593# Partition Types 789# Partition Types
@@ -614,6 +810,7 @@ CONFIG_PARTITION_ADVANCED=y
614# Library routines 810# Library routines
615# 811#
616# CONFIG_CRC_CCITT is not set 812# CONFIG_CRC_CCITT is not set
813# CONFIG_CRC16 is not set
617CONFIG_CRC32=y 814CONFIG_CRC32=y
618# CONFIG_LIBCRC32C is not set 815# CONFIG_LIBCRC32C is not set
619 816
@@ -625,7 +822,9 @@ CONFIG_CRC32=y
625# 822#
626# Kernel hacking 823# Kernel hacking
627# 824#
825# CONFIG_PRINTK_TIME is not set
628# CONFIG_DEBUG_KERNEL is not set 826# CONFIG_DEBUG_KERNEL is not set
827CONFIG_LOG_BUF_SHIFT=14
629# CONFIG_SERIAL_TEXT_DEBUG is not set 828# CONFIG_SERIAL_TEXT_DEBUG is not set
630 829
631# 830#
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 76a55a438f23..17a4da65e275 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -12,7 +12,7 @@ extra-$(CONFIG_6xx) += idle_6xx.o
12extra-$(CONFIG_POWER4) += idle_power4.o 12extra-$(CONFIG_POWER4) += idle_power4.o
13extra-y += vmlinux.lds 13extra-y += vmlinux.lds
14 14
15obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ 15obj-y := entry.o traps.o idle.o time.o misc.o \
16 process.o align.o \ 16 process.o align.o \
17 setup.o \ 17 setup.o \
18 ppc_htab.o 18 ppc_htab.o
@@ -38,8 +38,7 @@ endif
38# These are here while we do the architecture merge 38# These are here while we do the architecture merge
39 39
40else 40else
41obj-y := irq.o idle.o \ 41obj-y := idle.o align.o
42 align.o
43obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o 42obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
44obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o 43obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
45obj-$(CONFIG_MODULES) += module.o 44obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c
index 968261d69572..fe0e767fb94e 100644
--- a/arch/ppc/kernel/asm-offsets.c
+++ b/arch/ppc/kernel/asm-offsets.c
@@ -25,6 +25,7 @@
25#include <asm/processor.h> 25#include <asm/processor.h>
26#include <asm/cputable.h> 26#include <asm/cputable.h>
27#include <asm/thread_info.h> 27#include <asm/thread_info.h>
28#include <asm/vdso_datapage.h>
28 29
29#define DEFINE(sym, val) \ 30#define DEFINE(sym, val) \
30 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 31 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -143,5 +144,32 @@ main(void)
143 144
144 DEFINE(TASK_SIZE, TASK_SIZE); 145 DEFINE(TASK_SIZE, TASK_SIZE);
145 DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); 146 DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
147
148 /* datapage offsets for use by vdso */
149 DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct vdso_data, tb_orig_stamp));
150 DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct vdso_data, tb_ticks_per_sec));
151 DEFINE(CFG_TB_TO_XS, offsetof(struct vdso_data, tb_to_xs));
152 DEFINE(CFG_STAMP_XSEC, offsetof(struct vdso_data, stamp_xsec));
153 DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct vdso_data, tb_update_count));
154 DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct vdso_data, tz_minuteswest));
155 DEFINE(CFG_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
156 DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32));
157 DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec));
158 DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
159 DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec));
160 DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec));
161 DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec));
162 DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
163
164 /* timeval/timezone offsets for use by vdso */
165 DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
166 DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
167
168 /* Other bits used by the vdso */
169 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
170 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
171 DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
172 DEFINE(CLOCK_REALTIME_RES, TICK_NSEC);
173
146 return 0; 174 return 0;
147} 175}
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index aeb349b47af3..f3d274c6b231 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -358,6 +358,6 @@ label:
358 NORMAL_EXCEPTION_PROLOG; \ 358 NORMAL_EXCEPTION_PROLOG; \
359 bne load_up_fpu; /* if from user, just load it up */ \ 359 bne load_up_fpu; /* if from user, just load it up */ \
360 addi r3,r1,STACK_FRAME_OVERHEAD; \ 360 addi r3,r1,STACK_FRAME_OVERHEAD; \
361 EXC_XFER_EE_LITE(0x800, KernelFP) 361 EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
362 362
363#endif /* __HEAD_BOOKE_H__ */ 363#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index 11e5b44713f7..821a75e45602 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -53,10 +53,6 @@ void default_idle(void)
53 } 53 }
54#endif 54#endif
55 } 55 }
56 if (need_resched())
57 schedule();
58 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
59 cpu_die();
60} 56}
61 57
62/* 58/*
@@ -64,11 +60,22 @@ void default_idle(void)
64 */ 60 */
65void cpu_idle(void) 61void cpu_idle(void)
66{ 62{
67 for (;;) 63 int cpu = smp_processor_id();
68 if (ppc_md.idle != NULL) 64
69 ppc_md.idle(); 65 for (;;) {
70 else 66 while (!need_resched()) {
71 default_idle(); 67 if (ppc_md.idle != NULL)
68 ppc_md.idle();
69 else
70 default_idle();
71 }
72
73 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
74 cpu_die();
75 preempt_enable_no_resched();
76 schedule();
77 preempt_disable();
78 }
72} 79}
73 80
74#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx) 81#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx)
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
deleted file mode 100644
index fbb2b9f8922c..000000000000
--- a/arch/ppc/kernel/irq.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * arch/ppc/kernel/irq.c
3 *
4 * Derived from arch/i386/kernel/irq.c
5 * Copyright (C) 1992 Linus Torvalds
6 * Adapted from arch/i386 by Gary Thomas
7 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
8 * Updated and modified by Cort Dougan <cort@fsmlabs.com>
9 * Copyright (C) 1996-2001 Cort Dougan
10 * Adapted for Power Macintosh by Paul Mackerras
11 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
12 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
13 *
14 * This file contains the code used by various IRQ handling routines:
15 * asking for different IRQ's should be done through these routines
16 * instead of just grabbing them. Thus setups with different IRQ numbers
17 * shouldn't result in any weird surprises, and installing new handlers
18 * should be easier.
19 *
20 * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the
21 * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit
22 * mask register (of which only 16 are defined), hence the weird shifting
23 * and complement of the cached_irq_mask. I want to be able to stuff
24 * this right into the SIU SMASK register.
25 * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
26 * to reduce code space and undefined function references.
27 */
28
29#include <linux/errno.h>
30#include <linux/module.h>
31#include <linux/threads.h>
32#include <linux/kernel_stat.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/ptrace.h>
36#include <linux/ioport.h>
37#include <linux/interrupt.h>
38#include <linux/timex.h>
39#include <linux/config.h>
40#include <linux/init.h>
41#include <linux/slab.h>
42#include <linux/pci.h>
43#include <linux/delay.h>
44#include <linux/irq.h>
45#include <linux/proc_fs.h>
46#include <linux/random.h>
47#include <linux/seq_file.h>
48#include <linux/cpumask.h>
49#include <linux/profile.h>
50#include <linux/bitops.h>
51
52#include <asm/uaccess.h>
53#include <asm/system.h>
54#include <asm/io.h>
55#include <asm/pgtable.h>
56#include <asm/irq.h>
57#include <asm/cache.h>
58#include <asm/prom.h>
59#include <asm/ptrace.h>
60#include <asm/machdep.h>
61
62#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
63
64extern atomic_t ipi_recv;
65extern atomic_t ipi_sent;
66
67#define MAXCOUNT 10000000
68
69int ppc_spurious_interrupts = 0;
70struct irqaction *ppc_irq_action[NR_IRQS];
71unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
72unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
73atomic_t ppc_n_lost_interrupts;
74
75#ifdef CONFIG_TAU_INT
76extern int tau_initialized;
77extern int tau_interrupts(int);
78#endif
79
80int show_interrupts(struct seq_file *p, void *v)
81{
82 int i = *(loff_t *) v, j;
83 struct irqaction * action;
84 unsigned long flags;
85
86 if (i == 0) {
87 seq_puts(p, " ");
88 for (j=0; j<NR_CPUS; j++)
89 if (cpu_online(j))
90 seq_printf(p, "CPU%d ", j);
91 seq_putc(p, '\n');
92 }
93
94 if (i < NR_IRQS) {
95 spin_lock_irqsave(&irq_desc[i].lock, flags);
96 action = irq_desc[i].action;
97 if ( !action || !action->handler )
98 goto skip;
99 seq_printf(p, "%3d: ", i);
100#ifdef CONFIG_SMP
101 for (j = 0; j < NR_CPUS; j++)
102 if (cpu_online(j))
103 seq_printf(p, "%10u ",
104 kstat_cpu(j).irqs[i]);
105#else
106 seq_printf(p, "%10u ", kstat_irqs(i));
107#endif /* CONFIG_SMP */
108 if (irq_desc[i].handler)
109 seq_printf(p, " %s ", irq_desc[i].handler->typename);
110 else
111 seq_puts(p, " None ");
112 seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge ");
113 seq_printf(p, " %s", action->name);
114 for (action = action->next; action; action = action->next)
115 seq_printf(p, ", %s", action->name);
116 seq_putc(p, '\n');
117skip:
118 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
119 } else if (i == NR_IRQS) {
120#ifdef CONFIG_TAU_INT
121 if (tau_initialized){
122 seq_puts(p, "TAU: ");
123 for (j = 0; j < NR_CPUS; j++)
124 if (cpu_online(j))
125 seq_printf(p, "%10u ", tau_interrupts(j));
126 seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
127 }
128#endif
129#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
130 /* should this be per processor send/receive? */
131 seq_printf(p, "IPI (recv/sent): %10u/%u\n",
132 atomic_read(&ipi_recv), atomic_read(&ipi_sent));
133#endif
134 seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
135 }
136 return 0;
137}
138
139void do_IRQ(struct pt_regs *regs)
140{
141 int irq, first = 1;
142 irq_enter();
143
144 /*
145 * Every platform is required to implement ppc_md.get_irq.
146 * This function will either return an irq number or -1 to
147 * indicate there are no more pending. But the first time
148 * through the loop this means there wasn't and IRQ pending.
149 * The value -2 is for buggy hardware and means that this IRQ
150 * has already been handled. -- Tom
151 */
152 while ((irq = ppc_md.get_irq(regs)) >= 0) {
153 __do_IRQ(irq, regs);
154 first = 0;
155 }
156 if (irq != -2 && first)
157 /* That's not SMP safe ... but who cares ? */
158 ppc_spurious_interrupts++;
159 irq_exit();
160}
161
162void __init init_IRQ(void)
163{
164 ppc_md.init_IRQ();
165}
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index ae6af29938a1..5e61124581d0 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -497,9 +497,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
497 * and invalidate the corresponding instruction cache blocks. 497 * and invalidate the corresponding instruction cache blocks.
498 * This is a no-op on the 601. 498 * This is a no-op on the 601.
499 * 499 *
500 * flush_icache_range(unsigned long start, unsigned long stop) 500 * __flush_icache_range(unsigned long start, unsigned long stop)
501 */ 501 */
502_GLOBAL(flush_icache_range) 502_GLOBAL(__flush_icache_range)
503BEGIN_FTR_SECTION 503BEGIN_FTR_SECTION
504 blr /* for 601, do nothing */ 504 blr /* for 601, do nothing */
505END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 505END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index e8f4e576750a..48ed58f995c0 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -62,20 +62,6 @@ struct pci_controller** hose_tail = &hose_head;
62static int pci_bus_count; 62static int pci_bus_count;
63 63
64static void 64static void
65fixup_rev1_53c810(struct pci_dev* dev)
66{
67 /* rev 1 ncr53c810 chips don't set the class at all which means
68 * they don't get their resources remapped. Fix that here.
69 */
70
71 if ((dev->class == PCI_CLASS_NOT_DEFINED)) {
72 printk("NCR 53c810 rev 1 detected, setting PCI class.\n");
73 dev->class = PCI_CLASS_STORAGE_SCSI;
74 }
75}
76DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
77
78static void
79fixup_broken_pcnet32(struct pci_dev* dev) 65fixup_broken_pcnet32(struct pci_dev* dev)
80{ 66{
81 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { 67 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index e0ca61b37f4f..66073f775193 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -46,6 +46,7 @@
46#include <asm/btext.h> 46#include <asm/btext.h>
47#include <asm/div64.h> 47#include <asm/div64.h>
48#include <asm/xmon.h> 48#include <asm/xmon.h>
49#include <asm/signal.h>
49 50
50#ifdef CONFIG_8xx 51#ifdef CONFIG_8xx
51#include <asm/commproc.h> 52#include <asm/commproc.h>
@@ -57,7 +58,6 @@ extern void machine_check_exception(struct pt_regs *regs);
57extern void alignment_exception(struct pt_regs *regs); 58extern void alignment_exception(struct pt_regs *regs);
58extern void program_check_exception(struct pt_regs *regs); 59extern void program_check_exception(struct pt_regs *regs);
59extern void single_step_exception(struct pt_regs *regs); 60extern void single_step_exception(struct pt_regs *regs);
60extern int do_signal(sigset_t *, struct pt_regs *);
61extern int pmac_newworld; 61extern int pmac_newworld;
62extern int sys_sigreturn(struct pt_regs *regs); 62extern int sys_sigreturn(struct pt_regs *regs);
63 63
@@ -78,7 +78,6 @@ EXPORT_SYMBOL(program_check_exception);
78EXPORT_SYMBOL(single_step_exception); 78EXPORT_SYMBOL(single_step_exception);
79EXPORT_SYMBOL(sys_sigreturn); 79EXPORT_SYMBOL(sys_sigreturn);
80EXPORT_SYMBOL(ppc_n_lost_interrupts); 80EXPORT_SYMBOL(ppc_n_lost_interrupts);
81EXPORT_SYMBOL(ppc_lost_interrupts);
82 81
83EXPORT_SYMBOL(ISA_DMA_THRESHOLD); 82EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
84EXPORT_SYMBOL(DMA_MODE_READ); 83EXPORT_SYMBOL(DMA_MODE_READ);
@@ -176,6 +175,7 @@ EXPORT_SYMBOL(pci_bus_to_phys);
176#endif /* CONFIG_PCI */ 175#endif /* CONFIG_PCI */
177 176
178#ifdef CONFIG_NOT_COHERENT_CACHE 177#ifdef CONFIG_NOT_COHERENT_CACHE
178extern void flush_dcache_all(void);
179EXPORT_SYMBOL(flush_dcache_all); 179EXPORT_SYMBOL(flush_dcache_all);
180#endif 180#endif
181 181
@@ -217,9 +217,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
217EXPORT_SYMBOL(cuda_request); 217EXPORT_SYMBOL(cuda_request);
218EXPORT_SYMBOL(cuda_poll); 218EXPORT_SYMBOL(cuda_poll);
219#endif /* CONFIG_ADB_CUDA */ 219#endif /* CONFIG_ADB_CUDA */
220#ifdef CONFIG_PPC_MULTIPLATFORM
221EXPORT_SYMBOL(_machine);
222#endif
223#ifdef CONFIG_PPC_PMAC 220#ifdef CONFIG_PPC_PMAC
224EXPORT_SYMBOL(sys_ctrler); 221EXPORT_SYMBOL(sys_ctrler);
225EXPORT_SYMBOL(pmac_newworld); 222EXPORT_SYMBOL(pmac_newworld);
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 6bcb85d2b7fd..dc55e1abc45b 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -76,6 +76,7 @@ unsigned int DMA_MODE_WRITE;
76 76
77#ifdef CONFIG_PPC_MULTIPLATFORM 77#ifdef CONFIG_PPC_MULTIPLATFORM
78int _machine = 0; 78int _machine = 0;
79EXPORT_SYMBOL(_machine);
79 80
80extern void prep_init(unsigned long r3, unsigned long r4, 81extern void prep_init(unsigned long r3, unsigned long r4,
81 unsigned long r5, unsigned long r6, unsigned long r7); 82 unsigned long r5, unsigned long r6, unsigned long r7);
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index bc5bf1124836..43b8fc2ca591 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -341,6 +341,7 @@ int __devinit start_secondary(void *unused)
341 cpu = smp_processor_id(); 341 cpu = smp_processor_id();
342 smp_store_cpu_info(cpu); 342 smp_store_cpu_info(cpu);
343 set_dec(tb_ticks_per_jiffy); 343 set_dec(tb_ticks_per_jiffy);
344 preempt_disable();
344 cpu_callin_map[cpu] = 1; 345 cpu_callin_map[cpu] = 1;
345 346
346 printk("CPU %d done callin...\n", cpu); 347 printk("CPU %d done callin...\n", cpu);
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 79b3f533d0a3..98edc75f4105 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -51,6 +51,9 @@
51 51
52#include <syslib/ppc83xx_setup.h> 52#include <syslib/ppc83xx_setup.h>
53 53
54static const char *GFAR_PHY_0 = "phy0:0";
55static const char *GFAR_PHY_1 = "phy0:1";
56
54#ifndef CONFIG_PCI 57#ifndef CONFIG_PCI
55unsigned long isa_io_base = 0; 58unsigned long isa_io_base = 0;
56unsigned long isa_mem_base = 0; 59unsigned long isa_mem_base = 0;
@@ -97,6 +100,7 @@ mpc834x_sys_setup_arch(void)
97 bd_t *binfo = (bd_t *) __res; 100 bd_t *binfo = (bd_t *) __res;
98 unsigned int freq; 101 unsigned int freq;
99 struct gianfar_platform_data *pdata; 102 struct gianfar_platform_data *pdata;
103 struct gianfar_mdio_data *mdata;
100 104
101 /* get the core frequency */ 105 /* get the core frequency */
102 freq = binfo->bi_intfreq; 106 freq = binfo->bi_intfreq;
@@ -111,24 +115,27 @@ mpc834x_sys_setup_arch(void)
111#endif 115#endif
112 mpc83xx_early_serial_map(); 116 mpc83xx_early_serial_map();
113 117
118 /* setup the board related info for the MDIO bus */
119 mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC83xx_MDIO);
120
121 mdata->irq[0] = MPC83xx_IRQ_EXT1;
122 mdata->irq[1] = MPC83xx_IRQ_EXT2;
123 mdata->irq[2] = -1;
124 mdata->irq[31] = -1;
125 mdata->paddr += binfo->bi_immr_base;
126
114 /* setup the board related information for the enet controllers */ 127 /* setup the board related information for the enet controllers */
115 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); 128 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
116 if (pdata) { 129 if (pdata) {
117 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; 130 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
118 pdata->interruptPHY = MPC83xx_IRQ_EXT1; 131 pdata->bus_id = GFAR_PHY_0;
119 pdata->phyid = 0;
120 /* fixup phy address */
121 pdata->phy_reg_addr += binfo->bi_immr_base;
122 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); 132 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
123 } 133 }
124 134
125 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); 135 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2);
126 if (pdata) { 136 if (pdata) {
127 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; 137 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
128 pdata->interruptPHY = MPC83xx_IRQ_EXT2; 138 pdata->bus_id = GFAR_PHY_1;
129 pdata->phyid = 1;
130 /* fixup phy address */
131 pdata->phy_reg_addr += binfo->bi_immr_base;
132 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); 139 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
133 } 140 }
134 141
diff --git a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h
index 95fdf4b0680b..7bcc6c35a417 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.h
+++ b/arch/ppc/platforms/85xx/stx_gp3.h
@@ -21,6 +21,7 @@
21 21
22#include <linux/config.h> 22#include <linux/config.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/seq_file.h>
24#include <asm/ppcboot.h> 25#include <asm/ppcboot.h>
25 26
26#define BOARD_CCSRBAR ((uint)0xe0000000) 27#define BOARD_CCSRBAR ((uint)0xe0000000)
diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
index 9f2d95ea8564..4742bf609357 100644
--- a/arch/ppc/platforms/pmac_pic.c
+++ b/arch/ppc/platforms/pmac_pic.c
@@ -75,6 +75,9 @@ static DEFINE_SPINLOCK(pmac_pic_lock);
75#define GATWICK_IRQ_POOL_SIZE 10 75#define GATWICK_IRQ_POOL_SIZE 10
76static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; 76static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
77 77
78#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
79static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
80
78/* 81/*
79 * Mark an irq as "lost". This is only used on the pmac 82 * Mark an irq as "lost". This is only used on the pmac
80 * since it can lose interrupts (see pmac_set_irq_mask). 83 * since it can lose interrupts (see pmac_set_irq_mask).
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index 067d7d53b81e..4415748071dc 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -61,6 +61,15 @@
61#include <asm/pci-bridge.h> 61#include <asm/pci-bridge.h>
62#include <asm/todc.h> 62#include <asm/todc.h>
63 63
64/* prep registers for L2 */
65#define CACHECRBA 0x80000823 /* Cache configuration register address */
66#define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */
67#define L2CACHE_512KB 0x00 /* 512KB */
68#define L2CACHE_256KB 0x01 /* 256KB */
69#define L2CACHE_1MB 0x02 /* 1MB */
70#define L2CACHE_NONE 0x03 /* NONE */
71#define L2CACHE_PARITY 0x08 /* Mask for L2 Cache Parity Protected bit */
72
64TODC_ALLOC(); 73TODC_ALLOC();
65 74
66unsigned char ucSystemType; 75unsigned char ucSystemType;
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 5bd33baac243..5b7f2b80e56e 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o
33obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o 33obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o
34ifeq ($(CONFIG_40x),y) 34ifeq ($(CONFIG_40x),y)
35obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o 35obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o
36obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
37endif 36endif
38endif 37endif
39obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ 38obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
@@ -96,6 +95,7 @@ obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
96ifeq ($(CONFIG_85xx),y) 95ifeq ($(CONFIG_85xx),y)
97obj-$(CONFIG_PCI) += pci_auto.o 96obj-$(CONFIG_PCI) += pci_auto.o
98endif 97endif
98obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
99obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \ 99obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \
100 mpc83xx_sys.o mpc83xx_devices.o 100 mpc83xx_sys.o mpc83xx_devices.o
101ifeq ($(CONFIG_83xx),y) 101ifeq ($(CONFIG_83xx),y)
diff --git a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c
index c867be6981cb..29d95d415ceb 100644
--- a/arch/ppc/syslib/cpm2_pic.c
+++ b/arch/ppc/syslib/cpm2_pic.c
@@ -37,7 +37,7 @@ static u_char irq_to_siureg[] = {
37static u_char irq_to_siubit[] = { 37static u_char irq_to_siubit[] = {
38 0, 15, 14, 13, 12, 11, 10, 9, 38 0, 15, 14, 13, 12, 11, 10, 9,
39 8, 7, 6, 5, 4, 3, 2, 1, 39 8, 7, 6, 5, 4, 3, 2, 1,
40 2, 1, 15, 14, 13, 12, 11, 10, 40 2, 1, 0, 14, 13, 12, 11, 10,
41 9, 8, 7, 6, 5, 4, 3, 0, 41 9, 8, 7, 6, 5, 4, 3, 0,
42 31, 30, 29, 28, 27, 26, 25, 24, 42 31, 30, 29, 28, 27, 26, 25, 24,
43 23, 22, 21, 20, 19, 18, 17, 16, 43 23, 22, 21, 20, 19, 18, 17, 16,
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index dbf8acac507f..f43fbf9a9389 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -27,18 +27,20 @@
27 * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup 27 * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup
28 */ 28 */
29 29
30struct gianfar_mdio_data mpc83xx_mdio_pdata = {
31 .paddr = 0x24520,
32};
33
30static struct gianfar_platform_data mpc83xx_tsec1_pdata = { 34static struct gianfar_platform_data mpc83xx_tsec1_pdata = {
31 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | 35 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
32 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | 36 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
33 FSL_GIANFAR_DEV_HAS_MULTI_INTR, 37 FSL_GIANFAR_DEV_HAS_MULTI_INTR,
34 .phy_reg_addr = 0x24000,
35}; 38};
36 39
37static struct gianfar_platform_data mpc83xx_tsec2_pdata = { 40static struct gianfar_platform_data mpc83xx_tsec2_pdata = {
38 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | 41 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
39 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | 42 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
40 FSL_GIANFAR_DEV_HAS_MULTI_INTR, 43 FSL_GIANFAR_DEV_HAS_MULTI_INTR,
41 .phy_reg_addr = 0x24000,
42}; 44};
43 45
44static struct fsl_i2c_platform_data mpc83xx_fsl_i2c1_pdata = { 46static struct fsl_i2c_platform_data mpc83xx_fsl_i2c1_pdata = {
@@ -220,6 +222,12 @@ struct platform_device ppc_sys_platform_devices[] = {
220 }, 222 },
221 }, 223 },
222 }, 224 },
225 [MPC83xx_MDIO] = {
226 .name = "fsl-gianfar_mdio",
227 .id = 0,
228 .dev.platform_data = &mpc83xx_mdio_pdata,
229 .num_resources = 0,
230 },
223}; 231};
224 232
225static int __init mach_mpc83xx_fixup(struct platform_device *pdev) 233static int __init mach_mpc83xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/mpc83xx_sys.c b/arch/ppc/syslib/mpc83xx_sys.c
index 29aa63350025..da743446789b 100644
--- a/arch/ppc/syslib/mpc83xx_sys.c
+++ b/arch/ppc/syslib/mpc83xx_sys.c
@@ -24,72 +24,72 @@ struct ppc_sys_spec ppc_sys_specs[] = {
24 .ppc_sys_name = "8349E", 24 .ppc_sys_name = "8349E",
25 .mask = 0xFFFF0000, 25 .mask = 0xFFFF0000,
26 .value = 0x80500000, 26 .value = 0x80500000,
27 .num_devices = 8, 27 .num_devices = 9,
28 .device_list = (enum ppc_sys_devices[]) 28 .device_list = (enum ppc_sys_devices[])
29 { 29 {
30 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 30 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
31 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2, 31 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
32 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 32 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
33 }, 33 },
34 }, 34 },
35 { 35 {
36 .ppc_sys_name = "8349", 36 .ppc_sys_name = "8349",
37 .mask = 0xFFFF0000, 37 .mask = 0xFFFF0000,
38 .value = 0x80510000, 38 .value = 0x80510000,
39 .num_devices = 7, 39 .num_devices = 8,
40 .device_list = (enum ppc_sys_devices[]) 40 .device_list = (enum ppc_sys_devices[])
41 { 41 {
42 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 42 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
43 MPC83xx_IIC2, MPC83xx_DUART, 43 MPC83xx_IIC2, MPC83xx_DUART,
44 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 44 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
45 }, 45 },
46 }, 46 },
47 { 47 {
48 .ppc_sys_name = "8347E", 48 .ppc_sys_name = "8347E",
49 .mask = 0xFFFF0000, 49 .mask = 0xFFFF0000,
50 .value = 0x80520000, 50 .value = 0x80520000,
51 .num_devices = 8, 51 .num_devices = 9,
52 .device_list = (enum ppc_sys_devices[]) 52 .device_list = (enum ppc_sys_devices[])
53 { 53 {
54 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 54 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
55 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2, 55 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
56 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 56 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
57 }, 57 },
58 }, 58 },
59 { 59 {
60 .ppc_sys_name = "8347", 60 .ppc_sys_name = "8347",
61 .mask = 0xFFFF0000, 61 .mask = 0xFFFF0000,
62 .value = 0x80530000, 62 .value = 0x80530000,
63 .num_devices = 7, 63 .num_devices = 8,
64 .device_list = (enum ppc_sys_devices[]) 64 .device_list = (enum ppc_sys_devices[])
65 { 65 {
66 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 66 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
67 MPC83xx_IIC2, MPC83xx_DUART, 67 MPC83xx_IIC2, MPC83xx_DUART,
68 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 68 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
69 }, 69 },
70 }, 70 },
71 { 71 {
72 .ppc_sys_name = "8343E", 72 .ppc_sys_name = "8343E",
73 .mask = 0xFFFF0000, 73 .mask = 0xFFFF0000,
74 .value = 0x80540000, 74 .value = 0x80540000,
75 .num_devices = 7, 75 .num_devices = 8,
76 .device_list = (enum ppc_sys_devices[]) 76 .device_list = (enum ppc_sys_devices[])
77 { 77 {
78 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 78 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
79 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2, 79 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
80 MPC83xx_USB2_DR, 80 MPC83xx_USB2_DR, MPC83xx_MDIO
81 }, 81 },
82 }, 82 },
83 { 83 {
84 .ppc_sys_name = "8343", 84 .ppc_sys_name = "8343",
85 .mask = 0xFFFF0000, 85 .mask = 0xFFFF0000,
86 .value = 0x80550000, 86 .value = 0x80550000,
87 .num_devices = 6, 87 .num_devices = 7,
88 .device_list = (enum ppc_sys_devices[]) 88 .device_list = (enum ppc_sys_devices[])
89 { 89 {
90 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 90 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
91 MPC83xx_IIC2, MPC83xx_DUART, 91 MPC83xx_IIC2, MPC83xx_DUART,
92 MPC83xx_USB2_DR, 92 MPC83xx_USB2_DR, MPC83xx_MDIO
93 }, 93 },
94 }, 94 },
95 { /* default match */ 95 { /* default match */
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
index 03b1fc9b9501..af4deace49e0 100644
--- a/arch/ppc/syslib/prom.c
+++ b/arch/ppc/syslib/prom.c
@@ -13,7 +13,6 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/version.h>
17#include <linux/threads.h> 16#include <linux/threads.h>
18#include <linux/spinlock.h> 17#include <linux/spinlock.h>
19#include <linux/ioport.h> 18#include <linux/ioport.h>
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
index 7f15136830f4..df14422ae1c6 100644
--- a/arch/ppc/syslib/prom_init.c
+++ b/arch/ppc/syslib/prom_init.c
@@ -9,7 +9,6 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/string.h> 10#include <linux/string.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/version.h>
13#include <linux/threads.h> 12#include <linux/threads.h>
14#include <linux/spinlock.h> 13#include <linux/spinlock.h>
15#include <linux/ioport.h> 14#include <linux/ioport.h>
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index 29552348e581..9d10c12e87fe 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -279,17 +279,12 @@ config ARCH_FLATMEM_ENABLE
279 def_bool y 279 def_bool y
280 depends on !NUMA 280 depends on !NUMA
281 281
282config ARCH_DISCONTIGMEM_ENABLE 282config ARCH_SPARSEMEM_ENABLE
283 def_bool y
284 depends on SMP && PPC_PSERIES
285
286config ARCH_DISCONTIGMEM_DEFAULT
287 def_bool y 283 def_bool y
288 depends on ARCH_DISCONTIGMEM_ENABLE
289 284
290config ARCH_SPARSEMEM_ENABLE 285config ARCH_SPARSEMEM_DEFAULT
291 def_bool y 286 def_bool y
292 depends on ARCH_DISCONTIGMEM_ENABLE 287 depends on NUMA
293 288
294source "mm/Kconfig" 289source "mm/Kconfig"
295 290
@@ -297,6 +292,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
297 def_bool y 292 def_bool y
298 depends on NEED_MULTIPLE_NODES 293 depends on NEED_MULTIPLE_NODES
299 294
295config ARCH_MEMORY_PROBE
296 def_bool y
297 depends on MEMORY_HOTPLUG
298
300# Some NUMA nodes have memory ranges that span 299# Some NUMA nodes have memory ranges that span
301# other nodes. Even though a pfn is valid and 300# other nodes. Even though a pfn is valid and
302# between a node's start and end pfns, it may not 301# between a node's start and end pfns, it may not
diff --git a/arch/ppc64/boot/addRamDisk.c b/arch/ppc64/boot/addRamDisk.c
index 7f2c09473394..c02a99952be7 100644
--- a/arch/ppc64/boot/addRamDisk.c
+++ b/arch/ppc64/boot/addRamDisk.c
@@ -5,11 +5,59 @@
5#include <sys/types.h> 5#include <sys/types.h>
6#include <sys/stat.h> 6#include <sys/stat.h>
7#include <string.h> 7#include <string.h>
8#include <elf.h>
8 9
9#define ElfHeaderSize (64 * 1024) 10#define ElfHeaderSize (64 * 1024)
10#define ElfPages (ElfHeaderSize / 4096) 11#define ElfPages (ElfHeaderSize / 4096)
11#define KERNELBASE (0xc000000000000000) 12#define KERNELBASE (0xc000000000000000)
13#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
12 14
15struct addr_range {
16 unsigned long long addr;
17 unsigned long memsize;
18 unsigned long offset;
19};
20
21static int check_elf64(void *p, int size, struct addr_range *r)
22{
23 Elf64_Ehdr *elf64 = p;
24 Elf64_Phdr *elf64ph;
25
26 if (elf64->e_ident[EI_MAG0] != ELFMAG0 ||
27 elf64->e_ident[EI_MAG1] != ELFMAG1 ||
28 elf64->e_ident[EI_MAG2] != ELFMAG2 ||
29 elf64->e_ident[EI_MAG3] != ELFMAG3 ||
30 elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
31 elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
32 elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64)
33 return 0;
34
35 if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size)
36 return 0;
37
38 elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 +
39 (unsigned long)elf64->e_phoff);
40
41 r->memsize = (unsigned long)elf64ph->p_memsz;
42 r->offset = (unsigned long)elf64ph->p_offset;
43 r->addr = (unsigned long long)elf64ph->p_vaddr;
44
45#ifdef DEBUG
46 printf("PPC64 ELF file, ph:\n");
47 printf("p_type 0x%08x\n", elf64ph->p_type);
48 printf("p_flags 0x%08x\n", elf64ph->p_flags);
49 printf("p_offset 0x%016llx\n", elf64ph->p_offset);
50 printf("p_vaddr 0x%016llx\n", elf64ph->p_vaddr);
51 printf("p_paddr 0x%016llx\n", elf64ph->p_paddr);
52 printf("p_filesz 0x%016llx\n", elf64ph->p_filesz);
53 printf("p_memsz 0x%016llx\n", elf64ph->p_memsz);
54 printf("p_align 0x%016llx\n", elf64ph->p_align);
55 printf("... skipping 0x%08lx bytes of ELF header\n",
56 (unsigned long)elf64ph->p_offset);
57#endif
58
59 return 64;
60}
13void get4k(FILE *file, char *buf ) 61void get4k(FILE *file, char *buf )
14{ 62{
15 unsigned j; 63 unsigned j;
@@ -34,97 +82,92 @@ void death(const char *msg, FILE *fdesc, const char *fname)
34int main(int argc, char **argv) 82int main(int argc, char **argv)
35{ 83{
36 char inbuf[4096]; 84 char inbuf[4096];
37 FILE *ramDisk = NULL; 85 struct addr_range vmlinux;
38 FILE *sysmap = NULL; 86 FILE *ramDisk;
39 FILE *inputVmlinux = NULL; 87 FILE *inputVmlinux;
40 FILE *outputVmlinux = NULL; 88 FILE *outputVmlinux;
41 89
42 unsigned i = 0; 90 char *rd_name, *lx_name, *out_name;
43 unsigned long ramFileLen = 0; 91
44 unsigned long ramLen = 0; 92 size_t i;
45 unsigned long roundR = 0; 93 unsigned long ramFileLen;
46 94 unsigned long ramLen;
47 unsigned long sysmapFileLen = 0; 95 unsigned long roundR;
48 unsigned long sysmapLen = 0; 96 unsigned long offset_end;
49 unsigned long sysmapPages = 0; 97
50 char* ptr_end = NULL; 98 unsigned long kernelLen;
51 unsigned long offset_end = 0; 99 unsigned long actualKernelLen;
52 100 unsigned long round;
53 unsigned long kernelLen = 0; 101 unsigned long roundedKernelLen;
54 unsigned long actualKernelLen = 0; 102 unsigned long ramStartOffs;
55 unsigned long round = 0; 103 unsigned long ramPages;
56 unsigned long roundedKernelLen = 0; 104 unsigned long roundedKernelPages;
57 unsigned long ramStartOffs = 0; 105 unsigned long hvReleaseData;
58 unsigned long ramPages = 0;
59 unsigned long roundedKernelPages = 0;
60 unsigned long hvReleaseData = 0;
61 u_int32_t eyeCatcher = 0xc8a5d9c4; 106 u_int32_t eyeCatcher = 0xc8a5d9c4;
62 unsigned long naca = 0; 107 unsigned long naca;
63 unsigned long xRamDisk = 0; 108 unsigned long xRamDisk;
64 unsigned long xRamDiskSize = 0; 109 unsigned long xRamDiskSize;
65 long padPages = 0; 110 long padPages;
66 111
67 112
68 if (argc < 2) { 113 if (argc < 2) {
69 fprintf(stderr, "Name of RAM disk file missing.\n"); 114 fprintf(stderr, "Name of RAM disk file missing.\n");
70 exit(1); 115 exit(1);
71 } 116 }
117 rd_name = argv[1];
72 118
73 if (argc < 3) { 119 if (argc < 3) {
74 fprintf(stderr, "Name of System Map input file is missing.\n");
75 exit(1);
76 }
77
78 if (argc < 4) {
79 fprintf(stderr, "Name of vmlinux file missing.\n"); 120 fprintf(stderr, "Name of vmlinux file missing.\n");
80 exit(1); 121 exit(1);
81 } 122 }
123 lx_name = argv[2];
82 124
83 if (argc < 5) { 125 if (argc < 4) {
84 fprintf(stderr, "Name of vmlinux output file missing.\n"); 126 fprintf(stderr, "Name of vmlinux output file missing.\n");
85 exit(1); 127 exit(1);
86 } 128 }
129 out_name = argv[3];
87 130
88 131
89 ramDisk = fopen(argv[1], "r"); 132 ramDisk = fopen(rd_name, "r");
90 if ( ! ramDisk ) { 133 if ( ! ramDisk ) {
91 fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", argv[1]); 134 fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", rd_name);
92 exit(1); 135 exit(1);
93 } 136 }
94 137
95 sysmap = fopen(argv[2], "r"); 138 inputVmlinux = fopen(lx_name, "r");
96 if ( ! sysmap ) {
97 fprintf(stderr, "System Map file \"%s\" failed to open.\n", argv[2]);
98 exit(1);
99 }
100
101 inputVmlinux = fopen(argv[3], "r");
102 if ( ! inputVmlinux ) { 139 if ( ! inputVmlinux ) {
103 fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", argv[3]); 140 fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name);
104 exit(1); 141 exit(1);
105 } 142 }
106 143
107 outputVmlinux = fopen(argv[4], "w+"); 144 outputVmlinux = fopen(out_name, "w+");
108 if ( ! outputVmlinux ) { 145 if ( ! outputVmlinux ) {
109 fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", argv[4]); 146 fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name);
110 exit(1); 147 exit(1);
111 } 148 }
112 149
113 150 i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux);
114 151 if (i != sizeof(inbuf)) {
152 fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i);
153 exit(1);
154 }
155
156 i = check_elf64(inbuf, sizeof(inbuf), &vmlinux);
157 if (i == 0) {
158 fprintf(stderr, "You must have a linux kernel specified as argv[2]\n");
159 exit(1);
160 }
161
115 /* Input Vmlinux file */ 162 /* Input Vmlinux file */
116 fseek(inputVmlinux, 0, SEEK_END); 163 fseek(inputVmlinux, 0, SEEK_END);
117 kernelLen = ftell(inputVmlinux); 164 kernelLen = ftell(inputVmlinux);
118 fseek(inputVmlinux, 0, SEEK_SET); 165 fseek(inputVmlinux, 0, SEEK_SET);
119 printf("kernel file size = %d\n", kernelLen); 166 printf("kernel file size = %lu\n", kernelLen);
120 if ( kernelLen == 0 ) {
121 fprintf(stderr, "You must have a linux kernel specified as argv[3]\n");
122 exit(1);
123 }
124 167
125 actualKernelLen = kernelLen - ElfHeaderSize; 168 actualKernelLen = kernelLen - ElfHeaderSize;
126 169
127 printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); 170 printf("actual kernel length (minus ELF header) = %lu\n", actualKernelLen);
128 171
129 round = actualKernelLen % 4096; 172 round = actualKernelLen % 4096;
130 roundedKernelLen = actualKernelLen; 173 roundedKernelLen = actualKernelLen;
@@ -134,39 +177,7 @@ int main(int argc, char **argv)
134 roundedKernelPages = roundedKernelLen / 4096; 177 roundedKernelPages = roundedKernelLen / 4096;
135 printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages); 178 printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages);
136 179
137 180 offset_end = _ALIGN_UP(vmlinux.memsize, 4096);
138
139 /* Input System Map file */
140 /* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */
141 fseek(sysmap, 0, SEEK_END);
142 sysmapFileLen = ftell(sysmap);
143 fseek(sysmap, 0, SEEK_SET);
144 printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen);
145
146 sysmapLen = sysmapFileLen;
147
148 roundR = 4096 - (sysmapLen % 4096);
149 if (roundR) {
150 printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
151 sysmapLen += roundR;
152 }
153 printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen);
154
155 /* Process the Sysmap file to determine where _end is */
156 sysmapPages = sysmapLen / 4096;
157 /* read the whole file line by line, expect that it doesn't fail */
158 while ( fgets(inbuf, 4096, sysmap) ) ;
159 /* search for _end in the last page of the system map */
160 ptr_end = strstr(inbuf, " _end");
161 if (!ptr_end) {
162 fprintf(stderr, "Unable to find _end in the sysmap file \n");
163 fprintf(stderr, "inbuf: \n");
164 fprintf(stderr, "%s \n", inbuf);
165 exit(1);
166 }
167 printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10);
168 /* convert address of _end in system map to hex offset. */
169 offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16);
170 /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */ 181 /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */
171 padPages = offset_end/4096 - roundedKernelPages; 182 padPages = offset_end/4096 - roundedKernelPages;
172 183
@@ -194,7 +205,7 @@ int main(int argc, char **argv)
194 fseek(ramDisk, 0, SEEK_END); 205 fseek(ramDisk, 0, SEEK_END);
195 ramFileLen = ftell(ramDisk); 206 ramFileLen = ftell(ramDisk);
196 fseek(ramDisk, 0, SEEK_SET); 207 fseek(ramDisk, 0, SEEK_SET);
197 printf("%s file size = %ld/0x%lx \n", argv[1], ramFileLen, ramFileLen); 208 printf("%s file size = %ld/0x%lx \n", rd_name, ramFileLen, ramFileLen);
198 209
199 ramLen = ramFileLen; 210 ramLen = ramFileLen;
200 211
@@ -248,19 +259,19 @@ int main(int argc, char **argv)
248 /* fseek to the hvReleaseData pointer */ 259 /* fseek to the hvReleaseData pointer */
249 fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); 260 fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET);
250 if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { 261 if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) {
251 death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[4]); 262 death("Could not read hvReleaseData pointer\n", outputVmlinux, out_name);
252 } 263 }
253 hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ 264 hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */
254 printf("hvReleaseData is at %08x\n", hvReleaseData); 265 printf("hvReleaseData is at %08lx\n", hvReleaseData);
255 266
256 /* fseek to the hvReleaseData */ 267 /* fseek to the hvReleaseData */
257 fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); 268 fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET);
258 if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { 269 if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) {
259 death("Could not read hvReleaseData\n", outputVmlinux, argv[4]); 270 death("Could not read hvReleaseData\n", outputVmlinux, out_name);
260 } 271 }
261 /* Check hvReleaseData sanity */ 272 /* Check hvReleaseData sanity */
262 if (memcmp(inbuf, &eyeCatcher, 4) != 0) { 273 if (memcmp(inbuf, &eyeCatcher, 4) != 0) {
263 death("hvReleaseData is invalid\n", outputVmlinux, argv[4]); 274 death("hvReleaseData is invalid\n", outputVmlinux, out_name);
264 } 275 }
265 /* Get the naca pointer */ 276 /* Get the naca pointer */
266 naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE; 277 naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE;
@@ -269,13 +280,13 @@ int main(int argc, char **argv)
269 /* fseek to the naca */ 280 /* fseek to the naca */
270 fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); 281 fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
271 if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { 282 if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) {
272 death("Could not read naca\n", outputVmlinux, argv[4]); 283 death("Could not read naca\n", outputVmlinux, out_name);
273 } 284 }
274 xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); 285 xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c]));
275 xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); 286 xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14]));
276 /* Make sure a RAM disk isn't already present */ 287 /* Make sure a RAM disk isn't already present */
277 if ((xRamDisk != 0) || (xRamDiskSize != 0)) { 288 if ((xRamDisk != 0) || (xRamDiskSize != 0)) {
278 death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[4]); 289 death("RAM disk is already attached to this kernel\n", outputVmlinux, out_name);
279 } 290 }
280 /* Fill in the values */ 291 /* Fill in the values */
281 *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); 292 *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs);
@@ -285,15 +296,15 @@ int main(int argc, char **argv)
285 fflush(outputVmlinux); 296 fflush(outputVmlinux);
286 fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); 297 fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
287 if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { 298 if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) {
288 death("Could not write naca\n", outputVmlinux, argv[4]); 299 death("Could not write naca\n", outputVmlinux, out_name);
289 } 300 }
290 printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08x\n", 301 printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08lx\n",
291 ramPages, ramStartOffs); 302 ramPages, ramStartOffs);
292 303
293 /* Done */ 304 /* Done */
294 fclose(outputVmlinux); 305 fclose(outputVmlinux);
295 /* Set permission to executable */ 306 /* Set permission to executable */
296 chmod(argv[4], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); 307 chmod(out_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
297 308
298 return 0; 309 return 0;
299} 310}
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index c441aebe7648..dac4cc20fa93 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -11,13 +11,10 @@ obj-y := misc.o prom.o
11 11
12endif 12endif
13 13
14obj-y += irq.o idle.o dma.o \ 14obj-y += idle.o dma.o \
15 align.o pacaData.o \ 15 align.o \
16 udbg.o ioctl32.o \
17 rtc.o \ 16 rtc.o \
18 cpu_setup_power4.o \ 17 iommu.o
19 iommu.o sysfs.o vdso.o firmware.o
20obj-y += vdso32/ vdso64/
21 18
22pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o 19pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
23 20
@@ -28,32 +25,19 @@ ifneq ($(CONFIG_PPC_MERGE),y)
28obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 25obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
29endif 26endif
30 27
31obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
32
33obj-$(CONFIG_KEXEC) += machine_kexec.o 28obj-$(CONFIG_KEXEC) += machine_kexec.o
34obj-$(CONFIG_EEH) += eeh.o
35obj-$(CONFIG_PROC_FS) += proc_ppc64.o
36obj-$(CONFIG_MODULES) += module.o 29obj-$(CONFIG_MODULES) += module.o
37ifneq ($(CONFIG_PPC_MERGE),y) 30ifneq ($(CONFIG_PPC_MERGE),y)
38obj-$(CONFIG_MODULES) += ppc_ksyms.o 31obj-$(CONFIG_MODULES) += ppc_ksyms.o
39endif 32endif
40obj-$(CONFIG_PPC_RTAS) += rtas_pci.o
41obj-$(CONFIG_SCANLOG) += scanlog.o
42obj-$(CONFIG_LPARCFG) += lparcfg.o
43obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o 33obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
44ifneq ($(CONFIG_PPC_MERGE),y) 34ifneq ($(CONFIG_PPC_MERGE),y)
45obj-$(CONFIG_BOOTX_TEXT) += btext.o 35obj-$(CONFIG_BOOTX_TEXT) += btext.o
46endif 36endif
47obj-$(CONFIG_HVCS) += hvcserver.o 37obj-$(CONFIG_HVCS) += hvcserver.o
48 38
49obj-$(CONFIG_PPC_PMAC) += udbg_scc.o
50
51obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
52
53obj-$(CONFIG_KPROBES) += kprobes.o 39obj-$(CONFIG_KPROBES) += kprobes.o
54 40
55CFLAGS_ioctl32.o += -Ifs/
56
57ifneq ($(CONFIG_PPC_MERGE),y) 41ifneq ($(CONFIG_PPC_MERGE),y)
58ifeq ($(CONFIG_PPC_ISERIES),y) 42ifeq ($(CONFIG_PPC_ISERIES),y)
59arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s 43arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index bce9065da6cb..84ab5c18ef52 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -74,7 +74,6 @@ int main(void)
74 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); 74 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
75 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); 75 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
76 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); 76 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
77 DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
78 DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); 77 DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
79 78
80 /* paca */ 79 /* paca */
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 9e8050ea1225..1c869ea72d28 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -28,7 +28,6 @@
28#include <asm/processor.h> 28#include <asm/processor.h>
29#include <asm/page.h> 29#include <asm/page.h>
30#include <asm/mmu.h> 30#include <asm/mmu.h>
31#include <asm/systemcfg.h>
32#include <asm/ppc_asm.h> 31#include <asm/ppc_asm.h>
33#include <asm/asm-offsets.h> 32#include <asm/asm-offsets.h>
34#include <asm/bug.h> 33#include <asm/bug.h>
@@ -1701,21 +1700,9 @@ _GLOBAL(__secondary_start)
1701 HMT_MEDIUM /* Set thread priority to MEDIUM */ 1700 HMT_MEDIUM /* Set thread priority to MEDIUM */
1702 1701
1703 ld r2,PACATOC(r13) 1702 ld r2,PACATOC(r13)
1704 li r6,0 1703
1705 stb r6,PACAPROCENABLED(r13) 1704 /* Do early setup for that CPU */
1706 1705 bl .early_setup_secondary
1707#ifndef CONFIG_PPC_ISERIES
1708 /* Initialize the page table pointer register. */
1709 LOADADDR(r6,_SDR1)
1710 ld r6,0(r6) /* get the value of _SDR1 */
1711 mtspr SPRN_SDR1,r6 /* set the htab location */
1712#endif
1713 /* Initialize the first segment table (or SLB) entry */
1714 ld r3,PACASTABVIRT(r13) /* get addr of segment table */
1715BEGIN_FTR_SECTION
1716 bl .stab_initialize
1717END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1718 bl .slb_initialize
1719 1706
1720 /* Initialize the kernel stack. Just a repeat for iSeries. */ 1707 /* Initialize the kernel stack. Just a repeat for iSeries. */
1721 LOADADDR(r3,current_set) 1708 LOADADDR(r3,current_set)
@@ -1724,37 +1711,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
1724 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD 1711 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1725 std r1,PACAKSAVE(r13) 1712 std r1,PACAKSAVE(r13)
1726 1713
1727 ld r3,PACASTABREAL(r13) /* get raddr of segment table */
1728 ori r4,r3,1 /* turn on valid bit */
1729
1730#ifdef CONFIG_PPC_ISERIES
1731 li r0,-1 /* hypervisor call */
1732 li r3,1
1733 sldi r3,r3,63 /* 0x8000000000000000 */
1734 ori r3,r3,4 /* 0x8000000000000004 */
1735 sc /* HvCall_setASR */
1736#else
1737 /* set the ASR */
1738 ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
1739 ld r3,0(r3)
1740 lwz r3,PLATFORM(r3) /* r3 = platform flags */
1741 andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
1742 beq 98f /* branch if result is 0 */
1743 mfspr r3,SPRN_PVR
1744 srwi r3,r3,16
1745 cmpwi r3,0x37 /* SStar */
1746 beq 97f
1747 cmpwi r3,0x36 /* IStar */
1748 beq 97f
1749 cmpwi r3,0x34 /* Pulsar */
1750 bne 98f
175197: li r3,H_SET_ASR /* hcall = H_SET_ASR */
1752 HVSC /* Invoking hcall */
1753 b 99f
175498: /* !(rpa hypervisor) || !(star) */
1755 mtasr r4 /* set the stab location */
175699:
1757#endif
1758 li r7,0 1714 li r7,0
1759 mtlr r7 1715 mtlr r7
1760 1716
@@ -1896,40 +1852,6 @@ _STATIC(start_here_multiplatform)
1896 mr r3,r31 1852 mr r3,r31
1897 bl .early_setup 1853 bl .early_setup
1898 1854
1899 /* set the ASR */
1900 ld r3,PACASTABREAL(r13)
1901 ori r4,r3,1 /* turn on valid bit */
1902 ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
1903 ld r3,0(r3)
1904 lwz r3,PLATFORM(r3) /* r3 = platform flags */
1905 andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
1906 beq 98f /* branch if result is 0 */
1907 mfspr r3,SPRN_PVR
1908 srwi r3,r3,16
1909 cmpwi r3,0x37 /* SStar */
1910 beq 97f
1911 cmpwi r3,0x36 /* IStar */
1912 beq 97f
1913 cmpwi r3,0x34 /* Pulsar */
1914 bne 98f
191597: li r3,H_SET_ASR /* hcall = H_SET_ASR */
1916 HVSC /* Invoking hcall */
1917 b 99f
191898: /* !(rpa hypervisor) || !(star) */
1919 mtasr r4 /* set the stab location */
192099:
1921 /* Set SDR1 (hash table pointer) */
1922 ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
1923 ld r3,0(r3)
1924 lwz r3,PLATFORM(r3) /* r3 = platform flags */
1925 /* Test if bit 0 is set (LPAR bit) */
1926 andi. r3,r3,PLATFORM_LPAR
1927 bne 98f /* branch if result is !0 */
1928 LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
1929 sub r6,r6,r26
1930 ld r6,0(r6) /* get the value of _SDR1 */
1931 mtspr SPRN_SDR1,r6 /* set the htab location */
193298:
1933 LOADADDR(r3,.start_here_common) 1855 LOADADDR(r3,.start_here_common)
1934 SET_REG_TO_CONST(r4, MSR_KERNEL) 1856 SET_REG_TO_CONST(r4, MSR_KERNEL)
1935 mtspr SPRN_SRR0,r3 1857 mtspr SPRN_SRR0,r3
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 8fec27469802..b879d3057ef8 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -26,7 +26,6 @@
26#include <asm/processor.h> 26#include <asm/processor.h>
27#include <asm/cputable.h> 27#include <asm/cputable.h>
28#include <asm/time.h> 28#include <asm/time.h>
29#include <asm/systemcfg.h>
30#include <asm/machdep.h> 29#include <asm/machdep.h>
31#include <asm/smp.h> 30#include <asm/smp.h>
32 31
@@ -34,15 +33,11 @@ extern void power4_idle(void);
34 33
35void default_idle(void) 34void default_idle(void)
36{ 35{
37 long oldval;
38 unsigned int cpu = smp_processor_id(); 36 unsigned int cpu = smp_processor_id();
37 set_thread_flag(TIF_POLLING_NRFLAG);
39 38
40 while (1) { 39 while (1) {
41 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 40 if (!need_resched()) {
42
43 if (!oldval) {
44 set_thread_flag(TIF_POLLING_NRFLAG);
45
46 while (!need_resched() && !cpu_is_offline(cpu)) { 41 while (!need_resched() && !cpu_is_offline(cpu)) {
47 ppc64_runlatch_off(); 42 ppc64_runlatch_off();
48 43
@@ -55,13 +50,12 @@ void default_idle(void)
55 } 50 }
56 51
57 HMT_medium(); 52 HMT_medium();
58 clear_thread_flag(TIF_POLLING_NRFLAG);
59 } else {
60 set_need_resched();
61 } 53 }
62 54
63 ppc64_runlatch_on(); 55 ppc64_runlatch_on();
56 preempt_enable_no_resched();
64 schedule(); 57 schedule();
58 preempt_disable();
65 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 59 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
66 cpu_die(); 60 cpu_die();
67 } 61 }
@@ -77,7 +71,9 @@ void native_idle(void)
77 71
78 if (need_resched()) { 72 if (need_resched()) {
79 ppc64_runlatch_on(); 73 ppc64_runlatch_on();
74 preempt_enable_no_resched();
80 schedule(); 75 schedule();
76 preempt_disable();
81 } 77 }
82 78
83 if (cpu_is_offline(smp_processor_id()) && 79 if (cpu_is_offline(smp_processor_id()) &&
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index 914632ec587d..5e089deb0a2b 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -78,12 +78,12 @@ _GLOBAL(call_do_softirq)
78 mtlr r0 78 mtlr r0
79 blr 79 blr
80 80
81_GLOBAL(call_handle_IRQ_event) 81_GLOBAL(call___do_IRQ)
82 mflr r0 82 mflr r0
83 std r0,16(r1) 83 std r0,16(r1)
84 stdu r1,THREAD_SIZE-112(r6) 84 stdu r1,THREAD_SIZE-112(r5)
85 mr r1,r6 85 mr r1,r5
86 bl .handle_IRQ_event 86 bl .__do_IRQ
87 ld r1,0(r1) 87 ld r1,0(r1)
88 ld r0,16(r1) 88 ld r0,16(r1)
89 mtlr r0 89 mtlr r0
@@ -186,7 +186,8 @@ _KPROBE(__flush_icache_range)
186 bdnz 2b 186 bdnz 2b
187 isync 187 isync
188 blr 188 blr
189 .previous .text 189
190 .text
190/* 191/*
191 * Like above, but only do the D-cache. 192 * Like above, but only do the D-cache.
192 * 193 *
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
index 4fb1a9f5060d..c0fcd29918ce 100644
--- a/arch/ppc64/kernel/nvram.c
+++ b/arch/ppc64/kernel/nvram.c
@@ -31,7 +31,6 @@
31#include <asm/rtas.h> 31#include <asm/rtas.h>
32#include <asm/prom.h> 32#include <asm/prom.h>
33#include <asm/machdep.h> 33#include <asm/machdep.h>
34#include <asm/systemcfg.h>
35 34
36#undef DEBUG_NVRAM 35#undef DEBUG_NVRAM
37 36
@@ -167,7 +166,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file,
167 case IOC_NVRAM_GET_OFFSET: { 166 case IOC_NVRAM_GET_OFFSET: {
168 int part, offset; 167 int part, offset;
169 168
170 if (systemcfg->platform != PLATFORM_POWERMAC) 169 if (_machine != PLATFORM_POWERMAC)
171 return -EINVAL; 170 return -EINVAL;
172 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) 171 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
173 return -EFAULT; 172 return -EFAULT;
@@ -450,7 +449,7 @@ static int nvram_setup_partition(void)
450 * in our nvram, as Apple defined partitions use pretty much 449 * in our nvram, as Apple defined partitions use pretty much
451 * all of the space 450 * all of the space
452 */ 451 */
453 if (systemcfg->platform == PLATFORM_POWERMAC) 452 if (_machine == PLATFORM_POWERMAC)
454 return -ENOSPC; 453 return -ENOSPC;
455 454
456 /* see if we have an OS partition that meets our needs. 455 /* see if we have an OS partition that meets our needs.
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index 30247ff74972..3cef1b8f57f0 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -548,6 +548,11 @@ static int __init pcibios_init(void)
548 if (ppc64_isabridge_dev != NULL) 548 if (ppc64_isabridge_dev != NULL)
549 printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); 549 printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
550 550
551#ifdef CONFIG_PPC_MULTIPLATFORM
552 /* map in PCI I/O space */
553 phbs_remap_io();
554#endif
555
551 printk("PCI: Probing PCI hardware done\n"); 556 printk("PCI: Probing PCI hardware done\n");
552 557
553 return 0; 558 return 0;
@@ -1277,12 +1282,9 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
1277 * G5 machines... So when something asks for bus 0 io base 1282 * G5 machines... So when something asks for bus 0 io base
1278 * (bus 0 is HT root), we return the AGP one instead. 1283 * (bus 0 is HT root), we return the AGP one instead.
1279 */ 1284 */
1280#ifdef CONFIG_PPC_PMAC 1285 if (machine_is_compatible("MacRISC4"))
1281 if (systemcfg->platform == PLATFORM_POWERMAC &&
1282 machine_is_compatible("MacRISC4"))
1283 if (in_bus == 0) 1286 if (in_bus == 0)
1284 in_bus = 0xf0; 1287 in_bus = 0xf0;
1285#endif /* CONFIG_PPC_PMAC */
1286 1288
1287 /* That syscall isn't quite compatible with PCI domains, but it's 1289 /* That syscall isn't quite compatible with PCI domains, but it's
1288 * used on pre-domains setup. We return the first match 1290 * used on pre-domains setup. We return the first match
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
index 1a443a7ada4c..12c4c9e9bbc7 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -43,7 +43,7 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
43 u32 *regs; 43 u32 *regs;
44 struct pci_dn *pdn; 44 struct pci_dn *pdn;
45 45
46 if (phb->is_dynamic) 46 if (mem_init_done)
47 pdn = kmalloc(sizeof(*pdn), GFP_KERNEL); 47 pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
48 else 48 else
49 pdn = alloc_bootmem(sizeof(*pdn)); 49 pdn = alloc_bootmem(sizeof(*pdn));
@@ -120,6 +120,14 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
120 return NULL; 120 return NULL;
121} 121}
122 122
123/**
124 * pci_devs_phb_init_dynamic - setup pci devices under this PHB
125 * phb: pci-to-host bridge (top-level bridge connecting to cpu)
126 *
127 * This routine is called both during boot, (before the memory
128 * subsystem is set up, before kmalloc is valid) and during the
129 * dynamic lpar operation of adding a PHB to a running system.
130 */
123void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) 131void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
124{ 132{
125 struct device_node * dn = (struct device_node *) phb->arch_data; 133 struct device_node * dn = (struct device_node *) phb->arch_data;
@@ -201,9 +209,14 @@ static struct notifier_block pci_dn_reconfig_nb = {
201 .notifier_call = pci_dn_reconfig_notifier, 209 .notifier_call = pci_dn_reconfig_notifier,
202}; 210};
203 211
204/* 212/**
205 * Actually initialize the phbs. 213 * pci_devs_phb_init - Initialize phbs and pci devs under them.
206 * The buswalk on this phb has not happened yet. 214 *
215 * This routine walks over all phb's (pci-host bridges) on the
216 * system, and sets up assorted pci-related structures
217 * (including pci info in the device node structs) for each
218 * pci device found underneath. This routine runs once,
219 * early in the boot sequence.
207 */ 220 */
208void __init pci_devs_phb_init(void) 221void __init pci_devs_phb_init(void)
209{ 222{
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 3402fbee62c7..fbad2c360784 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -318,7 +318,7 @@ static int __devinit finish_node_interrupts(struct device_node *np,
318 } 318 }
319 319
320 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ 320 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
321 if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) { 321 if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
322 char *name = get_property(ic->parent, "name", NULL); 322 char *name = get_property(ic->parent, "name", NULL);
323 if (name && !strcmp(name, "u3")) 323 if (name && !strcmp(name, "u3"))
324 np->intrs[intrcount].line += 128; 324 np->intrs[intrcount].line += 128;
@@ -1065,7 +1065,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
1065 prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); 1065 prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
1066 if (prop == NULL) 1066 if (prop == NULL)
1067 return 0; 1067 return 0;
1068 systemcfg->platform = *prop; 1068 _machine = *prop;
1069 1069
1070 /* check if iommu is forced on or off */ 1070 /* check if iommu is forced on or off */
1071 if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) 1071 if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
@@ -1230,11 +1230,8 @@ void __init early_init_devtree(void *params)
1230 of_scan_flat_dt(early_init_dt_scan_memory, NULL); 1230 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
1231 lmb_enforce_memory_limit(memory_limit); 1231 lmb_enforce_memory_limit(memory_limit);
1232 lmb_analyze(); 1232 lmb_analyze();
1233 systemcfg->physicalMemorySize = lmb_phys_mem_size();
1234 lmb_reserve(0, __pa(klimit)); 1233 lmb_reserve(0, __pa(klimit));
1235 1234
1236 DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize);
1237
1238 /* Reserve LMB regions used by kernel, initrd, dt, etc... */ 1235 /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1239 early_reserve_mem(); 1236 early_reserve_mem();
1240 1237
@@ -1753,7 +1750,7 @@ static int of_finish_dynamic_node(struct device_node *node,
1753 /* We don't support that function on PowerMac, at least 1750 /* We don't support that function on PowerMac, at least
1754 * not yet 1751 * not yet
1755 */ 1752 */
1756 if (systemcfg->platform == PLATFORM_POWERMAC) 1753 if (_machine == PLATFORM_POWERMAC)
1757 return -ENODEV; 1754 return -ENODEV;
1758 1755
1759 /* fix up new node's linux_phandle field */ 1756 /* fix up new node's linux_phandle field */
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index e4c880dab997..6375f40b23db 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -1934,7 +1934,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
1934 /* 1934 /*
1935 * On pSeries, inform the firmware about our capabilities 1935 * On pSeries, inform the firmware about our capabilities
1936 */ 1936 */
1937 if (RELOC(of_platform) & PLATFORM_PSERIES) 1937 if (RELOC(of_platform) == PLATFORM_PSERIES ||
1938 RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
1938 prom_send_capabilities(); 1939 prom_send_capabilities();
1939 1940
1940 /* 1941 /*
diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
index 4aacf521e3e4..1bbacac44988 100644
--- a/arch/ppc64/kernel/vdso.c
+++ b/arch/ppc64/kernel/vdso.c
@@ -34,6 +34,7 @@
34#include <asm/machdep.h> 34#include <asm/machdep.h>
35#include <asm/cputable.h> 35#include <asm/cputable.h>
36#include <asm/sections.h> 36#include <asm/sections.h>
37#include <asm/systemcfg.h>
37#include <asm/vdso.h> 38#include <asm/vdso.h>
38 39
39#undef DEBUG 40#undef DEBUG
@@ -179,7 +180,7 @@ static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
179 * Last page is systemcfg. 180 * Last page is systemcfg.
180 */ 181 */
181 if ((vma->vm_end - address) <= PAGE_SIZE) 182 if ((vma->vm_end - address) <= PAGE_SIZE)
182 pg = virt_to_page(systemcfg); 183 pg = virt_to_page(_systemcfg);
183 else 184 else
184 pg = virt_to_page(vbase + offset); 185 pg = virt_to_page(vbase + offset);
185 186
@@ -604,7 +605,7 @@ void __init vdso_init(void)
604 get_page(pg); 605 get_page(pg);
605 } 606 }
606 607
607 get_page(virt_to_page(systemcfg)); 608 get_page(virt_to_page(_systemcfg));
608} 609}
609 610
610int in_gate_area_no_task(unsigned long addr) 611int in_gate_area_no_task(unsigned long addr)
diff --git a/arch/ppc64/kernel/vdso32/gettimeofday.S b/arch/ppc64/kernel/vdso32/gettimeofday.S
deleted file mode 100644
index e243c1d24af7..000000000000
--- a/arch/ppc64/kernel/vdso32/gettimeofday.S
+++ /dev/null
@@ -1,140 +0,0 @@
1/*
2 * Userland implementation of gettimeofday() for 32 bits processes in a
3 * ppc64 kernel for use in the vDSO
4 *
5 * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org), IBM Corp.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12#include <linux/config.h>
13#include <asm/processor.h>
14#include <asm/ppc_asm.h>
15#include <asm/vdso.h>
16#include <asm/asm-offsets.h>
17#include <asm/unistd.h>
18
19 .text
20/*
21 * Exact prototype of gettimeofday
22 *
23 * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz);
24 *
25 */
26V_FUNCTION_BEGIN(__kernel_gettimeofday)
27 .cfi_startproc
28 mflr r12
29 .cfi_register lr,r12
30
31 mr r10,r3 /* r10 saves tv */
32 mr r11,r4 /* r11 saves tz */
33 bl __get_datapage@local /* get data page */
34 mr r9, r3 /* datapage ptr in r9 */
35 bl __do_get_xsec@local /* get xsec from tb & kernel */
36 bne- 2f /* out of line -> do syscall */
37
38 /* seconds are xsec >> 20 */
39 rlwinm r5,r4,12,20,31
40 rlwimi r5,r3,12,0,19
41 stw r5,TVAL32_TV_SEC(r10)
42
43 /* get remaining xsec and convert to usec. we scale
44 * up remaining xsec by 12 bits and get the top 32 bits
45 * of the multiplication
46 */
47 rlwinm r5,r4,12,0,19
48 lis r6,1000000@h
49 ori r6,r6,1000000@l
50 mulhwu r5,r5,r6
51 stw r5,TVAL32_TV_USEC(r10)
52
53 cmpli cr0,r11,0 /* check if tz is NULL */
54 beq 1f
55 lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */
56 lwz r5,CFG_TZ_DSTTIME(r9)
57 stw r4,TZONE_TZ_MINWEST(r11)
58 stw r5,TZONE_TZ_DSTTIME(r11)
59
601: mtlr r12
61 li r3,0
62 blr
63
642: mr r3,r10
65 mr r4,r11
66 li r0,__NR_gettimeofday
67 sc
68 b 1b
69 .cfi_endproc
70V_FUNCTION_END(__kernel_gettimeofday)
71
72/*
73 * This is the core of gettimeofday(), it returns the xsec
74 * value in r3 & r4 and expects the datapage ptr (non clobbered)
75 * in r9. clobbers r0,r4,r5,r6,r7,r8
76*/
77__do_get_xsec:
78 .cfi_startproc
79 /* Check for update count & load values. We use the low
80 * order 32 bits of the update count
81 */
821: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9)
83 andi. r0,r8,1 /* pending update ? loop */
84 bne- 1b
85 xor r0,r8,r8 /* create dependency */
86 add r9,r9,r0
87
88 /* Load orig stamp (offset to TB) */
89 lwz r5,CFG_TB_ORIG_STAMP(r9)
90 lwz r6,(CFG_TB_ORIG_STAMP+4)(r9)
91
92 /* Get a stable TB value */
932: mftbu r3
94 mftbl r4
95 mftbu r0
96 cmpl cr0,r3,r0
97 bne- 2b
98
99 /* Substract tb orig stamp. If the high part is non-zero, we jump to the
100 * slow path which call the syscall. If it's ok, then we have our 32 bits
101 * tb_ticks value in r7
102 */
103 subfc r7,r6,r4
104 subfe. r0,r5,r3
105 bne- 3f
106
107 /* Load scale factor & do multiplication */
108 lwz r5,CFG_TB_TO_XS(r9) /* load values */
109 lwz r6,(CFG_TB_TO_XS+4)(r9)
110 mulhwu r4,r7,r5
111 mulhwu r6,r7,r6
112 mullw r0,r7,r5
113 addc r6,r6,r0
114
115 /* At this point, we have the scaled xsec value in r4 + XER:CA
116 * we load & add the stamp since epoch
117 */
118 lwz r5,CFG_STAMP_XSEC(r9)
119 lwz r6,(CFG_STAMP_XSEC+4)(r9)
120 adde r4,r4,r6
121 addze r3,r5
122
123 /* We now have our result in r3,r4. We create a fake dependency
124 * on that result and re-check the counter
125 */
126 xor r0,r4,r4
127 add r9,r9,r0
128 lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9)
129 cmpl cr0,r8,r0 /* check if updated */
130 bne- 1b
131
132 /* Warning ! The caller expects CR:EQ to be set to indicate a
133 * successful calculation (so it won't fallback to the syscall
134 * method). We have overriden that CR bit in the counter check,
135 * but fortunately, the loop exit condition _is_ CR:EQ set, so
136 * we can exit safely here. If you change this code, be careful
137 * of that side effect.
138 */
1393: blr
140 .cfi_endproc
diff --git a/arch/ppc64/kernel/vdso64/gettimeofday.S b/arch/ppc64/kernel/vdso64/gettimeofday.S
deleted file mode 100644
index f6df8028570a..000000000000
--- a/arch/ppc64/kernel/vdso64/gettimeofday.S
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * Userland implementation of gettimeofday() for 64 bits processes in a
3 * ppc64 kernel for use in the vDSO
4 *
5 * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org),
6 * IBM Corp.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13#include <linux/config.h>
14#include <asm/processor.h>
15#include <asm/ppc_asm.h>
16#include <asm/vdso.h>
17#include <asm/asm-offsets.h>
18
19 .text
20/*
21 * Exact prototype of gettimeofday
22 *
23 * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz);
24 *
25 */
26V_FUNCTION_BEGIN(__kernel_gettimeofday)
27 .cfi_startproc
28 mflr r12
29 .cfi_register lr,r12
30
31 mr r11,r3 /* r11 holds tv */
32 mr r10,r4 /* r10 holds tz */
33 bl V_LOCAL_FUNC(__get_datapage) /* get data page */
34 bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
35 lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */
36 ori r7,r7,16960
37 rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
38 rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
39 std r5,TVAL64_TV_SEC(r11) /* store sec in tv */
40 subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
41 mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / XSEC_PER_SEC */
42 rldicl r0,r0,44,20
43 cmpldi cr0,r10,0 /* check if tz is NULL */
44 std r0,TVAL64_TV_USEC(r11) /* store usec in tv */
45 beq 1f
46 lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */
47 lwz r5,CFG_TZ_DSTTIME(r3)
48 stw r4,TZONE_TZ_MINWEST(r10)
49 stw r5,TZONE_TZ_DSTTIME(r10)
501: mtlr r12
51 li r3,0 /* always success */
52 blr
53 .cfi_endproc
54V_FUNCTION_END(__kernel_gettimeofday)
55
56
57/*
58 * This is the core of gettimeofday(), it returns the xsec
59 * value in r4 and expects the datapage ptr (non clobbered)
60 * in r3. clobbers r0,r4,r5,r6,r7,r8
61*/
62V_FUNCTION_BEGIN(__do_get_xsec)
63 .cfi_startproc
64 /* check for update count & load values */
651: ld r7,CFG_TB_UPDATE_COUNT(r3)
66 andi. r0,r4,1 /* pending update ? loop */
67 bne- 1b
68 xor r0,r4,r4 /* create dependency */
69 add r3,r3,r0
70
71 /* Get TB & offset it */
72 mftb r8
73 ld r9,CFG_TB_ORIG_STAMP(r3)
74 subf r8,r9,r8
75
76 /* Scale result */
77 ld r5,CFG_TB_TO_XS(r3)
78 mulhdu r8,r8,r5
79
80 /* Add stamp since epoch */
81 ld r6,CFG_STAMP_XSEC(r3)
82 add r4,r6,r8
83
84 xor r0,r4,r4
85 add r3,r3,r0
86 ld r0,CFG_TB_UPDATE_COUNT(r3)
87 cmpld cr0,r0,r7 /* check if updated */
88 bne- 1b
89 blr
90 .cfi_endproc
91V_FUNCTION_END(__do_get_xsec)
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index bc59282da762..896d39d0e4ce 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -486,7 +486,7 @@ out:
486 * - goto next entry in p_info 486 * - goto next entry in p_info
487 */ 487 */
488 488
489extern inline int 489static inline int
490debug_next_entry(file_private_info_t *p_info) 490debug_next_entry(file_private_info_t *p_info)
491{ 491{
492 debug_info_t *id; 492 debug_info_t *id;
@@ -800,7 +800,7 @@ debug_set_level(debug_info_t* id, int new_level)
800 * - set active entry to next in the ring buffer 800 * - set active entry to next in the ring buffer
801 */ 801 */
802 802
803extern inline void 803static inline void
804proceed_active_entry(debug_info_t * id) 804proceed_active_entry(debug_info_t * id)
805{ 805{
806 if ((id->active_entries[id->active_area] += id->entry_size) 806 if ((id->active_entries[id->active_area] += id->entry_size)
@@ -817,7 +817,7 @@ proceed_active_entry(debug_info_t * id)
817 * - set active area to next in the ring buffer 817 * - set active area to next in the ring buffer
818 */ 818 */
819 819
820extern inline void 820static inline void
821proceed_active_area(debug_info_t * id) 821proceed_active_area(debug_info_t * id)
822{ 822{
823 id->active_area++; 823 id->active_area++;
@@ -828,7 +828,7 @@ proceed_active_area(debug_info_t * id)
828 * get_active_entry: 828 * get_active_entry:
829 */ 829 */
830 830
831extern inline debug_entry_t* 831static inline debug_entry_t*
832get_active_entry(debug_info_t * id) 832get_active_entry(debug_info_t * id)
833{ 833{
834 return (debug_entry_t *) (((char *) id->areas[id->active_area] 834 return (debug_entry_t *) (((char *) id->areas[id->active_area]
@@ -841,7 +841,7 @@ get_active_entry(debug_info_t * id)
841 * - set timestamp, caller address, cpu number etc. 841 * - set timestamp, caller address, cpu number etc.
842 */ 842 */
843 843
844extern inline void 844static inline void
845debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, 845debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
846 int exception) 846 int exception)
847{ 847{
@@ -971,7 +971,7 @@ debug_entry_t
971 * counts arguments in format string for sprintf view 971 * counts arguments in format string for sprintf view
972 */ 972 */
973 973
974extern inline int 974static inline int
975debug_count_numargs(char *string) 975debug_count_numargs(char *string)
976{ 976{
977 int numargs=0; 977 int numargs=0;
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 9f3dff6c0b72..78b64fe5e7c2 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -99,15 +99,15 @@ void default_idle(void)
99{ 99{
100 int cpu, rc; 100 int cpu, rc;
101 101
102 /* CPU is going idle. */
103 cpu = smp_processor_id();
104
102 local_irq_disable(); 105 local_irq_disable();
103 if (need_resched()) { 106 if (need_resched()) {
104 local_irq_enable(); 107 local_irq_enable();
105 schedule(); 108 return;
106 return; 109 }
107 }
108 110
109 /* CPU is going idle. */
110 cpu = smp_processor_id();
111 rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu); 111 rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu);
112 if (rc != NOTIFY_OK && rc != NOTIFY_DONE) 112 if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
113 BUG(); 113 BUG();
@@ -120,7 +120,7 @@ void default_idle(void)
120 __ctl_set_bit(8, 15); 120 __ctl_set_bit(8, 15);
121 121
122#ifdef CONFIG_HOTPLUG_CPU 122#ifdef CONFIG_HOTPLUG_CPU
123 if (cpu_is_offline(smp_processor_id())) 123 if (cpu_is_offline(cpu))
124 cpu_die(); 124 cpu_die();
125#endif 125#endif
126 126
@@ -139,8 +139,14 @@ void default_idle(void)
139 139
140void cpu_idle(void) 140void cpu_idle(void)
141{ 141{
142 for (;;) 142 for (;;) {
143 default_idle(); 143 while (!need_resched())
144 default_idle();
145
146 preempt_enable_no_resched();
147 schedule();
148 preempt_disable();
149 }
144} 150}
145 151
146void show_regs(struct pt_regs *regs) 152void show_regs(struct pt_regs *regs)
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index e13c87b446b2..5856b3fda6bf 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -533,6 +533,7 @@ int __devinit start_secondary(void *cpuvoid)
533{ 533{
534 /* Setup the cpu */ 534 /* Setup the cpu */
535 cpu_init(); 535 cpu_init();
536 preempt_disable();
536 /* init per CPU timer */ 537 /* init per CPU timer */
537 init_cpu_timer(); 538 init_cpu_timer();
538#ifdef CONFIG_VIRT_TIMER 539#ifdef CONFIG_VIRT_TIMER
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 64e32da77754..fb2607c369ed 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -160,7 +160,7 @@ static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
160 * 11 Page translation -> Not present (nullification) 160 * 11 Page translation -> Not present (nullification)
161 * 3b Region third trans. -> Not present (nullification) 161 * 3b Region third trans. -> Not present (nullification)
162 */ 162 */
163extern inline void 163static inline void
164do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) 164do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
165{ 165{
166 struct task_struct *tsk; 166 struct task_struct *tsk;
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 6dce9d0b81f8..fd4f240b833d 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -51,28 +51,24 @@ void enable_hlt(void)
51 51
52EXPORT_SYMBOL(enable_hlt); 52EXPORT_SYMBOL(enable_hlt);
53 53
54void default_idle(void) 54void cpu_idle(void)
55{ 55{
56 /* endless idle loop with no priority at all */ 56 /* endless idle loop with no priority at all */
57 while (1) { 57 while (1) {
58 if (hlt_counter) { 58 if (hlt_counter) {
59 while (1) 59 while (!need_resched())
60 if (need_resched()) 60 cpu_relax();
61 break;
62 } else { 61 } else {
63 while (!need_resched()) 62 while (!need_resched())
64 cpu_sleep(); 63 cpu_sleep();
65 } 64 }
66 65
66 preempt_enable_no_resched();
67 schedule(); 67 schedule();
68 preempt_disable();
68 } 69 }
69} 70}
70 71
71void cpu_idle(void)
72{
73 default_idle();
74}
75
76void machine_restart(char * __unused) 72void machine_restart(char * __unused)
77{ 73{
78 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ 74 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 5ecefc02896a..59e49b18252c 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -112,7 +112,9 @@ int __cpu_up(unsigned int cpu)
112 112
113int start_secondary(void *unused) 113int start_secondary(void *unused)
114{ 114{
115 unsigned int cpu = smp_processor_id(); 115 unsigned int cpu;
116
117 cpu = smp_processor_id();
116 118
117 atomic_inc(&init_mm.mm_count); 119 atomic_inc(&init_mm.mm_count);
118 current->active_mm = &init_mm; 120 current->active_mm = &init_mm;
@@ -120,6 +122,7 @@ int start_secondary(void *unused)
120 smp_store_cpu_info(cpu); 122 smp_store_cpu_info(cpu);
121 123
122 __smp_slave_init(cpu); 124 __smp_slave_init(cpu);
125 preempt_disable();
123 per_cpu_trap_init(); 126 per_cpu_trap_init();
124 127
125 atomic_inc(&cpus_booted); 128 atomic_inc(&cpus_booted);
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index efde41c0cd66..b95d04141855 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -307,23 +307,19 @@ __setup("hlt", hlt_setup);
307 307
308static inline void hlt(void) 308static inline void hlt(void)
309{ 309{
310 if (hlt_counter)
311 return;
312
313 __asm__ __volatile__ ("sleep" : : : "memory"); 310 __asm__ __volatile__ ("sleep" : : : "memory");
314} 311}
315 312
316/* 313/*
317 * The idle loop on a uniprocessor SH.. 314 * The idle loop on a uniprocessor SH..
318 */ 315 */
319void default_idle(void) 316void cpu_idle(void)
320{ 317{
321 /* endless idle loop with no priority at all */ 318 /* endless idle loop with no priority at all */
322 while (1) { 319 while (1) {
323 if (hlt_counter) { 320 if (hlt_counter) {
324 while (1) 321 while (!need_resched())
325 if (need_resched()) 322 cpu_relax();
326 break;
327 } else { 323 } else {
328 local_irq_disable(); 324 local_irq_disable();
329 while (!need_resched()) { 325 while (!need_resched()) {
@@ -334,13 +330,11 @@ void default_idle(void)
334 } 330 }
335 local_irq_enable(); 331 local_irq_enable();
336 } 332 }
333 preempt_enable_no_resched();
337 schedule(); 334 schedule();
335 preempt_disable();
338 } 336 }
339}
340 337
341void cpu_idle(void)
342{
343 default_idle();
344} 338}
345 339
346void machine_restart(char * __unused) 340void machine_restart(char * __unused)
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 6a4ebc62193e..d7bfc61d2879 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -75,7 +75,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
75 { 9, 3, "Fujitsu or Weitek on-chip FPU"}, 75 { 9, 3, "Fujitsu or Weitek on-chip FPU"},
76}; 76};
77 77
78#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) 78#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
79 79
80struct cpu_iu_info linux_sparc_chips[] = { 80struct cpu_iu_info linux_sparc_chips[] = {
81 /* Sun4/100, 4/200, SLC */ 81 /* Sun4/100, 4/200, SLC */
@@ -120,7 +120,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
120 { 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"}, 120 { 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"},
121}; 121};
122 122
123#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) 123#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
124 124
125char *sparc_cpu_type; 125char *sparc_cpu_type;
126char *sparc_fpu_type; 126char *sparc_fpu_type;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 25e31d5ec99b..cccfc12802ed 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -143,7 +143,7 @@ static struct pcic_ca2irq pcic_i_jk[] = {
143 * as several PROMs may be installed on the same physical board. 143 * as several PROMs may be installed on the same physical board.
144 */ 144 */
145#define SN2L_INIT(name, map) \ 145#define SN2L_INIT(name, map) \
146 { name, map, sizeof(map)/sizeof(struct pcic_ca2irq) } 146 { name, map, ARRAY_SIZE(map) }
147 147
148static struct pcic_sn2list pcic_known_sysnames[] = { 148static struct pcic_sn2list pcic_known_sysnames[] = {
149 SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */ 149 SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 29e72b57d4fd..ea8647411462 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -67,13 +67,6 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
67struct task_struct *last_task_used_math = NULL; 67struct task_struct *last_task_used_math = NULL;
68struct thread_info *current_set[NR_CPUS]; 68struct thread_info *current_set[NR_CPUS];
69 69
70/*
71 * default_idle is new in 2.5. XXX Review, currently stolen from sparc64.
72 */
73void default_idle(void)
74{
75}
76
77#ifndef CONFIG_SMP 70#ifndef CONFIG_SMP
78 71
79#define SUN4C_FAULT_HIGH 100 72#define SUN4C_FAULT_HIGH 100
@@ -92,12 +85,11 @@ void cpu_idle(void)
92 static unsigned long fps; 85 static unsigned long fps;
93 unsigned long now; 86 unsigned long now;
94 unsigned long faults; 87 unsigned long faults;
95 unsigned long flags;
96 88
97 extern unsigned long sun4c_kernel_faults; 89 extern unsigned long sun4c_kernel_faults;
98 extern void sun4c_grow_kernel_ring(void); 90 extern void sun4c_grow_kernel_ring(void);
99 91
100 local_irq_save(flags); 92 local_irq_disable();
101 now = jiffies; 93 now = jiffies;
102 count -= (now - last_jiffies); 94 count -= (now - last_jiffies);
103 last_jiffies = now; 95 last_jiffies = now;
@@ -113,14 +105,19 @@ void cpu_idle(void)
113 sun4c_grow_kernel_ring(); 105 sun4c_grow_kernel_ring();
114 } 106 }
115 } 107 }
116 local_irq_restore(flags); 108 local_irq_enable();
117 } 109 }
118 110
119 while((!need_resched()) && pm_idle) { 111 if (pm_idle) {
120 (*pm_idle)(); 112 while (!need_resched())
113 (*pm_idle)();
114 } else {
115 while (!need_resched())
116 cpu_relax();
121 } 117 }
122 118 preempt_enable_no_resched();
123 schedule(); 119 schedule();
120 preempt_disable();
124 check_pgt_cache(); 121 check_pgt_cache();
125 } 122 }
126} 123}
@@ -130,13 +127,15 @@ void cpu_idle(void)
130/* This is being executed in task 0 'user space'. */ 127/* This is being executed in task 0 'user space'. */
131void cpu_idle(void) 128void cpu_idle(void)
132{ 129{
130 set_thread_flag(TIF_POLLING_NRFLAG);
133 /* endless idle loop with no priority at all */ 131 /* endless idle loop with no priority at all */
134 while(1) { 132 while(1) {
135 if(need_resched()) { 133 while (!need_resched())
136 schedule(); 134 cpu_relax();
137 check_pgt_cache(); 135 preempt_enable_no_resched();
138 } 136 schedule();
139 barrier(); /* or else gcc optimizes... */ 137 preempt_disable();
138 check_pgt_cache();
140 } 139 }
141} 140}
142 141
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 2bbd53f3cafb..9eeed3347df3 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -33,8 +33,6 @@
33#include <asm/kdebug.h> 33#include <asm/kdebug.h>
34#include <asm/uaccess.h> 34#include <asm/uaccess.h>
35 35
36#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
37
38extern int prom_node_root; 36extern int prom_node_root;
39 37
40/* At boot time we determine these two values necessary for setting 38/* At boot time we determine these two values necessary for setting
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 77ef5df4e5a7..00eed88ef2e8 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -43,7 +43,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
43 { 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"}, 43 { 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"},
44}; 44};
45 45
46#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) 46#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
47 47
48struct cpu_iu_info linux_sparc_chips[] = { 48struct cpu_iu_info linux_sparc_chips[] = {
49 { 0x17, 0x10, "TI UltraSparc I (SpitFire)"}, 49 { 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
@@ -59,7 +59,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
59 { 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"}, 59 { 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"},
60}; 60};
61 61
62#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) 62#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
63 63
64char *sparc_cpu_type = "cpu-oops"; 64char *sparc_cpu_type = "cpu-oops";
65char *sparc_fpu_type = "fpu-oops"; 65char *sparc_fpu_type = "fpu-oops";
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 92e26304de90..e62214354bb5 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -92,10 +92,8 @@ static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
92 return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p); 92 return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p);
93} 93}
94 94
95typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
96
97#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) 95#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
98#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, 96#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
99#define IOCTL_TABLE_START \ 97#define IOCTL_TABLE_START \
100 struct ioctl_trans ioctl_start[] = { 98 struct ioctl_trans ioctl_start[] = {
101#define IOCTL_TABLE_END \ 99#define IOCTL_TABLE_END \
@@ -116,8 +114,6 @@ COMPATIBLE_IOCTL(FBIOGCURPOS)
116COMPATIBLE_IOCTL(FBIOGCURMAX) 114COMPATIBLE_IOCTL(FBIOGCURMAX)
117/* Little k */ 115/* Little k */
118/* Little v, the video4linux ioctls */ 116/* Little v, the video4linux ioctls */
119COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
120COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
121/* And these ioctls need translation */ 117/* And these ioctls need translation */
122/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ 118/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
123HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap) 119HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap)
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 7d10b0397091..02f9dec1d459 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -74,7 +74,9 @@ void cpu_idle(void)
74 while (!need_resched()) 74 while (!need_resched())
75 barrier(); 75 barrier();
76 76
77 preempt_enable_no_resched();
77 schedule(); 78 schedule();
79 preempt_disable();
78 check_pgt_cache(); 80 check_pgt_cache();
79 } 81 }
80} 82}
@@ -83,21 +85,31 @@ void cpu_idle(void)
83 85
84/* 86/*
85 * the idle loop on a UltraMultiPenguin... 87 * the idle loop on a UltraMultiPenguin...
88 *
89 * TIF_POLLING_NRFLAG is set because we do not sleep the cpu
90 * inside of the idler task, so an interrupt is not needed
91 * to get a clean fast response.
92 *
93 * XXX Reverify this assumption... -DaveM
94 *
95 * Addendum: We do want it to do something for the signal
96 * delivery case, we detect that by just seeing
97 * if we are trying to send this to an idler or not.
86 */ 98 */
87#define idle_me_harder() (cpu_data(smp_processor_id()).idle_volume += 1)
88#define unidle_me() (cpu_data(smp_processor_id()).idle_volume = 0)
89void cpu_idle(void) 99void cpu_idle(void)
90{ 100{
101 cpuinfo_sparc *cpuinfo = &local_cpu_data();
91 set_thread_flag(TIF_POLLING_NRFLAG); 102 set_thread_flag(TIF_POLLING_NRFLAG);
103
92 while(1) { 104 while(1) {
93 if (need_resched()) { 105 if (need_resched()) {
94 unidle_me(); 106 cpuinfo->idle_volume = 0;
95 clear_thread_flag(TIF_POLLING_NRFLAG); 107 preempt_enable_no_resched();
96 schedule(); 108 schedule();
97 set_thread_flag(TIF_POLLING_NRFLAG); 109 preempt_disable();
98 check_pgt_cache(); 110 check_pgt_cache();
99 } 111 }
100 idle_me_harder(); 112 cpuinfo->idle_volume++;
101 113
102 /* The store ordering is so that IRQ handlers on 114 /* The store ordering is so that IRQ handlers on
103 * other cpus see our increasing idleness for the buddy 115 * other cpus see our increasing idleness for the buddy
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index e09ddf927655..96b825055668 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -790,7 +790,7 @@ static unsigned long sysio_irq_offsets[] = {
790 790
791#undef bogon 791#undef bogon
792 792
793#define NUM_SYSIO_OFFSETS (sizeof(sysio_irq_offsets) / sizeof(sysio_irq_offsets[0])) 793#define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
794 794
795/* Convert Interrupt Mapping register pointer to associated 795/* Convert Interrupt Mapping register pointer to associated
796 * Interrupt Clear register pointer, SYSIO specific version. 796 * Interrupt Clear register pointer, SYSIO specific version.
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 5d90ee9aebf1..797a65493fb8 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -168,6 +168,9 @@ void __init smp_callin(void)
168 rmb(); 168 rmb();
169 169
170 cpu_set(cpuid, cpu_online_map); 170 cpu_set(cpuid, cpu_online_map);
171
172 /* idle thread is expected to have preempt disabled */
173 preempt_disable();
171} 174}
172 175
173void cpu_panic(void) 176void cpu_panic(void)
@@ -1149,20 +1152,9 @@ void __init smp_cpus_done(unsigned int max_cpus)
1149 (bogosum/(5000/HZ))%100); 1152 (bogosum/(5000/HZ))%100);
1150} 1153}
1151 1154
1152/* This needn't do anything as we do not sleep the cpu
1153 * inside of the idler task, so an interrupt is not needed
1154 * to get a clean fast response.
1155 *
1156 * XXX Reverify this assumption... -DaveM
1157 *
1158 * Addendum: We do want it to do something for the signal
1159 * delivery case, we detect that by just seeing
1160 * if we are trying to send this to an idler or not.
1161 */
1162void smp_send_reschedule(int cpu) 1155void smp_send_reschedule(int cpu)
1163{ 1156{
1164 if (cpu_data(cpu).idle_volume == 0) 1157 smp_receive_signal(cpu);
1165 smp_receive_signal(cpu);
1166} 1158}
1167 1159
1168/* This is a nop because we capture all other cpus 1160/* This is a nop because we capture all other cpus
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 3be278d916db..6f0539aa44d0 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -30,8 +30,6 @@
30#include <asm/sections.h> 30#include <asm/sections.h>
31#include <asm/kdebug.h> 31#include <asm/kdebug.h>
32 32
33#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
34
35/* 33/*
36 * To debug kernel to catch accesses to certain virtual/physical addresses. 34 * To debug kernel to catch accesses to certain virtual/physical addresses.
37 * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. 35 * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index b489aad12853..84c73a300acb 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -243,34 +243,18 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
243 return err; 243 return err;
244} 244}
245 245
246static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 246static void uml_net_get_drvinfo(struct net_device *dev,
247{ 247 struct ethtool_drvinfo *info)
248 static const struct ethtool_drvinfo info = { 248{
249 .cmd = ETHTOOL_GDRVINFO, 249 strcpy(info->driver, DRIVER_NAME);
250 .driver = DRIVER_NAME, 250 strcpy(info->version, "42");
251 .version = "42",
252 };
253 void *useraddr;
254 u32 ethcmd;
255
256 switch (cmd) {
257 case SIOCETHTOOL:
258 useraddr = ifr->ifr_data;
259 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
260 return -EFAULT;
261 switch (ethcmd) {
262 case ETHTOOL_GDRVINFO:
263 if (copy_to_user(useraddr, &info, sizeof(info)))
264 return -EFAULT;
265 return 0;
266 default:
267 return -EOPNOTSUPP;
268 }
269 default:
270 return -EINVAL;
271 }
272} 251}
273 252
253static struct ethtool_ops uml_net_ethtool_ops = {
254 .get_drvinfo = uml_net_get_drvinfo,
255 .get_link = ethtool_op_get_link,
256};
257
274void uml_net_user_timer_expire(unsigned long _conn) 258void uml_net_user_timer_expire(unsigned long _conn)
275{ 259{
276#ifdef undef 260#ifdef undef
@@ -360,7 +344,7 @@ static int eth_configure(int n, void *init, char *mac,
360 dev->tx_timeout = uml_net_tx_timeout; 344 dev->tx_timeout = uml_net_tx_timeout;
361 dev->set_mac_address = uml_net_set_mac; 345 dev->set_mac_address = uml_net_set_mac;
362 dev->change_mtu = uml_net_change_mtu; 346 dev->change_mtu = uml_net_change_mtu;
363 dev->do_ioctl = uml_net_ioctl; 347 dev->ethtool_ops = &uml_net_ethtool_ops;
364 dev->watchdog_timeo = (HZ >> 1); 348 dev->watchdog_timeo = (HZ >> 1);
365 dev->irq = UM_ETH_IRQ; 349 dev->irq = UM_ETH_IRQ;
366 350
diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index 9c708c32c1f0..39cf247cdae4 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -36,11 +36,8 @@ extern void ret_from_fork (void);
36/* The idle loop. */ 36/* The idle loop. */
37void default_idle (void) 37void default_idle (void)
38{ 38{
39 while (1) { 39 while (! need_resched ())
40 while (! need_resched ()) 40 asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
41 asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
42 schedule ();
43 }
44} 41}
45 42
46void (*idle)(void) = default_idle; 43void (*idle)(void) = default_idle;
@@ -54,7 +51,14 @@ void (*idle)(void) = default_idle;
54void cpu_idle (void) 51void cpu_idle (void)
55{ 52{
56 /* endless idle loop with no priority at all */ 53 /* endless idle loop with no priority at all */
57 (*idle) (); 54 while (1) {
55 while (!need_resched())
56 (*idle) ();
57
58 preempt_enable_no_resched();
59 schedule();
60 preempt_disable();
61 }
58} 62}
59 63
60/* 64/*
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index 4ba0e293d5e5..e335bd0b637d 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -64,12 +64,6 @@ struct ioctl_trans ioctl_start[] = {
64#include <linux/compat_ioctl.h> 64#include <linux/compat_ioctl.h>
65#define DECLARES 65#define DECLARES
66#include "compat_ioctl.c" 66#include "compat_ioctl.c"
67COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
68COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
69COMPATIBLE_IOCTL(BLKRASET)
70COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
71COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
72COMPATIBLE_IOCTL(FIOQSIZE)
73 67
74/* And these ioctls need translation */ 68/* And these ioctls need translation */
75/* realtime device */ 69/* realtime device */
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index b5a89c0bdf59..59be85d9a4bc 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -86,12 +86,22 @@ EXPORT_SYMBOL(enable_hlt);
86 */ 86 */
87void default_idle(void) 87void default_idle(void)
88{ 88{
89 local_irq_enable();
90
89 if (!atomic_read(&hlt_counter)) { 91 if (!atomic_read(&hlt_counter)) {
90 local_irq_disable(); 92 clear_thread_flag(TIF_POLLING_NRFLAG);
91 if (!need_resched()) 93 smp_mb__after_clear_bit();
92 safe_halt(); 94 while (!need_resched()) {
93 else 95 local_irq_disable();
94 local_irq_enable(); 96 if (!need_resched())
97 safe_halt();
98 else
99 local_irq_enable();
100 }
101 set_thread_flag(TIF_POLLING_NRFLAG);
102 } else {
103 while (!need_resched())
104 cpu_relax();
95 } 105 }
96} 106}
97 107
@@ -102,30 +112,16 @@ void default_idle(void)
102 */ 112 */
103static void poll_idle (void) 113static void poll_idle (void)
104{ 114{
105 int oldval;
106
107 local_irq_enable(); 115 local_irq_enable();
108 116
109 /* 117 asm volatile(
110 * Deal with another CPU just having chosen a thread to 118 "2:"
111 * run here: 119 "testl %0,%1;"
112 */ 120 "rep; nop;"
113 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 121 "je 2b;"
114 122 : :
115 if (!oldval) { 123 "i" (_TIF_NEED_RESCHED),
116 set_thread_flag(TIF_POLLING_NRFLAG); 124 "m" (current_thread_info()->flags));
117 asm volatile(
118 "2:"
119 "testl %0,%1;"
120 "rep; nop;"
121 "je 2b;"
122 : :
123 "i" (_TIF_NEED_RESCHED),
124 "m" (current_thread_info()->flags));
125 clear_thread_flag(TIF_POLLING_NRFLAG);
126 } else {
127 set_need_resched();
128 }
129} 125}
130 126
131void cpu_idle_wait(void) 127void cpu_idle_wait(void)
@@ -187,6 +183,8 @@ static inline void play_dead(void)
187 */ 183 */
188void cpu_idle (void) 184void cpu_idle (void)
189{ 185{
186 set_thread_flag(TIF_POLLING_NRFLAG);
187
190 /* endless idle loop with no priority at all */ 188 /* endless idle loop with no priority at all */
191 while (1) { 189 while (1) {
192 while (!need_resched()) { 190 while (!need_resched()) {
@@ -204,7 +202,9 @@ void cpu_idle (void)
204 idle(); 202 idle();
205 } 203 }
206 204
205 preempt_enable_no_resched();
207 schedule(); 206 schedule();
207 preempt_disable();
208 } 208 }
209} 209}
210 210
@@ -219,15 +219,12 @@ static void mwait_idle(void)
219{ 219{
220 local_irq_enable(); 220 local_irq_enable();
221 221
222 if (!need_resched()) { 222 while (!need_resched()) {
223 set_thread_flag(TIF_POLLING_NRFLAG); 223 __monitor((void *)&current_thread_info()->flags, 0, 0);
224 do { 224 smp_mb();
225 __monitor((void *)&current_thread_info()->flags, 0, 0); 225 if (need_resched())
226 if (need_resched()) 226 break;
227 break; 227 __mwait(0, 0);
228 __mwait(0, 0);
229 } while (!need_resched());
230 clear_thread_flag(TIF_POLLING_NRFLAG);
231 } 228 }
232} 229}
233 230
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 4b5b088ec102..c4e59bbdc187 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -472,6 +472,7 @@ void __cpuinit start_secondary(void)
472 * things done here to the most necessary things. 472 * things done here to the most necessary things.
473 */ 473 */
474 cpu_init(); 474 cpu_init();
475 preempt_disable();
475 smp_callin(); 476 smp_callin();
476 477
477 /* otherwise gcc will move up the smp_processor_id before the cpu_init */ 478 /* otherwise gcc will move up the smp_processor_id before the cpu_init */
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 08ef6d82ee51..6a44b54ae817 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -96,8 +96,9 @@ void cpu_idle(void)
96 while (1) { 96 while (1) {
97 while (!need_resched()) 97 while (!need_resched())
98 platform_idle(); 98 platform_idle();
99 preempt_enable(); 99 preempt_enable_no_resched();
100 schedule(); 100 schedule();
101 preempt_disable();
101 } 102 }
102} 103}
103 104
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index 58e782e5c42d..0dc55cc8691b 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -611,38 +611,6 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
611 return -EINVAL; 611 return -EINVAL;
612} 612}
613 613
614static int iss_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
615{
616#if 0
617 static const struct ethtool_drvinfo info = {
618 .cmd = ETHTOOL_GDRVINFO,
619 .driver = DRIVER_NAME,
620 .version = "42",
621 };
622 void *useraddr;
623 u32 ethcmd;
624
625 switch (cmd) {
626 case SIOCETHTOOL:
627 useraddr = ifr->ifr_data;
628 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
629 return -EFAULT;
630
631 switch (ethcmd) {
632 case ETHTOOL_GDRVINFO:
633 if (copy_to_user(useraddr, &info, sizeof(info)))
634 return -EFAULT;
635 return 0;
636 default:
637 return -EOPNOTSUPP;
638 }
639 default:
640 return -EINVAL;
641 }
642#endif
643 return -EINVAL;
644}
645
646void iss_net_user_timer_expire(unsigned long _conn) 614void iss_net_user_timer_expire(unsigned long _conn)
647{ 615{
648} 616}
@@ -731,7 +699,6 @@ static int iss_net_configure(int index, char *init)
731 dev->tx_timeout = iss_net_tx_timeout; 699 dev->tx_timeout = iss_net_tx_timeout;
732 dev->set_mac_address = iss_net_set_mac; 700 dev->set_mac_address = iss_net_set_mac;
733 dev->change_mtu = iss_net_change_mtu; 701 dev->change_mtu = iss_net_change_mtu;
734 dev->do_ioctl = iss_net_ioctl;
735 dev->watchdog_timeo = (HZ >> 1); 702 dev->watchdog_timeo = (HZ >> 1);
736 dev->irq = -1; 703 dev->irq = -1;
737 704
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 3937adf4e5e5..aa993715d644 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -203,6 +203,7 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
203 acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL); 203 acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
204 return find.handle; 204 return find.handle;
205} 205}
206EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
206 207
207/* Get device's handler per its address under its parent */ 208/* Get device's handler per its address under its parent */
208struct acpi_find_child { 209struct acpi_find_child {
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 161db4acfb91..573b6a97bb1f 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -167,6 +167,19 @@ acpi_processor_power_activate(struct acpi_processor *pr,
167 return; 167 return;
168} 168}
169 169
170static void acpi_safe_halt(void)
171{
172 int polling = test_thread_flag(TIF_POLLING_NRFLAG);
173 if (polling) {
174 clear_thread_flag(TIF_POLLING_NRFLAG);
175 smp_mb__after_clear_bit();
176 }
177 if (!need_resched())
178 safe_halt();
179 if (polling)
180 set_thread_flag(TIF_POLLING_NRFLAG);
181}
182
170static atomic_t c3_cpu_count; 183static atomic_t c3_cpu_count;
171 184
172static void acpi_processor_idle(void) 185static void acpi_processor_idle(void)
@@ -177,7 +190,7 @@ static void acpi_processor_idle(void)
177 int sleep_ticks = 0; 190 int sleep_ticks = 0;
178 u32 t1, t2 = 0; 191 u32 t1, t2 = 0;
179 192
180 pr = processors[raw_smp_processor_id()]; 193 pr = processors[smp_processor_id()];
181 if (!pr) 194 if (!pr)
182 return; 195 return;
183 196
@@ -197,8 +210,13 @@ static void acpi_processor_idle(void)
197 } 210 }
198 211
199 cx = pr->power.state; 212 cx = pr->power.state;
200 if (!cx) 213 if (!cx) {
201 goto easy_out; 214 if (pm_idle_save)
215 pm_idle_save();
216 else
217 acpi_safe_halt();
218 return;
219 }
202 220
203 /* 221 /*
204 * Check BM Activity 222 * Check BM Activity
@@ -278,7 +296,8 @@ static void acpi_processor_idle(void)
278 if (pm_idle_save) 296 if (pm_idle_save)
279 pm_idle_save(); 297 pm_idle_save();
280 else 298 else
281 safe_halt(); 299 acpi_safe_halt();
300
282 /* 301 /*
283 * TBD: Can't get time duration while in C1, as resumes 302 * TBD: Can't get time duration while in C1, as resumes
284 * go to an ISR rather than here. Need to instrument 303 * go to an ISR rather than here. Need to instrument
@@ -414,16 +433,6 @@ static void acpi_processor_idle(void)
414 */ 433 */
415 if (next_state != pr->power.state) 434 if (next_state != pr->power.state)
416 acpi_processor_power_activate(pr, next_state); 435 acpi_processor_power_activate(pr, next_state);
417
418 return;
419
420 easy_out:
421 /* do C1 instead of busy loop */
422 if (pm_idle_save)
423 pm_idle_save();
424 else
425 safe_halt();
426 return;
427} 436}
428 437
429static int acpi_processor_set_power_policy(struct acpi_processor *pr) 438static int acpi_processor_set_power_policy(struct acpi_processor *pr)
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 0cded0468003..821c81e8cd38 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -1511,8 +1511,8 @@ static inline short setup_idle_tx_channel (hrz_dev * dev, hrz_vcc * vcc) {
1511 // a.k.a. prepare the channel and remember that we have done so. 1511 // a.k.a. prepare the channel and remember that we have done so.
1512 1512
1513 tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel]; 1513 tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel];
1514 u16 rd_ptr; 1514 u32 rd_ptr;
1515 u16 wr_ptr; 1515 u32 wr_ptr;
1516 u16 channel = vcc->channel; 1516 u16 channel = vcc->channel;
1517 1517
1518 unsigned long flags; 1518 unsigned long flags;
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 1468e8cf712d..0acbfff8ad28 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1816,7 +1816,6 @@ out_blkdev:
1816} 1816}
1817 1817
1818#ifdef MODULE 1818#ifdef MODULE
1819#include <linux/version.h>
1820 1819
1821int init_module(void) 1820int init_module(void)
1822{ 1821{
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5eadbb9d4d71..28002de783b6 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3714,6 +3714,12 @@ static int floppy_open(struct inode *inode, struct file *filp)
3714 USETF(FD_VERIFY); 3714 USETF(FD_VERIFY);
3715 } 3715 }
3716 3716
3717 /* set underlying gendisk policy to reflect real ro/rw status */
3718 if (UTESTF(FD_DISK_WRITABLE))
3719 inode->i_bdev->bd_disk->policy = 0;
3720 else
3721 inode->i_bdev->bd_disk->policy = 1;
3722
3717 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) 3723 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3718 goto out2; 3724 goto out2;
3719 3725
@@ -3770,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
3770 /* Allow ioctls if we have write-permissions even if read-only open. 3776 /* Allow ioctls if we have write-permissions even if read-only open.
3771 * Needed so that programs such as fdrawcmd still can work on write 3777 * Needed so that programs such as fdrawcmd still can work on write
3772 * protected disks */ 3778 * protected disks */
3773 if (filp->f_mode & 2 3779 if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
3774 || permission(filp->f_dentry->d_inode, 2, NULL) == 0)
3775 filp->private_data = (void *)8; 3780 filp->private_data = (void *)8;
3776 3781
3777 if (UFDCS->rawcmd == 1) 3782 if (UFDCS->rawcmd == 1)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a280e679b1ca..59e5982a5db3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -511,14 +511,11 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
511 */ 511 */
512static void pkt_iosched_process_queue(struct pktcdvd_device *pd) 512static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
513{ 513{
514 request_queue_t *q;
515 514
516 if (atomic_read(&pd->iosched.attention) == 0) 515 if (atomic_read(&pd->iosched.attention) == 0)
517 return; 516 return;
518 atomic_set(&pd->iosched.attention, 0); 517 atomic_set(&pd->iosched.attention, 0);
519 518
520 q = bdev_get_queue(pd->bdev);
521
522 for (;;) { 519 for (;;) {
523 struct bio *bio; 520 struct bio *bio;
524 int reads_queued, writes_queued; 521 int reads_queued, writes_queued;
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index ba54b5872578..b02fc2267159 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -389,7 +389,6 @@ static struct pci_device_id agp_ali_pci_table[] = {
389MODULE_DEVICE_TABLE(pci, agp_ali_pci_table); 389MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);
390 390
391static struct pci_driver agp_ali_pci_driver = { 391static struct pci_driver agp_ali_pci_driver = {
392 .owner = THIS_MODULE,
393 .name = "agpgart-ali", 392 .name = "agpgart-ali",
394 .id_table = agp_ali_pci_table, 393 .id_table = agp_ali_pci_table,
395 .probe = agp_ali_probe, 394 .probe = agp_ali_probe,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 40fcd88b2cea..1f776651ac64 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -515,7 +515,6 @@ static struct pci_device_id agp_amdk7_pci_table[] = {
515MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table); 515MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);
516 516
517static struct pci_driver agp_amdk7_pci_driver = { 517static struct pci_driver agp_amdk7_pci_driver = {
518 .owner = THIS_MODULE,
519 .name = "agpgart-amdk7", 518 .name = "agpgart-amdk7",
520 .id_table = agp_amdk7_pci_table, 519 .id_table = agp_amdk7_pci_table,
521 .probe = agp_amdk7_probe, 520 .probe = agp_amdk7_probe,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 8f748fddca94..78ce98a69f37 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -703,7 +703,6 @@ static struct pci_device_id agp_amd64_pci_table[] = {
703MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table); 703MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
704 704
705static struct pci_driver agp_amd64_pci_driver = { 705static struct pci_driver agp_amd64_pci_driver = {
706 .owner = THIS_MODULE,
707 .name = "agpgart-amd64", 706 .name = "agpgart-amd64",
708 .id_table = agp_amd64_pci_table, 707 .id_table = agp_amd64_pci_table,
709 .probe = agp_amd64_probe, 708 .probe = agp_amd64_probe,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index fbd415565463..53372a83b675 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -521,7 +521,6 @@ static struct pci_device_id agp_ati_pci_table[] = {
521MODULE_DEVICE_TABLE(pci, agp_ati_pci_table); 521MODULE_DEVICE_TABLE(pci, agp_ati_pci_table);
522 522
523static struct pci_driver agp_ati_pci_driver = { 523static struct pci_driver agp_ati_pci_driver = {
524 .owner = THIS_MODULE,
525 .name = "agpgart-ati", 524 .name = "agpgart-ati",
526 .id_table = agp_ati_pci_table, 525 .id_table = agp_ati_pci_table,
527 .probe = agp_ati_probe, 526 .probe = agp_ati_probe,
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 73f333f491bd..27bca34b4a65 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -147,6 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); 147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
150 flush_agp_mappings();
150 151
151 bridge->scratch_page_real = virt_to_gart(addr); 152 bridge->scratch_page_real = virt_to_gart(addr);
152 bridge->scratch_page = 153 bridge->scratch_page =
@@ -187,9 +188,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
187 return 0; 188 return 0;
188 189
189err_out: 190err_out:
190 if (bridge->driver->needs_scratch_page) 191 if (bridge->driver->needs_scratch_page) {
191 bridge->driver->agp_destroy_page( 192 bridge->driver->agp_destroy_page(
192 gart_to_virt(bridge->scratch_page_real)); 193 gart_to_virt(bridge->scratch_page_real));
194 flush_agp_mappings();
195 }
193 if (got_gatt) 196 if (got_gatt)
194 bridge->driver->free_gatt_table(bridge); 197 bridge->driver->free_gatt_table(bridge);
195 if (got_keylist) { 198 if (got_keylist) {
@@ -211,9 +214,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
211 bridge->key_list = NULL; 214 bridge->key_list = NULL;
212 215
213 if (bridge->driver->agp_destroy_page && 216 if (bridge->driver->agp_destroy_page &&
214 bridge->driver->needs_scratch_page) 217 bridge->driver->needs_scratch_page) {
215 bridge->driver->agp_destroy_page( 218 bridge->driver->agp_destroy_page(
216 gart_to_virt(bridge->scratch_page_real)); 219 gart_to_virt(bridge->scratch_page_real));
220 flush_agp_mappings();
221 }
217} 222}
218 223
219/* When we remove the global variable agp_bridge from all drivers 224/* When we remove the global variable agp_bridge from all drivers
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index d41e0a62e32e..e7aea77a60f9 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -429,7 +429,6 @@ static struct pci_device_id agp_efficeon_pci_table[] = {
429MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table); 429MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table);
430 430
431static struct pci_driver agp_efficeon_pci_driver = { 431static struct pci_driver agp_efficeon_pci_driver = {
432 .owner = THIS_MODULE,
433 .name = "agpgart-efficeon", 432 .name = "agpgart-efficeon",
434 .id_table = agp_efficeon_pci_table, 433 .id_table = agp_efficeon_pci_table,
435 .probe = agp_efficeon_probe, 434 .probe = agp_efficeon_probe,
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c4a38715c6f9..5567ce8d72b0 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -57,7 +57,8 @@ int map_page_into_agp(struct page *page)
57{ 57{
58 int i; 58 int i;
59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); 59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
60 global_flush_tlb(); 60 /* Caller's responsibility to call global_flush_tlb() for
61 * performance reasons */
61 return i; 62 return i;
62} 63}
63EXPORT_SYMBOL_GPL(map_page_into_agp); 64EXPORT_SYMBOL_GPL(map_page_into_agp);
@@ -66,7 +67,8 @@ int unmap_page_from_agp(struct page *page)
66{ 67{
67 int i; 68 int i;
68 i = change_page_attr(page, 1, PAGE_KERNEL); 69 i = change_page_attr(page, 1, PAGE_KERNEL);
69 global_flush_tlb(); 70 /* Caller's responsibility to call global_flush_tlb() for
71 * performance reasons */
70 return i; 72 return i;
71} 73}
72EXPORT_SYMBOL_GPL(unmap_page_from_agp); 74EXPORT_SYMBOL_GPL(unmap_page_from_agp);
@@ -153,6 +155,7 @@ void agp_free_memory(struct agp_memory *curr)
153 for (i = 0; i < curr->page_count; i++) { 155 for (i = 0; i < curr->page_count; i++) {
154 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); 156 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
155 } 157 }
158 flush_agp_mappings();
156 } 159 }
157 agp_free_key(curr->key); 160 agp_free_key(curr->key);
158 vfree(curr->memory); 161 vfree(curr->memory);
@@ -210,7 +213,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
210 new->memory[i] = virt_to_gart(addr); 213 new->memory[i] = virt_to_gart(addr);
211 new->page_count++; 214 new->page_count++;
212 } 215 }
213 new->bridge = bridge; 216 new->bridge = bridge;
214 217
215 flush_agp_mappings(); 218 flush_agp_mappings();
216 219
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 58944cd271ea..8ee19a4a6bce 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -111,8 +111,10 @@ static int i460_fetch_size (void)
111 111
112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) { 112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
113 printk(KERN_ERR PFX 113 printk(KERN_ERR PFX
114 "I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n", 114 "I/O (GART) page-size %luKB doesn't match expected "
115 1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT)); 115 "size %luKB\n",
116 1UL << (i460.io_page_shift - 10),
117 1UL << (I460_IO_PAGE_SHIFT));
116 return 0; 118 return 0;
117 } 119 }
118 120
@@ -514,9 +516,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
514{ 516{
515 void *page; 517 void *page;
516 518
517 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 519 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
518 page = agp_generic_alloc_page(agp_bridge); 520 page = agp_generic_alloc_page(agp_bridge);
519 else 521 global_flush_tlb();
522 } else
520 /* Returning NULL would cause problems */ 523 /* Returning NULL would cause problems */
521 /* AK: really dubious code. */ 524 /* AK: really dubious code. */
522 page = (void *)~0UL; 525 page = (void *)~0UL;
@@ -525,8 +528,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
525 528
526static void i460_destroy_page (void *page) 529static void i460_destroy_page (void *page)
527{ 530{
528 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 531 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
529 agp_generic_destroy_page(page); 532 agp_generic_destroy_page(page);
533 global_flush_tlb();
534 }
530} 535}
531 536
532#endif /* I460_LARGE_IO_PAGES */ 537#endif /* I460_LARGE_IO_PAGES */
@@ -536,7 +541,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
536{ 541{
537 /* Make sure the returned address is a valid GATT entry */ 542 /* Make sure the returned address is a valid GATT entry */
538 return bridge->driver->masks[0].mask 543 return bridge->driver->masks[0].mask
539 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12); 544 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
540} 545}
541 546
542struct agp_bridge_driver intel_i460_driver = { 547struct agp_bridge_driver intel_i460_driver = {
@@ -617,7 +622,6 @@ static struct pci_device_id agp_intel_i460_pci_table[] = {
617MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table); 622MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table);
618 623
619static struct pci_driver agp_intel_i460_pci_driver = { 624static struct pci_driver agp_intel_i460_pci_driver = {
620 .owner = THIS_MODULE,
621 .name = "agpgart-intel-i460", 625 .name = "agpgart-intel-i460",
622 .id_table = agp_intel_i460_pci_table, 626 .id_table = agp_intel_i460_pci_table,
623 .probe = agp_intel_i460_probe, 627 .probe = agp_intel_i460_probe,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index bf4cc9ffd5b1..e7bed5047dcc 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -270,6 +270,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
270 270
271 switch (pg_count) { 271 switch (pg_count) {
272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); 272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
273 global_flush_tlb();
273 break; 274 break;
274 case 4: 275 case 4:
275 /* kludge to get 4 physical pages for ARGB cursor */ 276 /* kludge to get 4 physical pages for ARGB cursor */
@@ -330,9 +331,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
330 if(curr->type == AGP_PHYS_MEMORY) { 331 if(curr->type == AGP_PHYS_MEMORY) {
331 if (curr->page_count == 4) 332 if (curr->page_count == 4)
332 i8xx_destroy_pages(gart_to_virt(curr->memory[0])); 333 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
333 else 334 else {
334 agp_bridge->driver->agp_destroy_page( 335 agp_bridge->driver->agp_destroy_page(
335 gart_to_virt(curr->memory[0])); 336 gart_to_virt(curr->memory[0]));
337 global_flush_tlb();
338 }
336 vfree(curr->memory); 339 vfree(curr->memory);
337 } 340 }
338 kfree(curr); 341 kfree(curr);
@@ -1824,7 +1827,6 @@ static struct pci_device_id agp_intel_pci_table[] = {
1824MODULE_DEVICE_TABLE(pci, agp_intel_pci_table); 1827MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
1825 1828
1826static struct pci_driver agp_intel_pci_driver = { 1829static struct pci_driver agp_intel_pci_driver = {
1827 .owner = THIS_MODULE,
1828 .name = "agpgart-intel", 1830 .name = "agpgart-intel",
1829 .id_table = agp_intel_pci_table, 1831 .id_table = agp_intel_pci_table,
1830 .probe = agp_intel_probe, 1832 .probe = agp_intel_probe,
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 3aed0c5e2f92..80dafa3030bd 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -398,7 +398,6 @@ static struct pci_device_id agp_nvidia_pci_table[] = {
398MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table); 398MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table);
399 399
400static struct pci_driver agp_nvidia_pci_driver = { 400static struct pci_driver agp_nvidia_pci_driver = {
401 .owner = THIS_MODULE,
402 .name = "agpgart-nvidia", 401 .name = "agpgart-nvidia",
403 .id_table = agp_nvidia_pci_table, 402 .id_table = agp_nvidia_pci_table,
404 .probe = agp_nvidia_probe, 403 .probe = agp_nvidia_probe,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index a701361a8890..ebc05554045c 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -332,7 +332,6 @@ static struct pci_device_id agp_sis_pci_table[] = {
332MODULE_DEVICE_TABLE(pci, agp_sis_pci_table); 332MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);
333 333
334static struct pci_driver agp_sis_pci_driver = { 334static struct pci_driver agp_sis_pci_driver = {
335 .owner = THIS_MODULE,
336 .name = "agpgart-sis", 335 .name = "agpgart-sis",
337 .id_table = agp_sis_pci_table, 336 .id_table = agp_sis_pci_table,
338 .probe = agp_sis_probe, 337 .probe = agp_sis_probe,
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 5a5392dd1254..3f8f7fa6b0ff 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -545,7 +545,6 @@ static struct pci_device_id agp_serverworks_pci_table[] = {
545MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table); 545MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table);
546 546
547static struct pci_driver agp_serverworks_pci_driver = { 547static struct pci_driver agp_serverworks_pci_driver = {
548 .owner = THIS_MODULE,
549 .name = "agpgart-serverworks", 548 .name = "agpgart-serverworks",
550 .id_table = agp_serverworks_pci_table, 549 .id_table = agp_serverworks_pci_table,
551 .probe = agp_serverworks_probe, 550 .probe = agp_serverworks_probe,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 183c50acab27..c8255312b8c1 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -658,7 +658,6 @@ static struct pci_device_id agp_uninorth_pci_table[] = {
658MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table); 658MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table);
659 659
660static struct pci_driver agp_uninorth_pci_driver = { 660static struct pci_driver agp_uninorth_pci_driver = {
661 .owner = THIS_MODULE,
662 .name = "agpgart-uninorth", 661 .name = "agpgart-uninorth",
663 .id_table = agp_uninorth_pci_table, 662 .id_table = agp_uninorth_pci_table,
664 .probe = agp_uninorth_probe, 663 .probe = agp_uninorth_probe,
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 5d9a13700074..c847df575cf5 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -518,7 +518,6 @@ MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
518 518
519 519
520static struct pci_driver agp_via_pci_driver = { 520static struct pci_driver agp_via_pci_driver = {
521 .owner = THIS_MODULE,
522 .name = "agpgart-via", 521 .name = "agpgart-via",
523 .id_table = agp_via_pci_table, 522 .id_table = agp_via_pci_table,
524 .probe = agp_via_probe, 523 .probe = agp_via_probe,
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 6d3fec160bff..efff0eec618c 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -203,10 +203,10 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
203 203
204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
205 if (gart_info->is_pcie) 205 if (gart_info->is_pcie)
206 *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc; 206 *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
207 else 207 else
208 *pci_gart = cpu_to_le32(page_base); 208 *pci_gart = cpu_to_le32(page_base);
209 *pci_gart++; 209 pci_gart++;
210 page_base += ATI_PCIGART_PAGE_SIZE; 210 page_base += ATI_PCIGART_PAGE_SIZE;
211 } 211 }
212 } 212 }
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index b7a0e4d6b934..407708a001e4 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -3113,7 +3113,6 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
3113int __init init_PCI (void) 3113int __init init_PCI (void)
3114{ /* Begin init_PCI */ 3114{ /* Begin init_PCI */
3115 memset (&epca_driver, 0, sizeof (epca_driver)); 3115 memset (&epca_driver, 0, sizeof (epca_driver));
3116 epca_driver.owner = THIS_MODULE;
3117 epca_driver.name = "epca"; 3116 epca_driver.name = "epca";
3118 epca_driver.id_table = epca_pci_tbl; 3117 epca_driver.id_table = epca_pci_tbl;
3119 epca_driver.probe = epca_init_one; 3118 epca_driver.probe = epca_init_one;
diff --git a/drivers/char/ip2.c b/drivers/char/ip2.c
index 6cd12f23aa58..7cadfc6ef352 100644
--- a/drivers/char/ip2.c
+++ b/drivers/char/ip2.c
@@ -7,7 +7,6 @@
7// 7//
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/version.h>
11#include <linux/init.h> 10#include <linux/init.h>
12#include <linux/wait.h> 11#include <linux/wait.h>
13 12
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index c1d06ba449b6..d16bd4b5c117 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2648,7 +2648,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
2648 spin_lock_irqsave(&intf->waiting_msgs_lock, flags); 2648 spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
2649 if (!list_empty(&intf->waiting_msgs)) { 2649 if (!list_empty(&intf->waiting_msgs)) {
2650 list_add_tail(&msg->link, &intf->waiting_msgs); 2650 list_add_tail(&msg->link, &intf->waiting_msgs);
2651 spin_unlock(&intf->waiting_msgs_lock); 2651 spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
2652 goto out; 2652 goto out;
2653 } 2653 }
2654 spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags); 2654 spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
@@ -2657,9 +2657,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
2657 if (rv > 0) { 2657 if (rv > 0) {
2658 /* Could not handle the message now, just add it to a 2658 /* Could not handle the message now, just add it to a
2659 list to handle later. */ 2659 list to handle later. */
2660 spin_lock(&intf->waiting_msgs_lock); 2660 spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
2661 list_add_tail(&msg->link, &intf->waiting_msgs); 2661 list_add_tail(&msg->link, &intf->waiting_msgs);
2662 spin_unlock(&intf->waiting_msgs_lock); 2662 spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
2663 } else if (rv == 0) { 2663 } else if (rv == 0) {
2664 ipmi_free_smi_msg(msg); 2664 ipmi_free_smi_msg(msg);
2665 } 2665 }
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index d6c72e0934e2..cc3e54dd7234 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -46,7 +46,6 @@
46* First release to the public 46* First release to the public
47*/ 47*/
48 48
49#include <linux/version.h>
50#include <linux/interrupt.h> 49#include <linux/interrupt.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/ptrace.h> 51#include <linux/ptrace.h>
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 3b965a651da4..26448f176803 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -38,7 +38,6 @@
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/version.h>
42#include <linux/autoconf.h> 41#include <linux/autoconf.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
44#include <linux/signal.h> 43#include <linux/signal.h>
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 352547eabf7b..0bbfce43031c 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -90,7 +90,6 @@
90#include <linux/fcntl.h> 90#include <linux/fcntl.h>
91#include <linux/major.h> 91#include <linux/major.h>
92#include <linux/delay.h> 92#include <linux/delay.h>
93#include <linux/version.h>
94#include <linux/pci.h> 93#include <linux/pci.h>
95#include <linux/init.h> 94#include <linux/init.h>
96#include <asm/uaccess.h> 95#include <asm/uaccess.h>
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 5d1ffa3bd4c3..82c6abde68df 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -912,7 +912,6 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
912MODULE_LICENSE("GPL"); 912MODULE_LICENSE("GPL");
913 913
914static struct pci_driver synclink_pci_driver = { 914static struct pci_driver synclink_pci_driver = {
915 .owner = THIS_MODULE,
916 .name = "synclink", 915 .name = "synclink",
917 .id_table = synclink_pci_tbl, 916 .id_table = synclink_pci_tbl,
918 .probe = synclink_init_one, 917 .probe = synclink_init_one,
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 7c063c5abc55..ee5a40be9f99 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -500,7 +500,6 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl);
500MODULE_LICENSE("GPL"); 500MODULE_LICENSE("GPL");
501 501
502static struct pci_driver synclinkmp_pci_driver = { 502static struct pci_driver synclinkmp_pci_driver = {
503 .owner = THIS_MODULE,
504 .name = "synclinkmp", 503 .name = "synclinkmp",
505 .id_table = synclinkmp_pci_tbl, 504 .id_table = synclinkmp_pci_tbl,
506 .probe = synclinkmp_init_one, 505 .probe = synclinkmp_init_one,
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index feb25158c8ee..145275ebdd7e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -354,7 +354,7 @@ struct sysrq_key_op *__sysrq_get_key_op (int key) {
354 return op_p; 354 return op_p;
355} 355}
356 356
357void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) { 357static void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) {
358 int i; 358 int i;
359 359
360 i = sysrq_key_table_key2index(key); 360 i = sysrq_key_table_key2index(key);
@@ -419,7 +419,7 @@ void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
419 __handle_sysrq(key, pt_regs, tty, 1); 419 __handle_sysrq(key, pt_regs, tty, 1);
420} 420}
421 421
422int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, 422static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
423 struct sysrq_key_op *remove_op_p) { 423 struct sysrq_key_op *remove_op_p) {
424 424
425 int retval; 425 int retval;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 99a60496ecc6..9293bcc4dc62 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/version.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/fs.h> 24#include <linux/fs.h>
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 98601c7d04a9..4d75c261f98a 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -26,7 +26,6 @@
26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */ 27 */
28#include <linux/config.h> 28#include <linux/config.h>
29#include <linux/version.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 867cc4e418c7..60aabdb4a046 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -32,7 +32,6 @@
32 * iseries/vio.h 32 * iseries/vio.h
33 */ 33 */
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/kernel.h> 36#include <linux/kernel.h>
38#include <linux/errno.h> 37#include <linux/errno.h>
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index d9ef55bdf88a..2451edbefece 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -755,7 +755,6 @@ static struct pci_device_id pcipcwd_pci_tbl[] = {
755MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl); 755MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
756 756
757static struct pci_driver pcipcwd_driver = { 757static struct pci_driver pcipcwd_driver = {
758 .owner = THIS_MODULE,
759 .name = WATCHDOG_NAME, 758 .name = WATCHDOG_NAME,
760 .id_table = pcipcwd_pci_tbl, 759 .id_table = pcipcwd_pci_tbl,
761 .probe = pcipcwd_card_init, 760 .probe = pcipcwd_card_init,
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index dc9370f6c348..4b3311993d48 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -711,7 +711,6 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
711 711
712 712
713static struct pci_driver wdtpci_driver = { 713static struct pci_driver wdtpci_driver = {
714 .owner = THIS_MODULE,
715 .name = "wdt_pci", 714 .name = "wdt_pci",
716 .id_table = wdtpci_pci_tbl, 715 .id_table = wdtpci_pci_tbl,
717 .probe = wdtpci_init_one, 716 .probe = wdtpci_init_one,
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 25acf478c9e8..23a63207d747 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -38,7 +38,6 @@ static struct cpufreq_driver *cpufreq_driver;
38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; 38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
39static DEFINE_SPINLOCK(cpufreq_driver_lock); 39static DEFINE_SPINLOCK(cpufreq_driver_lock);
40 40
41
42/* internal prototypes */ 41/* internal prototypes */
43static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); 42static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
44static void handle_update(void *data); 43static void handle_update(void *data);
@@ -1115,24 +1114,21 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1115 int retval = -EINVAL; 1114 int retval = -EINVAL;
1116 1115
1117 /* 1116 /*
1118 * Converted the lock_cpu_hotplug to preempt_disable() 1117 * If we are already in context of hotplug thread, we dont need to
1119 * and preempt_enable(). This is a bit kludgy and relies on how cpu 1118 * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent
1120 * hotplug works. All we need is a guarantee that cpu hotplug won't make 1119 * hotplug from removing this cpu that we are working on.
1121 * progress on any cpu. Once we do preempt_disable(), this would ensure
1122 * that hotplug threads don't get onto this cpu, thereby delaying
1123 * the cpu remove process.
1124 *
1125 * We removed the lock_cpu_hotplug since we need to call this function
1126 * via cpu hotplug callbacks, which result in locking the cpu hotplug
1127 * thread itself. Agree this is not very clean, cpufreq community
1128 * could improve this if required. - Ashok Raj <ashok.raj@intel.com>
1129 */ 1120 */
1130 preempt_disable(); 1121 if (!current_in_cpu_hotplug())
1122 lock_cpu_hotplug();
1123
1131 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, 1124 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
1132 target_freq, relation); 1125 target_freq, relation);
1133 if (cpu_online(policy->cpu) && cpufreq_driver->target) 1126 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1134 retval = cpufreq_driver->target(policy, target_freq, relation); 1127 retval = cpufreq_driver->target(policy, target_freq, relation);
1135 preempt_enable(); 1128
1129 if (!current_in_cpu_hotplug())
1130 unlock_cpu_hotplug();
1131
1136 return retval; 1132 return retval;
1137} 1133}
1138EXPORT_SYMBOL_GPL(__cpufreq_driver_target); 1134EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index ba17292eb290..6d83299e7c9b 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -34,7 +34,6 @@
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details. 35 * GNU General Public License for more details.
36 */ 36 */
37#include <linux/version.h>
38#include <linux/config.h> 37#include <linux/config.h>
39#include <linux/init.h> 38#include <linux/init.h>
40#include <linux/module.h> 39#include <linux/module.h>
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 3bf05d5d0c82..c81bd4bce1b8 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -60,9 +60,11 @@
60 60
61#define HDAPS_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */ 61#define HDAPS_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
62#define HDAPS_INPUT_FUZZ 4 /* input event threshold */ 62#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
63#define HDAPS_INPUT_FLAT 4
63 64
64static struct timer_list hdaps_timer; 65static struct timer_list hdaps_timer;
65static struct platform_device *pdev; 66static struct platform_device *pdev;
67static struct input_dev *hdaps_idev;
66static unsigned int hdaps_invert; 68static unsigned int hdaps_invert;
67static u8 km_activity; 69static u8 km_activity;
68static int rest_x; 70static int rest_x;
@@ -310,18 +312,6 @@ static struct platform_driver hdaps_driver = {
310 }, 312 },
311}; 313};
312 314
313/* Input class stuff */
314
315static struct input_dev hdaps_idev = {
316 .name = "hdaps",
317 .evbit = { BIT(EV_ABS) },
318 .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
319 .absmin = { [ABS_X] = -256, [ABS_Y] = -256 },
320 .absmax = { [ABS_X] = 256, [ABS_Y] = 256 },
321 .absfuzz = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
322 .absflat = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
323};
324
325/* 315/*
326 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem. 316 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
327 */ 317 */
@@ -343,9 +333,9 @@ static void hdaps_mousedev_poll(unsigned long unused)
343 if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y)) 333 if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y))
344 goto out; 334 goto out;
345 335
346 input_report_abs(&hdaps_idev, ABS_X, x - rest_x); 336 input_report_abs(hdaps_idev, ABS_X, x - rest_x);
347 input_report_abs(&hdaps_idev, ABS_Y, y - rest_y); 337 input_report_abs(hdaps_idev, ABS_Y, y - rest_y);
348 input_sync(&hdaps_idev); 338 input_sync(hdaps_idev);
349 339
350 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); 340 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
351 341
@@ -565,12 +555,25 @@ static int __init hdaps_init(void)
565 if (ret) 555 if (ret)
566 goto out_device; 556 goto out_device;
567 557
558 hdaps_idev = input_allocate_device();
559 if (!hdaps_idev) {
560 ret = -ENOMEM;
561 goto out_group;
562 }
563
568 /* initial calibrate for the input device */ 564 /* initial calibrate for the input device */
569 hdaps_calibrate(); 565 hdaps_calibrate();
570 566
571 /* initialize the input class */ 567 /* initialize the input class */
572 hdaps_idev.dev = &pdev->dev; 568 hdaps_idev->name = "hdaps";
573 input_register_device(&hdaps_idev); 569 hdaps_idev->cdev.dev = &pdev->dev;
570 hdaps_idev->evbit[0] = BIT(EV_ABS);
571 input_set_abs_params(hdaps_idev, ABS_X,
572 -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
573 input_set_abs_params(hdaps_idev, ABS_X,
574 -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
575
576 input_register_device(hdaps_idev);
574 577
575 /* start up our timer for the input device */ 578 /* start up our timer for the input device */
576 init_timer(&hdaps_timer); 579 init_timer(&hdaps_timer);
@@ -581,6 +584,8 @@ static int __init hdaps_init(void)
581 printk(KERN_INFO "hdaps: driver successfully loaded.\n"); 584 printk(KERN_INFO "hdaps: driver successfully loaded.\n");
582 return 0; 585 return 0;
583 586
587out_group:
588 sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
584out_device: 589out_device:
585 platform_device_unregister(pdev); 590 platform_device_unregister(pdev);
586out_driver: 591out_driver:
@@ -595,7 +600,7 @@ out:
595static void __exit hdaps_exit(void) 600static void __exit hdaps_exit(void)
596{ 601{
597 del_timer_sync(&hdaps_timer); 602 del_timer_sync(&hdaps_timer);
598 input_unregister_device(&hdaps_idev); 603 input_unregister_device(hdaps_idev);
599 sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group); 604 sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
600 platform_device_unregister(pdev); 605 platform_device_unregister(pdev);
601 platform_driver_unregister(&hdaps_driver); 606 platform_driver_unregister(&hdaps_driver);
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 70ef926c3bd8..4e9a04e1f08e 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -180,11 +180,10 @@ superio_exit(void)
180#define W83781D_REG_BANK 0x4E 180#define W83781D_REG_BANK 0x4E
181 181
182#define W83781D_REG_CONFIG 0x40 182#define W83781D_REG_CONFIG 0x40
183#define W83781D_REG_ALARM1 0x41 183#define W83781D_REG_ALARM1 0x459
184#define W83781D_REG_ALARM2 0x42 184#define W83781D_REG_ALARM2 0x45A
185#define W83781D_REG_ALARM3 0x450 185#define W83781D_REG_ALARM3 0x45B
186 186
187#define W83781D_REG_IRQ 0x4C
188#define W83781D_REG_BEEP_CONFIG 0x4D 187#define W83781D_REG_BEEP_CONFIG 0x4D
189#define W83781D_REG_BEEP_INTS1 0x56 188#define W83781D_REG_BEEP_INTS1 0x56
190#define W83781D_REG_BEEP_INTS2 0x57 189#define W83781D_REG_BEEP_INTS2 0x57
@@ -1370,13 +1369,6 @@ static void w83627hf_init_client(struct i2c_client *client)
1370 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); 1369 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
1371 } 1370 }
1372 } 1371 }
1373
1374 /* enable comparator mode for temp2 and temp3 so
1375 alarm indication will work correctly */
1376 i = w83627hf_read_value(client, W83781D_REG_IRQ);
1377 if (!(i & 0x40))
1378 w83627hf_write_value(client, W83781D_REG_IRQ,
1379 i | 0x40);
1380 } 1372 }
1381 1373
1382 /* Start monitoring */ 1374 /* Start monitoring */
@@ -1400,7 +1392,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1400 /* skip missing sensors */ 1392 /* skip missing sensors */
1401 if (((data->type == w83697hf) && (i == 1)) || 1393 if (((data->type == w83697hf) && (i == 1)) ||
1402 ((data->type == w83627thf || data->type == w83637hf) 1394 ((data->type == w83627thf || data->type == w83637hf)
1403 && (i == 4 || i == 5))) 1395 && (i == 5 || i == 6)))
1404 continue; 1396 continue;
1405 data->in[i] = 1397 data->in[i] =
1406 w83627hf_read_value(client, W83781D_REG_IN(i)); 1398 w83627hf_read_value(client, W83781D_REG_IN(i));
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index ba90f5140af6..3eb47890db40 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -513,7 +513,6 @@ static void __devexit ali1535_remove(struct pci_dev *dev)
513} 513}
514 514
515static struct pci_driver ali1535_driver = { 515static struct pci_driver ali1535_driver = {
516 .owner = THIS_MODULE,
517 .name = "ali1535_smbus", 516 .name = "ali1535_smbus",
518 .id_table = ali1535_ids, 517 .id_table = ali1535_ids,
519 .probe = ali1535_probe, 518 .probe = ali1535_probe,
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index f1a62d892425..e6f63208fc4a 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -408,7 +408,6 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = {
408MODULE_DEVICE_TABLE (pci, ali1563_id_table); 408MODULE_DEVICE_TABLE (pci, ali1563_id_table);
409 409
410static struct pci_driver ali1563_pci_driver = { 410static struct pci_driver ali1563_pci_driver = {
411 .owner = THIS_MODULE,
412 .name = "ali1563_smbus", 411 .name = "ali1563_smbus",
413 .id_table = ali1563_id_table, 412 .id_table = ali1563_id_table,
414 .probe = ali1563_probe, 413 .probe = ali1563_probe,
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index 400b08ed4299..7a5c0941dbc1 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -504,7 +504,6 @@ static void __devexit ali15x3_remove(struct pci_dev *dev)
504} 504}
505 505
506static struct pci_driver ali15x3_driver = { 506static struct pci_driver ali15x3_driver = {
507 .owner = THIS_MODULE,
508 .name = "ali15x3_smbus", 507 .name = "ali15x3_smbus",
509 .id_table = ali15x3_ids, 508 .id_table = ali15x3_ids,
510 .probe = ali15x3_probe, 509 .probe = ali15x3_probe,
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index de035d137c3f..1750dedaf4b5 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -401,7 +401,6 @@ static void __devexit amd756_remove(struct pci_dev *dev)
401} 401}
402 402
403static struct pci_driver amd756_driver = { 403static struct pci_driver amd756_driver = {
404 .owner = THIS_MODULE,
405 .name = "amd756_smbus", 404 .name = "amd756_smbus",
406 .id_table = amd756_ids, 405 .id_table = amd756_ids,
407 .probe = amd756_probe, 406 .probe = amd756_probe,
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index f3b79a68dbec..e5ef560e686a 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -384,7 +384,6 @@ static void __devexit amd8111_remove(struct pci_dev *dev)
384} 384}
385 385
386static struct pci_driver amd8111_driver = { 386static struct pci_driver amd8111_driver = {
387 .owner = THIS_MODULE,
388 .name = "amd8111_smbus2", 387 .name = "amd8111_smbus2",
389 .id_table = amd8111_ids, 388 .id_table = amd8111_ids,
390 .probe = amd8111_probe, 389 .probe = amd8111_probe,
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 1b5354e24bf5..e0cb3b0f92fa 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -155,7 +155,6 @@ static void __devexit hydra_remove(struct pci_dev *dev)
155 155
156 156
157static struct pci_driver hydra_driver = { 157static struct pci_driver hydra_driver = {
158 .owner = THIS_MODULE,
159 .name = "hydra_smbus", 158 .name = "hydra_smbus",
160 .id_table = hydra_ids, 159 .id_table = hydra_ids,
161 .probe = hydra_probe, 160 .probe = hydra_probe,
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 4f63195069da..ac3eafa8aac0 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -560,7 +560,6 @@ static void __devexit i801_remove(struct pci_dev *dev)
560} 560}
561 561
562static struct pci_driver i801_driver = { 562static struct pci_driver i801_driver = {
563 .owner = THIS_MODULE,
564 .name = "i801_smbus", 563 .name = "i801_smbus",
565 .id_table = i801_ids, 564 .id_table = i801_ids,
566 .probe = i801_probe, 565 .probe = i801_probe,
diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
index 52bc30593bd7..748be30f2bae 100644
--- a/drivers/i2c/busses/i2c-i810.c
+++ b/drivers/i2c/busses/i2c-i810.c
@@ -233,7 +233,6 @@ static void __devexit i810_remove(struct pci_dev *dev)
233} 233}
234 234
235static struct pci_driver i810_driver = { 235static struct pci_driver i810_driver = {
236 .owner = THIS_MODULE,
237 .name = "i810_smbus", 236 .name = "i810_smbus",
238 .id_table = i810_ids, 237 .id_table = i810_ids,
239 .probe = i810_probe, 238 .probe = i810_probe,
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index fd26036e68a3..4d18e6e5f159 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -347,7 +347,6 @@ static void __devexit nforce2_remove(struct pci_dev *dev)
347} 347}
348 348
349static struct pci_driver nforce2_driver = { 349static struct pci_driver nforce2_driver = {
350 .owner = THIS_MODULE,
351 .name = "nForce2_smbus", 350 .name = "nForce2_smbus",
352 .id_table = nforce2_ids, 351 .id_table = nforce2_ids,
353 .probe = nforce2_probe, 352 .probe = nforce2_probe,
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 7d63eec423fe..692f47345481 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -462,7 +462,6 @@ static void __devexit piix4_remove(struct pci_dev *dev)
462} 462}
463 463
464static struct pci_driver piix4_driver = { 464static struct pci_driver piix4_driver = {
465 .owner = THIS_MODULE,
466 .name = "piix4_smbus", 465 .name = "piix4_smbus",
467 .id_table = piix4_ids, 466 .id_table = piix4_ids,
468 .probe = piix4_probe, 467 .probe = piix4_probe,
diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
index 42cb1d8ca659..9479525892e3 100644
--- a/drivers/i2c/busses/i2c-prosavage.c
+++ b/drivers/i2c/busses/i2c-prosavage.c
@@ -301,7 +301,6 @@ static struct pci_device_id prosavage_pci_tbl[] = {
301MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl); 301MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl);
302 302
303static struct pci_driver prosavage_driver = { 303static struct pci_driver prosavage_driver = {
304 .owner = THIS_MODULE,
305 .name = "prosavage_smbus", 304 .name = "prosavage_smbus",
306 .id_table = prosavage_pci_tbl, 305 .id_table = prosavage_pci_tbl,
307 .probe = prosavage_probe, 306 .probe = prosavage_probe,
diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
index aebe87ba4033..0c8518298e4d 100644
--- a/drivers/i2c/busses/i2c-savage4.c
+++ b/drivers/i2c/busses/i2c-savage4.c
@@ -179,7 +179,6 @@ static void __devexit savage4_remove(struct pci_dev *dev)
179} 179}
180 180
181static struct pci_driver savage4_driver = { 181static struct pci_driver savage4_driver = {
182 .owner = THIS_MODULE,
183 .name = "savage4_smbus", 182 .name = "savage4_smbus",
184 .id_table = savage4_ids, 183 .id_table = savage4_ids,
185 .probe = savage4_probe, 184 .probe = savage4_probe,
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 3ad27c3ba15b..b57ab74d23ec 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -398,7 +398,6 @@ static void __devexit sis5595_remove(struct pci_dev *dev)
398} 398}
399 399
400static struct pci_driver sis5595_driver = { 400static struct pci_driver sis5595_driver = {
401 .owner = THIS_MODULE,
402 .name = "sis5595_smbus", 401 .name = "sis5595_smbus",
403 .id_table = sis5595_ids, 402 .id_table = sis5595_ids,
404 .probe = sis5595_probe, 403 .probe = sis5595_probe,
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 7f49e5fd3ff0..acb75e282414 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -496,7 +496,6 @@ static void __devexit sis630_remove(struct pci_dev *dev)
496 496
497 497
498static struct pci_driver sis630_driver = { 498static struct pci_driver sis630_driver = {
499 .owner = THIS_MODULE,
500 .name = "sis630_smbus", 499 .name = "sis630_smbus",
501 .id_table = sis630_ids, 500 .id_table = sis630_ids,
502 .probe = sis630_probe, 501 .probe = sis630_probe,
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index 6a134c091324..3024907cdafe 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -329,7 +329,6 @@ static void __devexit sis96x_remove(struct pci_dev *dev)
329} 329}
330 330
331static struct pci_driver sis96x_driver = { 331static struct pci_driver sis96x_driver = {
332 .owner = THIS_MODULE,
333 .name = "sis96x_smbus", 332 .name = "sis96x_smbus",
334 .id_table = sis96x_ids, 333 .id_table = sis96x_ids,
335 .probe = sis96x_probe, 334 .probe = sis96x_probe,
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 544a38e64394..484bbacfce6b 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -159,7 +159,6 @@ static void __devexit vt586b_remove(struct pci_dev *dev)
159 159
160 160
161static struct pci_driver vt586b_driver = { 161static struct pci_driver vt586b_driver = {
162 .owner = THIS_MODULE,
163 .name = "vt586b_smbus", 162 .name = "vt586b_smbus",
164 .id_table = vt586b_ids, 163 .id_table = vt586b_ids,
165 .probe = vt586b_probe, 164 .probe = vt586b_probe,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index c9366b504833..47e52bf2c5ec 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -142,19 +142,18 @@ static int vt596_transaction(u8 size)
142 /* Make sure the SMBus host is ready to start transmitting */ 142 /* Make sure the SMBus host is ready to start transmitting */
143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " 144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
145 "Resetting... ", temp); 145 "Resetting...\n", temp);
146 146
147 outb_p(temp, SMBHSTSTS); 147 outb_p(temp, SMBHSTSTS);
148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
149 printk("Failed! (0x%02x)\n", temp); 149 dev_err(&vt596_adapter.dev, "SMBus reset failed! "
150 "(0x%02x)\n", temp);
150 return -1; 151 return -1;
151 } else {
152 printk("Successful!\n");
153 } 152 }
154 } 153 }
155 154
156 /* Start the transaction by setting bit 6 */ 155 /* Start the transaction by setting bit 6 */
157 outb_p(0x40 | (size & 0x3C), SMBHSTCNT); 156 outb_p(0x40 | size, SMBHSTCNT);
158 157
159 /* We will always wait for a fraction of a second */ 158 /* We will always wait for a fraction of a second */
160 do { 159 do {
@@ -171,7 +170,7 @@ static int vt596_transaction(u8 size)
171 if (temp & 0x10) { 170 if (temp & 0x10) {
172 result = -1; 171 result = -1;
173 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", 172 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
174 inb_p(SMBHSTCNT) & 0x3C); 173 size);
175 } 174 }
176 175
177 if (temp & 0x08) { 176 if (temp & 0x08) {
@@ -180,11 +179,13 @@ static int vt596_transaction(u8 size)
180 } 179 }
181 180
182 if (temp & 0x04) { 181 if (temp & 0x04) {
182 int read = inb_p(SMBHSTADD) & 0x01;
183 result = -1; 183 result = -1;
184 /* Quick commands are used to probe for chips, so 184 /* The quick and receive byte commands are used to probe
185 errors are expected, and we don't want to frighten the 185 for chips, so errors are expected, and we don't want
186 user. */ 186 to frighten the user. */
187 if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK) 187 if (!((size == VT596_QUICK && !read) ||
188 (size == VT596_BYTE && read)))
188 dev_err(&vt596_adapter.dev, "Transaction error!\n"); 189 dev_err(&vt596_adapter.dev, "Transaction error!\n");
189 } 190 }
190 191
@@ -439,7 +440,6 @@ static struct pci_device_id vt596_ids[] = {
439MODULE_DEVICE_TABLE(pci, vt596_ids); 440MODULE_DEVICE_TABLE(pci, vt596_ids);
440 441
441static struct pci_driver vt596_driver = { 442static struct pci_driver vt596_driver = {
442 .owner = THIS_MODULE,
443 .name = "vt596_smbus", 443 .name = "vt596_smbus",
444 .id_table = vt596_ids, 444 .id_table = vt596_ids,
445 .probe = vt596_probe, 445 .probe = vt596_probe,
@@ -462,9 +462,9 @@ static void __exit i2c_vt596_exit(void)
462 } 462 }
463} 463}
464 464
465MODULE_AUTHOR( 465MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "
466 "Frodo Looijaard <frodol@dds.nl> and " 466 "Mark D. Studebaker <mdsxyz123@yahoo.com> and "
467 "Philip Edelbrock <phil@netroedge.com>"); 467 "Jean Delvare <khali@linux-fr.org>");
468MODULE_DESCRIPTION("vt82c596 SMBus driver"); 468MODULE_DESCRIPTION("vt82c596 SMBus driver");
469MODULE_LICENSE("GPL"); 469MODULE_LICENSE("GPL");
470 470
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
index 650c3ebde84c..b675773b0cc1 100644
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -225,7 +225,6 @@ static void __devexit voodoo3_remove(struct pci_dev *dev)
225} 225}
226 226
227static struct pci_driver voodoo3_driver = { 227static struct pci_driver voodoo3_driver = {
228 .owner = THIS_MODULE,
229 .name = "voodoo3_smbus", 228 .name = "voodoo3_smbus",
230 .id_table = voodoo3_ids, 229 .id_table = voodoo3_ids,
231 .probe = voodoo3_probe, 230 .probe = voodoo3_probe,
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
index 01b037007410..02682fb794c8 100644
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -164,9 +164,9 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
164 buf[1] = BIN2BCD(dt->tm_sec); 164 buf[1] = BIN2BCD(dt->tm_sec);
165 buf[2] = BIN2BCD(dt->tm_min); 165 buf[2] = BIN2BCD(dt->tm_min);
166 buf[3] = BIN2BCD(dt->tm_hour); 166 buf[3] = BIN2BCD(dt->tm_hour);
167 buf[4] = BIN2BCD(dt->tm_wday) + 1; 167 buf[4] = BIN2BCD(dt->tm_wday + 1);
168 buf[5] = BIN2BCD(dt->tm_mday); 168 buf[5] = BIN2BCD(dt->tm_mday);
169 buf[6] = BIN2BCD(dt->tm_mon) + 1; 169 buf[6] = BIN2BCD(dt->tm_mon + 1);
170 val = dt->tm_year; 170 val = dt->tm_year;
171 if (val >= 100) { 171 if (val >= 100) {
172 val -= 100; 172 val -= 100;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index a737886e39d1..42e5b8175cbf 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -539,6 +539,15 @@ config BLK_DEV_CS5530
539 539
540 It is safe to say Y to this question. 540 It is safe to say Y to this question.
541 541
542config BLK_DEV_CS5535
543 tristate "AMD CS5535 chipset support"
544 depends on X86 && !X86_64
545 help
546 Include support for UDMA on the NSC/AMD CS5535 companion chipset.
547 This will automatically be detected and configured if found.
548
549 It is safe to say Y to this question.
550
542config BLK_DEV_HPT34X 551config BLK_DEV_HPT34X
543 tristate "HPT34X chipset support" 552 tristate "HPT34X chipset support"
544 help 553 help
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index e83f54d37f96..f615ab759962 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2038,11 +2038,9 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); 2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
2039 ide_drive_t *drive = floppy->drive; 2039 ide_drive_t *drive = floppy->drive;
2040 void __user *argp = (void __user *)arg; 2040 void __user *argp = (void __user *)arg;
2041 int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); 2041 int err;
2042 int prevent = (arg) ? 1 : 0; 2042 int prevent = (arg) ? 1 : 0;
2043 idefloppy_pc_t pc; 2043 idefloppy_pc_t pc;
2044 if (err != -EINVAL)
2045 return err;
2046 2044
2047 switch (cmd) { 2045 switch (cmd) {
2048 case CDROMEJECT: 2046 case CDROMEJECT:
@@ -2094,7 +2092,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2094 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: 2092 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
2095 return idefloppy_get_format_progress(drive, argp); 2093 return idefloppy_get_format_progress(drive, argp);
2096 } 2094 }
2097 return -EINVAL; 2095 return generic_ide_ioctl(drive, file, bdev, cmd, arg);
2098} 2096}
2099 2097
2100static int idefloppy_media_changed(struct gendisk *disk) 2098static int idefloppy_media_changed(struct gendisk *disk)
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 0b0aa4f51628..af7af958ab3e 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -104,8 +104,6 @@ void default_hwif_iops (ide_hwif_t *hwif)
104 hwif->INSL = ide_insl; 104 hwif->INSL = ide_insl;
105} 105}
106 106
107EXPORT_SYMBOL(default_hwif_iops);
108
109/* 107/*
110 * MMIO operations, typically used for SATA controllers 108 * MMIO operations, typically used for SATA controllers
111 */ 109 */
@@ -329,8 +327,6 @@ void default_hwif_transport(ide_hwif_t *hwif)
329 hwif->atapi_output_bytes = atapi_output_bytes; 327 hwif->atapi_output_bytes = atapi_output_bytes;
330} 328}
331 329
332EXPORT_SYMBOL(default_hwif_transport);
333
334/* 330/*
335 * Beginning of Taskfile OPCODE Library and feature sets. 331 * Beginning of Taskfile OPCODE Library and feature sets.
336 */ 332 */
@@ -529,8 +525,6 @@ int wait_for_ready (ide_drive_t *drive, int timeout)
529 return 0; 525 return 0;
530} 526}
531 527
532EXPORT_SYMBOL(wait_for_ready);
533
534/* 528/*
535 * This routine busy-waits for the drive status to be not "busy". 529 * This routine busy-waits for the drive status to be not "busy".
536 * It then checks the status for all of the "good" bits and none 530 * It then checks the status for all of the "good" bits and none
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 7ec18fa3b5ff..54f9639c2a8c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -161,8 +161,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
161 return ide_stopped; 161 return ide_stopped;
162} 162}
163 163
164EXPORT_SYMBOL(do_rw_taskfile);
165
166/* 164/*
167 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. 165 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
168 */ 166 */
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 9fe19808d815..8af179b531c3 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -803,6 +803,7 @@ found:
803 hwif->irq = hw->irq; 803 hwif->irq = hw->irq;
804 hwif->noprobe = 0; 804 hwif->noprobe = 0;
805 hwif->chipset = hw->chipset; 805 hwif->chipset = hw->chipset;
806 hwif->gendev.parent = hw->dev;
806 807
807 if (!initializing) { 808 if (!initializing) {
808 probe_hwif_init_with_fixup(hwif, fixup); 809 probe_hwif_init_with_fixup(hwif, fixup);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 1dafffa7e513..ef79805218e4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -182,13 +182,14 @@ static void ide_detach(dev_link_t *link)
182 182
183} /* ide_detach */ 183} /* ide_detach */
184 184
185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) 185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
186{ 186{
187 hw_regs_t hw; 187 hw_regs_t hw;
188 memset(&hw, 0, sizeof(hw)); 188 memset(&hw, 0, sizeof(hw));
189 ide_init_hwif_ports(&hw, io, ctl, NULL); 189 ide_init_hwif_ports(&hw, io, ctl, NULL);
190 hw.irq = irq; 190 hw.irq = irq;
191 hw.chipset = ide_pci; 191 hw.chipset = ide_pci;
192 hw.dev = &handle->dev;
192 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); 193 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
193} 194}
194 195
@@ -327,12 +328,12 @@ static void ide_config(dev_link_t *link)
327 328
328 /* retry registration in case device is still spinning up */ 329 /* retry registration in case device is still spinning up */
329 for (hd = -1, i = 0; i < 10; i++) { 330 for (hd = -1, i = 0; i < 10; i++) {
330 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); 331 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle);
331 if (hd >= 0) break; 332 if (hd >= 0) break;
332 if (link->io.NumPorts1 == 0x20) { 333 if (link->io.NumPorts1 == 0x20) {
333 outb(0x02, ctl_base + 0x10); 334 outb(0x02, ctl_base + 0x10);
334 hd = idecs_register(io_base + 0x10, ctl_base + 0x10, 335 hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
335 link->irq.AssignedIRQ); 336 link->irq.AssignedIRQ, handle);
336 if (hd >= 0) { 337 if (hd >= 0) {
337 io_base += 0x10; 338 io_base += 0x10;
338 ctl_base += 0x10; 339 ctl_base += 0x10;
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index af46226c1796..f35d684edc25 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o
6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o 6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o 7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o 8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
9obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
9obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o 10obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
10obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o 11obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
11obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o 12obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 844a6c9fb949..21965e5ef25e 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -74,6 +74,7 @@ static struct amd_ide_chip {
74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, 74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, 75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 },
76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, 76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 },
77 { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
77 { 0 } 78 { 0 }
78}; 79};
79 80
@@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
491 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), 492 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
492 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), 493 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
493 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), 494 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
495 /* 17 */ DECLARE_AMD_DEV("AMD5536"),
494}; 496};
495 497
496static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) 498static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
527 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, 529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
528 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, 530 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, 531 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
532 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
530 { 0, }, 533 { 0, },
531}; 534};
532MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); 535MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
new file mode 100644
index 000000000000..6eb305197f3c
--- /dev/null
+++ b/drivers/ide/pci/cs5535.c
@@ -0,0 +1,305 @@
1/*
2 * linux/drivers/ide/pci/cs5535.c
3 *
4 * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
5 *
6 * History:
7 * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
8 * - Reworked tuneproc, set_drive, misc mods to prep for mainline
9 * - Work was sponsored by CIS (M) Sdn Bhd.
10 * Ported to Kernel 2.6.11 on June 26, 2005 by
11 * Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
12 * Alexander Kiausch <alex.kiausch@t-online.de>
13 * Originally developed by AMD for 2.4/2.6
14 *
15 * Development of this chipset driver was funded
16 * by the nice folks at National Semiconductor/AMD.
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License version 2 as published by
20 * the Free Software Foundation.
21 *
22 * Documentation:
23 * CS5535 documentation available from AMD
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/ide.h>
30
31#include "ide-timing.h"
32
33#define MSR_ATAC_BASE 0x51300000
34#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
35#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
36#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02)
37#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03)
38#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04)
39#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05)
40#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08)
41#define ATAC_RESET (MSR_ATAC_BASE+0x10)
42#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20)
43#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21)
44#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22)
45#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23)
46#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24)
47#define ATAC_BM0_CMD_PRIM 0x00
48#define ATAC_BM0_STS_PRIM 0x02
49#define ATAC_BM0_PRD 0x04
50#define CS5535_CABLE_DETECT 0x48
51
52/* Format I PIO settings. We seperate out cmd and data for safer timings */
53
54static unsigned int cs5535_pio_cmd_timings[5] =
55{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 };
56static unsigned int cs5535_pio_dta_timings[5] =
57{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 };
58
59static unsigned int cs5535_mwdma_timings[3] =
60{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 };
61
62static unsigned int cs5535_udma_timings[5] =
63{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 };
64
65/* Macros to check if the register is the reset value - reset value is an
66 invalid timing and indicates the register has not been set previously */
67
68#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 )
69#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 )
70
71/****
72 * cs5535_set_speed - Configure the chipset to the new speed
73 * @drive: Drive to set up
74 * @speed: desired speed
75 *
76 * cs5535_set_speed() configures the chipset to a new speed.
77 */
78static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
79{
80
81 u32 reg = 0, dummy;
82 int unit = drive->select.b.unit;
83
84
85 /* Set the PIO timings */
86 if ((speed & XFER_MODE) == XFER_PIO) {
87 u8 pioa;
88 u8 piob;
89 u8 cmd;
90
91 pioa = speed - XFER_PIO_0;
92 piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
93 255, 4, NULL);
94 cmd = pioa < piob ? pioa : piob;
95
96 /* Write the speed of the current drive */
97 reg = (cs5535_pio_cmd_timings[cmd] << 16) |
98 cs5535_pio_dta_timings[pioa];
99 wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
100
101 /* And if nessesary - change the speed of the other drive */
102 rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy);
103
104 if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) !=
105 cs5535_pio_cmd_timings[cmd]) {
106 reg &= 0x0000FFFF;
107 reg |= cs5535_pio_cmd_timings[cmd] << 16;
108 wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0);
109 }
110
111 /* Set bit 31 of the DMA register for PIO format 1 timings */
112 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
113 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA,
114 reg | 0x80000000UL, 0);
115 } else {
116 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
117
118 reg &= 0x80000000UL; /* Preserve the PIO format bit */
119
120 if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
121 reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
122 else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
123 reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
124 else
125 return;
126
127 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0);
128 }
129}
130
131static u8 cs5535_ratemask(ide_drive_t *drive)
132{
133 /* eighty93 will return 1 if it's 80core and capable of
134 exceeding udma2, 0 otherwise. we need ratemask to set
135 the max speed and if we can > udma2 then we return 2
136 which selects speed_max as udma4 which is the 5535's max
137 speed, and 1 selects udma2 which is the max for 40c */
138 if (!eighty_ninty_three(drive))
139 return 1;
140
141 return 2;
142}
143
144
145/****
146 * cs5535_set_drive - Configure the drive to the new speed
147 * @drive: Drive to set up
148 * @speed: desired speed
149 *
150 * cs5535_set_drive() configures the drive and the chipset to a
151 * new speed. It also can be called by upper layers.
152 */
153static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
154{
155 speed = ide_rate_filter(cs5535_ratemask(drive), speed);
156 ide_config_drive_speed(drive, speed);
157 cs5535_set_speed(drive, speed);
158
159 return 0;
160}
161
162/****
163 * cs5535_tuneproc - PIO setup
164 * @drive: drive to set up
165 * @pio: mode to use (255 for 'best possible')
166 *
167 * A callback from the upper layers for PIO-only tuning.
168 */
169static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
170{
171 u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
172 XFER_PIO_4 };
173
174 /* cs5535 max pio is pio 4, best_pio will check the blacklist.
175 i think we don't need to rate_filter the incoming xferspeed
176 since we know we're only going to choose pio */
177 xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
178 ide_config_drive_speed(drive, modes[xferspeed]);
179 cs5535_set_speed(drive, xferspeed);
180}
181
182static int cs5535_config_drive_for_dma(ide_drive_t *drive)
183{
184 u8 speed;
185
186 speed = ide_dma_speed(drive, cs5535_ratemask(drive));
187
188 /* If no DMA speed was available then let dma_check hit pio */
189 if (!speed) {
190 return 0;
191 }
192
193 cs5535_set_drive(drive, speed);
194 return ide_dma_enable(drive);
195}
196
197static int cs5535_dma_check(ide_drive_t *drive)
198{
199 ide_hwif_t *hwif = drive->hwif;
200 struct hd_driveid *id = drive->id;
201 u8 speed;
202
203 drive->init_speed = 0;
204
205 if ((id->capability & 1) && drive->autodma) {
206 if (ide_use_dma(drive)) {
207 if (cs5535_config_drive_for_dma(drive))
208 return hwif->ide_dma_on(drive);
209 }
210
211 goto fast_ata_pio;
212
213 } else if ((id->capability & 8) || (id->field_valid & 2)) {
214fast_ata_pio:
215 speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
216 cs5535_set_drive(drive, speed);
217 return hwif->ide_dma_off_quietly(drive);
218 }
219 /* IORDY not supported */
220 return 0;
221}
222
223static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
224{
225 u8 bit;
226
227 /* if a 80 wire cable was detected */
228 pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
229 return (bit & 1);
230}
231
232/****
233 * init_hwif_cs5535 - Initialize one ide cannel
234 * @hwif: Channel descriptor
235 *
236 * This gets invoked by the IDE driver once for each channel. It
237 * performs channel-specific pre-initialization before drive probing.
238 *
239 */
240static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
241{
242 int i;
243
244 hwif->autodma = 0;
245
246 hwif->tuneproc = &cs5535_tuneproc;
247 hwif->speedproc = &cs5535_set_drive;
248 hwif->ide_dma_check = &cs5535_dma_check;
249
250 hwif->atapi_dma = 1;
251 hwif->ultra_mask = 0x1F;
252 hwif->mwdma_mask = 0x07;
253
254
255 hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
256
257 if (!noautodma)
258 hwif->autodma = 1;
259
260 /* just setting autotune and not worrying about bios timings */
261 for (i = 0; i < 2; i++) {
262 hwif->drives[i].autotune = 1;
263 hwif->drives[i].autodma = hwif->autodma;
264 }
265}
266
267static ide_pci_device_t cs5535_chipset __devinitdata = {
268 .name = "CS5535",
269 .init_hwif = init_hwif_cs5535,
270 .channels = 1,
271 .autodma = AUTODMA,
272 .bootable = ON_BOARD,
273};
274
275static int __devinit cs5535_init_one(struct pci_dev *dev,
276 const struct pci_device_id *id)
277{
278 return ide_setup_pci_device(dev, &cs5535_chipset);
279}
280
281static struct pci_device_id cs5535_pci_tbl[] =
282{
283 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
284 PCI_ANY_ID, 0, 0, 0},
285 { 0, },
286};
287
288MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl);
289
290static struct pci_driver driver = {
291 .name = "CS5535_IDE",
292 .id_table = cs5535_pci_tbl,
293 .probe = cs5535_init_one,
294};
295
296static int __init cs5535_ide_init(void)
297{
298 return ide_pci_register_driver(&driver);
299}
300
301module_init(cs5535_ide_init);
302
303MODULE_AUTHOR("AMD");
304MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE");
305MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 5a33513f3dd1..9f41ecd56338 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -469,7 +469,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
469 469
470static __devinitdata ide_hwif_t *primary; 470static __devinitdata ide_hwif_t *primary;
471 471
472void __devinit init_iops_cy82c693(ide_hwif_t *hwif) 472static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
473{ 473{
474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1) 474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
475 primary = hwif; 475 primary = hwif;
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 2b9961b88135..022d244f2eb0 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -701,6 +701,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
701 unsigned long barsize = pci_resource_len(dev, 5); 701 unsigned long barsize = pci_resource_len(dev, 5);
702 u8 tmpbyte = 0; 702 u8 tmpbyte = 0;
703 void __iomem *ioaddr; 703 void __iomem *ioaddr;
704 u32 tmp, irq_mask;
704 705
705 /* 706 /*
706 * Drop back to PIO if we can't map the mmio. Some 707 * Drop back to PIO if we can't map the mmio. Some
@@ -726,6 +727,14 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
726 pci_set_drvdata(dev, (void *) ioaddr); 727 pci_set_drvdata(dev, (void *) ioaddr);
727 728
728 if (pdev_is_sata(dev)) { 729 if (pdev_is_sata(dev)) {
730 /* make sure IDE0/1 interrupts are not masked */
731 irq_mask = (1 << 22) | (1 << 23);
732 tmp = readl(ioaddr + 0x48);
733 if (tmp & irq_mask) {
734 tmp &= ~irq_mask;
735 writel(tmp, ioaddr + 0x48);
736 readl(ioaddr + 0x48); /* flush */
737 }
729 writel(0, ioaddr + 0x148); 738 writel(0, ioaddr + 0x148);
730 writel(0, ioaddr + 0x1C8); 739 writel(0, ioaddr + 0x1C8);
731 } 740 }
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 18ed7765417c..d4f2111d4364 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -787,8 +787,9 @@ static int pre_init = 1; /* Before first ordered IDE scan */
787static LIST_HEAD(ide_pci_drivers); 787static LIST_HEAD(ide_pci_drivers);
788 788
789/* 789/*
790 * ide_register_pci_driver - attach IDE driver 790 * __ide_register_pci_driver - attach IDE driver
791 * @driver: pci driver 791 * @driver: pci driver
792 * @module: owner module of the driver
792 * 793 *
793 * Registers a driver with the IDE layer. The IDE layer arranges that 794 * Registers a driver with the IDE layer. The IDE layer arranges that
794 * boot time setup is done in the expected device order and then 795 * boot time setup is done in the expected device order and then
@@ -801,15 +802,16 @@ static LIST_HEAD(ide_pci_drivers);
801 * Returns are the same as for pci_register_driver 802 * Returns are the same as for pci_register_driver
802 */ 803 */
803 804
804int ide_pci_register_driver(struct pci_driver *driver) 805int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
805{ 806{
806 if(!pre_init) 807 if(!pre_init)
807 return pci_module_init(driver); 808 return __pci_register_driver(driver, module);
809 driver->driver.owner = module;
808 list_add_tail(&driver->node, &ide_pci_drivers); 810 list_add_tail(&driver->node, &ide_pci_drivers);
809 return 0; 811 return 0;
810} 812}
811 813
812EXPORT_SYMBOL_GPL(ide_pci_register_driver); 814EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
813 815
814/** 816/**
815 * ide_unregister_pci_driver - unregister an IDE driver 817 * ide_unregister_pci_driver - unregister an IDE driver
@@ -897,6 +899,6 @@ void __init ide_scan_pcibus (int scan_direction)
897 { 899 {
898 list_del(l); 900 list_del(l);
899 d = list_entry(l, struct pci_driver, node); 901 d = list_entry(l, struct pci_driver, node);
900 pci_register_driver(d); 902 __pci_register_driver(d, d->driver.owner);
901 } 903 }
902} 904}
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index aed5ca23fb22..5ea741f47fc8 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -31,7 +31,7 @@
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE. 32 * SOFTWARE.
33 * 33 *
34 * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $ 34 * $Id: user_mad.c 4010 2005-11-09 23:11:56Z roland $
35 */ 35 */
36 36
37#include <linux/module.h> 37#include <linux/module.h>
@@ -110,13 +110,13 @@ struct ib_umad_device {
110}; 110};
111 111
112struct ib_umad_file { 112struct ib_umad_file {
113 struct ib_umad_port *port; 113 struct ib_umad_port *port;
114 struct list_head recv_list; 114 struct list_head recv_list;
115 struct list_head port_list; 115 struct list_head port_list;
116 spinlock_t recv_lock; 116 spinlock_t recv_lock;
117 wait_queue_head_t recv_wait; 117 wait_queue_head_t recv_wait;
118 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; 118 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
119 struct ib_mr *mr[IB_UMAD_MAX_AGENTS]; 119 int agents_dead;
120}; 120};
121 121
122struct ib_umad_packet { 122struct ib_umad_packet {
@@ -145,6 +145,12 @@ static void ib_umad_release_dev(struct kref *ref)
145 kfree(dev); 145 kfree(dev);
146} 146}
147 147
148/* caller must hold port->mutex at least for reading */
149static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id)
150{
151 return file->agents_dead ? NULL : file->agent[id];
152}
153
148static int queue_packet(struct ib_umad_file *file, 154static int queue_packet(struct ib_umad_file *file,
149 struct ib_mad_agent *agent, 155 struct ib_mad_agent *agent,
150 struct ib_umad_packet *packet) 156 struct ib_umad_packet *packet)
@@ -152,10 +158,11 @@ static int queue_packet(struct ib_umad_file *file,
152 int ret = 1; 158 int ret = 1;
153 159
154 down_read(&file->port->mutex); 160 down_read(&file->port->mutex);
161
155 for (packet->mad.hdr.id = 0; 162 for (packet->mad.hdr.id = 0;
156 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; 163 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
157 packet->mad.hdr.id++) 164 packet->mad.hdr.id++)
158 if (agent == file->agent[packet->mad.hdr.id]) { 165 if (agent == __get_agent(file, packet->mad.hdr.id)) {
159 spin_lock_irq(&file->recv_lock); 166 spin_lock_irq(&file->recv_lock);
160 list_add_tail(&packet->list, &file->recv_list); 167 list_add_tail(&packet->list, &file->recv_list);
161 spin_unlock_irq(&file->recv_lock); 168 spin_unlock_irq(&file->recv_lock);
@@ -327,7 +334,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
327 334
328 down_read(&file->port->mutex); 335 down_read(&file->port->mutex);
329 336
330 agent = file->agent[packet->mad.hdr.id]; 337 agent = __get_agent(file, packet->mad.hdr.id);
331 if (!agent) { 338 if (!agent) {
332 ret = -EINVAL; 339 ret = -EINVAL;
333 goto err_up; 340 goto err_up;
@@ -481,7 +488,7 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
481 } 488 }
482 489
483 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) 490 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
484 if (!file->agent[agent_id]) 491 if (!__get_agent(file, agent_id))
485 goto found; 492 goto found;
486 493
487 ret = -ENOMEM; 494 ret = -ENOMEM;
@@ -505,29 +512,15 @@ found:
505 goto out; 512 goto out;
506 } 513 }
507 514
508 file->agent[agent_id] = agent;
509
510 file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
511 if (IS_ERR(file->mr[agent_id])) {
512 ret = -ENOMEM;
513 goto err;
514 }
515
516 if (put_user(agent_id, 515 if (put_user(agent_id,
517 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { 516 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) {
518 ret = -EFAULT; 517 ret = -EFAULT;
519 goto err_mr; 518 ib_unregister_mad_agent(agent);
519 goto out;
520 } 520 }
521 521
522 file->agent[agent_id] = agent;
522 ret = 0; 523 ret = 0;
523 goto out;
524
525err_mr:
526 ib_dereg_mr(file->mr[agent_id]);
527
528err:
529 file->agent[agent_id] = NULL;
530 ib_unregister_mad_agent(agent);
531 524
532out: 525out:
533 up_write(&file->port->mutex); 526 up_write(&file->port->mutex);
@@ -536,27 +529,29 @@ out:
536 529
537static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) 530static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
538{ 531{
532 struct ib_mad_agent *agent = NULL;
539 u32 id; 533 u32 id;
540 int ret = 0; 534 int ret = 0;
541 535
542 down_write(&file->port->mutex); 536 if (get_user(id, (u32 __user *) arg))
537 return -EFAULT;
543 538
544 if (get_user(id, (u32 __user *) arg)) { 539 down_write(&file->port->mutex);
545 ret = -EFAULT;
546 goto out;
547 }
548 540
549 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) { 541 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) {
550 ret = -EINVAL; 542 ret = -EINVAL;
551 goto out; 543 goto out;
552 } 544 }
553 545
554 ib_dereg_mr(file->mr[id]); 546 agent = file->agent[id];
555 ib_unregister_mad_agent(file->agent[id]);
556 file->agent[id] = NULL; 547 file->agent[id] = NULL;
557 548
558out: 549out:
559 up_write(&file->port->mutex); 550 up_write(&file->port->mutex);
551
552 if (agent)
553 ib_unregister_mad_agent(agent);
554
560 return ret; 555 return ret;
561} 556}
562 557
@@ -621,23 +616,29 @@ static int ib_umad_close(struct inode *inode, struct file *filp)
621 struct ib_umad_file *file = filp->private_data; 616 struct ib_umad_file *file = filp->private_data;
622 struct ib_umad_device *dev = file->port->umad_dev; 617 struct ib_umad_device *dev = file->port->umad_dev;
623 struct ib_umad_packet *packet, *tmp; 618 struct ib_umad_packet *packet, *tmp;
619 int already_dead;
624 int i; 620 int i;
625 621
626 down_write(&file->port->mutex); 622 down_write(&file->port->mutex);
627 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) 623
628 if (file->agent[i]) { 624 already_dead = file->agents_dead;
629 ib_dereg_mr(file->mr[i]); 625 file->agents_dead = 1;
630 ib_unregister_mad_agent(file->agent[i]);
631 }
632 626
633 list_for_each_entry_safe(packet, tmp, &file->recv_list, list) 627 list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
634 kfree(packet); 628 kfree(packet);
635 629
636 list_del(&file->port_list); 630 list_del(&file->port_list);
637 up_write(&file->port->mutex);
638 631
639 kfree(file); 632 downgrade_write(&file->port->mutex);
633
634 if (!already_dead)
635 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
636 if (file->agent[i])
637 ib_unregister_mad_agent(file->agent[i]);
638
639 up_read(&file->port->mutex);
640 640
641 kfree(file);
641 kref_put(&dev->ref, ib_umad_release_dev); 642 kref_put(&dev->ref, ib_umad_release_dev);
642 643
643 return 0; 644 return 0;
@@ -801,7 +802,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
801 goto err_class; 802 goto err_class;
802 port->sm_dev->owner = THIS_MODULE; 803 port->sm_dev->owner = THIS_MODULE;
803 port->sm_dev->ops = &umad_sm_fops; 804 port->sm_dev->ops = &umad_sm_fops;
804 kobject_set_name(&port->dev->kobj, "issm%d", port->dev_num); 805 kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num);
805 if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) 806 if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
806 goto err_sm_cdev; 807 goto err_sm_cdev;
807 808
@@ -863,14 +864,36 @@ static void ib_umad_kill_port(struct ib_umad_port *port)
863 864
864 port->ib_dev = NULL; 865 port->ib_dev = NULL;
865 866
866 list_for_each_entry(file, &port->file_list, port_list) 867 /*
867 for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) { 868 * Now go through the list of files attached to this port and
868 if (!file->agent[id]) 869 * unregister all of their MAD agents. We need to hold
869 continue; 870 * port->mutex while doing this to avoid racing with
870 ib_dereg_mr(file->mr[id]); 871 * ib_umad_close(), but we can't hold the mutex for writing
871 ib_unregister_mad_agent(file->agent[id]); 872 * while calling ib_unregister_mad_agent(), since that might
872 file->agent[id] = NULL; 873 * deadlock by calling back into queue_packet(). So we
873 } 874 * downgrade our lock to a read lock, and then drop and
875 * reacquire the write lock for the next iteration.
876 *
877 * We do list_del_init() on the file's list_head so that the
878 * list_del in ib_umad_close() is still OK, even after the
879 * file is removed from the list.
880 */
881 while (!list_empty(&port->file_list)) {
882 file = list_entry(port->file_list.next, struct ib_umad_file,
883 port_list);
884
885 file->agents_dead = 1;
886 list_del_init(&file->port_list);
887
888 downgrade_write(&port->mutex);
889
890 for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id)
891 if (file->agent[id])
892 ib_unregister_mad_agent(file->agent[id]);
893
894 up_read(&port->mutex);
895 down_write(&port->mutex);
896 }
874 897
875 up_write(&port->mutex); 898 up_write(&port->mutex);
876 899
@@ -913,7 +936,7 @@ static void ib_umad_add_one(struct ib_device *device)
913 936
914err: 937err:
915 while (--i >= s) 938 while (--i >= s)
916 ib_umad_kill_port(&umad_dev->port[i]); 939 ib_umad_kill_port(&umad_dev->port[i - s]);
917 940
918 kref_put(&umad_dev->ref, ib_umad_release_dev); 941 kref_put(&umad_dev->ref, ib_umad_release_dev);
919} 942}
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 63a74151c60b..ed45da892b1c 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -708,7 +708,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
708 resp->wc[i].opcode = wc[i].opcode; 708 resp->wc[i].opcode = wc[i].opcode;
709 resp->wc[i].vendor_err = wc[i].vendor_err; 709 resp->wc[i].vendor_err = wc[i].vendor_err;
710 resp->wc[i].byte_len = wc[i].byte_len; 710 resp->wc[i].byte_len = wc[i].byte_len;
711 resp->wc[i].imm_data = wc[i].imm_data; 711 resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data;
712 resp->wc[i].qp_num = wc[i].qp_num; 712 resp->wc[i].qp_num = wc[i].qp_num;
713 resp->wc[i].src_qp = wc[i].src_qp; 713 resp->wc[i].src_qp = wc[i].src_qp;
714 resp->wc[i].wc_flags = wc[i].wc_flags; 714 resp->wc[i].wc_flags = wc[i].wc_flags;
@@ -908,7 +908,12 @@ retry:
908 if (ret) 908 if (ret)
909 goto err_destroy; 909 goto err_destroy;
910 910
911 resp.qp_handle = uobj->uobject.id; 911 resp.qp_handle = uobj->uobject.id;
912 resp.max_recv_sge = attr.cap.max_recv_sge;
913 resp.max_send_sge = attr.cap.max_send_sge;
914 resp.max_recv_wr = attr.cap.max_recv_wr;
915 resp.max_send_wr = attr.cap.max_send_wr;
916 resp.max_inline_data = attr.cap.max_inline_data;
912 917
913 if (copy_to_user((void __user *) (unsigned long) cmd.response, 918 if (copy_to_user((void __user *) (unsigned long) cmd.response,
914 &resp, sizeof resp)) { 919 &resp, sizeof resp)) {
@@ -1135,7 +1140,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1135 next->num_sge = user_wr->num_sge; 1140 next->num_sge = user_wr->num_sge;
1136 next->opcode = user_wr->opcode; 1141 next->opcode = user_wr->opcode;
1137 next->send_flags = user_wr->send_flags; 1142 next->send_flags = user_wr->send_flags;
1138 next->imm_data = user_wr->imm_data; 1143 next->imm_data = (__be32 __force) user_wr->imm_data;
1139 1144
1140 if (qp->qp_type == IB_QPT_UD) { 1145 if (qp->qp_type == IB_QPT_UD) {
1141 next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, 1146 next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr,
@@ -1701,7 +1706,6 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1701 } 1706 }
1702 1707
1703 attr.max_wr = cmd.max_wr; 1708 attr.max_wr = cmd.max_wr;
1704 attr.max_sge = cmd.max_sge;
1705 attr.srq_limit = cmd.srq_limit; 1709 attr.srq_limit = cmd.srq_limit;
1706 1710
1707 ret = ib_modify_srq(srq, &attr, cmd.attr_mask); 1711 ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 4186cc888ea5..4c15e112736c 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -325,16 +325,8 @@ EXPORT_SYMBOL(ib_destroy_cq);
325int ib_resize_cq(struct ib_cq *cq, 325int ib_resize_cq(struct ib_cq *cq,
326 int cqe) 326 int cqe)
327{ 327{
328 int ret; 328 return cq->device->resize_cq ?
329 329 cq->device->resize_cq(cq, cqe) : -ENOSYS;
330 if (!cq->device->resize_cq)
331 return -ENOSYS;
332
333 ret = cq->device->resize_cq(cq, &cqe);
334 if (!ret)
335 cq->cqe = cqe;
336
337 return ret;
338} 330}
339EXPORT_SYMBOL(ib_resize_cq); 331EXPORT_SYMBOL(ib_resize_cq);
340 332
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index 25ebab64bc42..c3bec7490f52 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -97,7 +97,7 @@ static void poll_catas(unsigned long dev_ptr)
97 } 97 }
98 98
99 spin_lock_irqsave(&catas_lock, flags); 99 spin_lock_irqsave(&catas_lock, flags);
100 if (dev->catas_err.stop) 100 if (!dev->catas_err.stop)
101 mod_timer(&dev->catas_err.timer, 101 mod_timer(&dev->catas_err.timer,
102 jiffies + MTHCA_CATAS_POLL_INTERVAL); 102 jiffies + MTHCA_CATAS_POLL_INTERVAL);
103 spin_unlock_irqrestore(&catas_lock, flags); 103 spin_unlock_irqrestore(&catas_lock, flags);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 49f211d55df7..9ed34587fc5c 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1060,6 +1060,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1060 dev_lim->hca.arbel.resize_srq = field & 1; 1060 dev_lim->hca.arbel.resize_srq = field & 1;
1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); 1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
1062 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg); 1062 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg);
1063 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MAX_DESC_SZ_RQ_OFFSET);
1064 dev_lim->max_desc_sz = min_t(int, size, dev_lim->max_desc_sz);
1063 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET); 1065 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
1064 dev_lim->mpt_entry_sz = size; 1066 dev_lim->mpt_entry_sz = size;
1065 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET); 1067 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index f98e23555826..4a8adcef2079 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -258,7 +258,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
258{ 258{
259 struct mthca_cq *cq; 259 struct mthca_cq *cq;
260 struct mthca_cqe *cqe; 260 struct mthca_cqe *cqe;
261 int prod_index; 261 u32 prod_index;
262 int nfreed = 0; 262 int nfreed = 0;
263 263
264 spin_lock_irq(&dev->cq_table.lock); 264 spin_lock_irq(&dev->cq_table.lock);
@@ -293,19 +293,15 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
293 * Now sweep backwards through the CQ, removing CQ entries 293 * Now sweep backwards through the CQ, removing CQ entries
294 * that match our QP by copying older entries on top of them. 294 * that match our QP by copying older entries on top of them.
295 */ 295 */
296 while (prod_index > cq->cons_index) { 296 while ((int) --prod_index - (int) cq->cons_index >= 0) {
297 cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe); 297 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
298 if (cqe->my_qpn == cpu_to_be32(qpn)) { 298 if (cqe->my_qpn == cpu_to_be32(qpn)) {
299 if (srq) 299 if (srq)
300 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); 300 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
301 ++nfreed; 301 ++nfreed;
302 } 302 } else if (nfreed)
303 else if (nfreed) 303 memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe),
304 memcpy(get_cqe(cq, (prod_index - 1 + nfreed) & 304 cqe, MTHCA_CQ_ENTRY_SIZE);
305 cq->ibcq.cqe),
306 cqe,
307 MTHCA_CQ_ENTRY_SIZE);
308 --prod_index;
309 } 305 }
310 306
311 if (nfreed) { 307 if (nfreed) {
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index e7e5d3b4f004..497ff794ef6a 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -131,6 +131,7 @@ struct mthca_limits {
131 int max_sg; 131 int max_sg;
132 int num_qps; 132 int num_qps;
133 int max_wqes; 133 int max_wqes;
134 int max_desc_sz;
134 int max_qp_init_rdma; 135 int max_qp_init_rdma;
135 int reserved_qps; 136 int reserved_qps;
136 int num_srqs; 137 int num_srqs;
@@ -154,6 +155,7 @@ struct mthca_limits {
154 int reserved_mcgs; 155 int reserved_mcgs;
155 int num_pds; 156 int num_pds;
156 int reserved_pds; 157 int reserved_pds;
158 u32 page_size_cap;
157 u32 flags; 159 u32 flags;
158 u8 port_width_cap; 160 u8 port_width_cap;
159}; 161};
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 45c6328e780c..6f94b25f3acd 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -168,6 +168,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
168 mdev->limits.max_srq_wqes = dev_lim->max_srq_sz; 168 mdev->limits.max_srq_wqes = dev_lim->max_srq_sz;
169 mdev->limits.reserved_srqs = dev_lim->reserved_srqs; 169 mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
170 mdev->limits.reserved_eecs = dev_lim->reserved_eecs; 170 mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
171 mdev->limits.max_desc_sz = dev_lim->max_desc_sz;
171 /* 172 /*
172 * Subtract 1 from the limit because we need to allocate a 173 * Subtract 1 from the limit because we need to allocate a
173 * spare CQE so the HCA HW can tell the difference between an 174 * spare CQE so the HCA HW can tell the difference between an
@@ -181,6 +182,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
181 mdev->limits.reserved_uars = dev_lim->reserved_uars; 182 mdev->limits.reserved_uars = dev_lim->reserved_uars;
182 mdev->limits.reserved_pds = dev_lim->reserved_pds; 183 mdev->limits.reserved_pds = dev_lim->reserved_pds;
183 mdev->limits.port_width_cap = dev_lim->max_port_width; 184 mdev->limits.port_width_cap = dev_lim->max_port_width;
185 mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1);
184 mdev->limits.flags = dev_lim->flags; 186 mdev->limits.flags = dev_lim->flags;
185 187
186 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. 188 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
@@ -1196,7 +1198,6 @@ MODULE_DEVICE_TABLE(pci, mthca_pci_table);
1196 1198
1197static struct pci_driver mthca_driver = { 1199static struct pci_driver mthca_driver = {
1198 .name = DRV_NAME, 1200 .name = DRV_NAME,
1199 .owner = THIS_MODULE,
1200 .id_table = mthca_pci_table, 1201 .id_table = mthca_pci_table,
1201 .probe = mthca_init_one, 1202 .probe = mthca_init_one,
1202 .remove = __devexit_p(mthca_remove_one) 1203 .remove = __devexit_p(mthca_remove_one)
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 6b0166668269..4cc7e2846df1 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -90,6 +90,7 @@ static int mthca_query_device(struct ib_device *ibdev,
90 memcpy(&props->node_guid, out_mad->data + 12, 8); 90 memcpy(&props->node_guid, out_mad->data + 12, 8);
91 91
92 props->max_mr_size = ~0ull; 92 props->max_mr_size = ~0ull;
93 props->page_size_cap = mdev->limits.page_size_cap;
93 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps; 94 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
94 props->max_qp_wr = mdev->limits.max_wqes; 95 props->max_qp_wr = mdev->limits.max_wqes;
95 props->max_sge = mdev->limits.max_sg; 96 props->max_sge = mdev->limits.max_sg;
@@ -615,11 +616,11 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
615 return ERR_PTR(err); 616 return ERR_PTR(err);
616 } 617 }
617 618
618 init_attr->cap.max_inline_data = 0;
619 init_attr->cap.max_send_wr = qp->sq.max; 619 init_attr->cap.max_send_wr = qp->sq.max;
620 init_attr->cap.max_recv_wr = qp->rq.max; 620 init_attr->cap.max_recv_wr = qp->rq.max;
621 init_attr->cap.max_send_sge = qp->sq.max_gs; 621 init_attr->cap.max_send_sge = qp->sq.max_gs;
622 init_attr->cap.max_recv_sge = qp->rq.max_gs; 622 init_attr->cap.max_recv_sge = qp->rq.max_gs;
623 init_attr->cap.max_inline_data = qp->max_inline_data;
623 624
624 return &qp->ibqp; 625 return &qp->ibqp;
625} 626}
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index bcd4b01a339c..1e73947b4702 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -251,6 +251,7 @@ struct mthca_qp {
251 struct mthca_wq sq; 251 struct mthca_wq sq;
252 enum ib_sig_type sq_policy; 252 enum ib_sig_type sq_policy;
253 int send_wqe_offset; 253 int send_wqe_offset;
254 int max_inline_data;
254 255
255 u64 *wrid; 256 u64 *wrid;
256 union mthca_buf queue; 257 union mthca_buf queue;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 8852ea477c21..760c418d5bc9 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -885,6 +885,48 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
885 return err; 885 return err;
886} 886}
887 887
888static void mthca_adjust_qp_caps(struct mthca_dev *dev,
889 struct mthca_pd *pd,
890 struct mthca_qp *qp)
891{
892 int max_data_size;
893
894 /*
895 * Calculate the maximum size of WQE s/g segments, excluding
896 * the next segment and other non-data segments.
897 */
898 max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) -
899 sizeof (struct mthca_next_seg);
900
901 switch (qp->transport) {
902 case MLX:
903 max_data_size -= 2 * sizeof (struct mthca_data_seg);
904 break;
905
906 case UD:
907 if (mthca_is_memfree(dev))
908 max_data_size -= sizeof (struct mthca_arbel_ud_seg);
909 else
910 max_data_size -= sizeof (struct mthca_tavor_ud_seg);
911 break;
912
913 default:
914 max_data_size -= sizeof (struct mthca_raddr_seg);
915 break;
916 }
917
918 /* We don't support inline data for kernel QPs (yet). */
919 if (!pd->ibpd.uobject)
920 qp->max_inline_data = 0;
921 else
922 qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
923
924 qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
925 qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
926 sizeof (struct mthca_next_seg)) /
927 sizeof (struct mthca_data_seg);
928}
929
888/* 930/*
889 * Allocate and register buffer for WQEs. qp->rq.max, sq.max, 931 * Allocate and register buffer for WQEs. qp->rq.max, sq.max,
890 * rq.max_gs and sq.max_gs must all be assigned. 932 * rq.max_gs and sq.max_gs must all be assigned.
@@ -902,27 +944,53 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
902 size = sizeof (struct mthca_next_seg) + 944 size = sizeof (struct mthca_next_seg) +
903 qp->rq.max_gs * sizeof (struct mthca_data_seg); 945 qp->rq.max_gs * sizeof (struct mthca_data_seg);
904 946
947 if (size > dev->limits.max_desc_sz)
948 return -EINVAL;
949
905 for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size; 950 for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size;
906 qp->rq.wqe_shift++) 951 qp->rq.wqe_shift++)
907 ; /* nothing */ 952 ; /* nothing */
908 953
909 size = sizeof (struct mthca_next_seg) + 954 size = qp->sq.max_gs * sizeof (struct mthca_data_seg);
910 qp->sq.max_gs * sizeof (struct mthca_data_seg);
911 switch (qp->transport) { 955 switch (qp->transport) {
912 case MLX: 956 case MLX:
913 size += 2 * sizeof (struct mthca_data_seg); 957 size += 2 * sizeof (struct mthca_data_seg);
914 break; 958 break;
959
915 case UD: 960 case UD:
916 if (mthca_is_memfree(dev)) 961 size += mthca_is_memfree(dev) ?
917 size += sizeof (struct mthca_arbel_ud_seg); 962 sizeof (struct mthca_arbel_ud_seg) :
918 else 963 sizeof (struct mthca_tavor_ud_seg);
919 size += sizeof (struct mthca_tavor_ud_seg);
920 break; 964 break;
965
966 case UC:
967 size += sizeof (struct mthca_raddr_seg);
968 break;
969
970 case RC:
971 size += sizeof (struct mthca_raddr_seg);
972 /*
973 * An atomic op will require an atomic segment, a
974 * remote address segment and one scatter entry.
975 */
976 size = max_t(int, size,
977 sizeof (struct mthca_atomic_seg) +
978 sizeof (struct mthca_raddr_seg) +
979 sizeof (struct mthca_data_seg));
980 break;
981
921 default: 982 default:
922 /* bind seg is as big as atomic + raddr segs */ 983 break;
923 size += sizeof (struct mthca_bind_seg);
924 } 984 }
925 985
986 /* Make sure that we have enough space for a bind request */
987 size = max_t(int, size, sizeof (struct mthca_bind_seg));
988
989 size += sizeof (struct mthca_next_seg);
990
991 if (size > dev->limits.max_desc_sz)
992 return -EINVAL;
993
926 for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size; 994 for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size;
927 qp->sq.wqe_shift++) 995 qp->sq.wqe_shift++)
928 ; /* nothing */ 996 ; /* nothing */
@@ -1066,6 +1134,8 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1066 return ret; 1134 return ret;
1067 } 1135 }
1068 1136
1137 mthca_adjust_qp_caps(dev, pd, qp);
1138
1069 /* 1139 /*
1070 * If this is a userspace QP, we're done now. The doorbells 1140 * If this is a userspace QP, we're done now. The doorbells
1071 * will be allocated and buffers will be initialized in 1141 * will be allocated and buffers will be initialized in
@@ -1486,8 +1556,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1486 } 1556 }
1487 1557
1488 wqe += sizeof (struct mthca_atomic_seg); 1558 wqe += sizeof (struct mthca_atomic_seg);
1489 size += sizeof (struct mthca_raddr_seg) / 16 + 1559 size += (sizeof (struct mthca_raddr_seg) +
1490 sizeof (struct mthca_atomic_seg); 1560 sizeof (struct mthca_atomic_seg)) / 16;
1491 break; 1561 break;
1492 1562
1493 case IB_WR_RDMA_WRITE: 1563 case IB_WR_RDMA_WRITE:
@@ -1637,6 +1707,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1637{ 1707{
1638 struct mthca_dev *dev = to_mdev(ibqp->device); 1708 struct mthca_dev *dev = to_mdev(ibqp->device);
1639 struct mthca_qp *qp = to_mqp(ibqp); 1709 struct mthca_qp *qp = to_mqp(ibqp);
1710 __be32 doorbell[2];
1640 unsigned long flags; 1711 unsigned long flags;
1641 int err = 0; 1712 int err = 0;
1642 int nreq; 1713 int nreq;
@@ -1654,6 +1725,22 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1654 ind = qp->rq.next_ind; 1725 ind = qp->rq.next_ind;
1655 1726
1656 for (nreq = 0; wr; ++nreq, wr = wr->next) { 1727 for (nreq = 0; wr; ++nreq, wr = wr->next) {
1728 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
1729 nreq = 0;
1730
1731 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1732 doorbell[1] = cpu_to_be32(qp->qpn << 8);
1733
1734 wmb();
1735
1736 mthca_write64(doorbell,
1737 dev->kar + MTHCA_RECEIVE_DOORBELL,
1738 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
1739
1740 qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
1741 size0 = 0;
1742 }
1743
1657 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { 1744 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
1658 mthca_err(dev, "RQ %06x full (%u head, %u tail," 1745 mthca_err(dev, "RQ %06x full (%u head, %u tail,"
1659 " %d max, %d nreq)\n", qp->qpn, 1746 " %d max, %d nreq)\n", qp->qpn,
@@ -1711,8 +1798,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1711 1798
1712out: 1799out:
1713 if (likely(nreq)) { 1800 if (likely(nreq)) {
1714 __be32 doorbell[2];
1715
1716 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); 1801 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1717 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); 1802 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
1718 1803
@@ -1806,8 +1891,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1806 } 1891 }
1807 1892
1808 wqe += sizeof (struct mthca_atomic_seg); 1893 wqe += sizeof (struct mthca_atomic_seg);
1809 size += sizeof (struct mthca_raddr_seg) / 16 + 1894 size += (sizeof (struct mthca_raddr_seg) +
1810 sizeof (struct mthca_atomic_seg); 1895 sizeof (struct mthca_atomic_seg)) / 16;
1811 break; 1896 break;
1812 1897
1813 case IB_WR_RDMA_READ: 1898 case IB_WR_RDMA_READ:
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 26d5161fde07..f7d234295efe 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -417,6 +417,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
417{ 417{
418 struct mthca_dev *dev = to_mdev(ibsrq->device); 418 struct mthca_dev *dev = to_mdev(ibsrq->device);
419 struct mthca_srq *srq = to_msrq(ibsrq); 419 struct mthca_srq *srq = to_msrq(ibsrq);
420 __be32 doorbell[2];
420 unsigned long flags; 421 unsigned long flags;
421 int err = 0; 422 int err = 0;
422 int first_ind; 423 int first_ind;
@@ -432,6 +433,25 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
432 first_ind = srq->first_free; 433 first_ind = srq->first_free;
433 434
434 for (nreq = 0; wr; ++nreq, wr = wr->next) { 435 for (nreq = 0; wr; ++nreq, wr = wr->next) {
436 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
437 nreq = 0;
438
439 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
440 doorbell[1] = cpu_to_be32(srq->srqn << 8);
441
442 /*
443 * Make sure that descriptors are written
444 * before doorbell is rung.
445 */
446 wmb();
447
448 mthca_write64(doorbell,
449 dev->kar + MTHCA_RECEIVE_DOORBELL,
450 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
451
452 first_ind = srq->first_free;
453 }
454
435 ind = srq->first_free; 455 ind = srq->first_free;
436 456
437 if (ind < 0) { 457 if (ind < 0) {
@@ -494,8 +514,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
494 } 514 }
495 515
496 if (likely(nreq)) { 516 if (likely(nreq)) {
497 __be32 doorbell[2];
498
499 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift); 517 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
500 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq); 518 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
501 519
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
index 1f4c0ff28f79..73f1c0b9021e 100644
--- a/drivers/infiniband/hw/mthca/mthca_wqe.h
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -49,7 +49,8 @@ enum {
49}; 49};
50 50
51enum { 51enum {
52 MTHCA_INVAL_LKEY = 0x100 52 MTHCA_INVAL_LKEY = 0x100,
53 MTHCA_TAVOR_MAX_WQES_PER_RECV_DB = 256
53}; 54};
54 55
55struct mthca_next_seg { 56struct mthca_next_seg {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 0095acc0fbbe..9923a15a9996 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -179,6 +179,7 @@ struct ipoib_dev_priv {
179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
180 struct list_head fs_list; 180 struct list_head fs_list;
181 struct dentry *mcg_dentry; 181 struct dentry *mcg_dentry;
182 struct dentry *path_dentry;
182#endif 183#endif
183}; 184};
184 185
@@ -270,7 +271,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev);
270 271
271#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 272#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
272struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); 273struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
273void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter);
274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); 274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter, 275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
276 union ib_gid *gid, 276 union ib_gid *gid,
@@ -278,6 +278,11 @@ void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
278 unsigned int *queuelen, 278 unsigned int *queuelen,
279 unsigned int *complete, 279 unsigned int *complete,
280 unsigned int *send_only); 280 unsigned int *send_only);
281
282struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev);
283int ipoib_path_iter_next(struct ipoib_path_iter *iter);
284void ipoib_path_iter_read(struct ipoib_path_iter *iter,
285 struct ipoib_path *path);
281#endif 286#endif
282 287
283int ipoib_mcast_attach(struct net_device *dev, u16 mlid, 288int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
@@ -299,13 +304,13 @@ void ipoib_pkey_poll(void *dev);
299int ipoib_pkey_dev_delay_open(struct net_device *dev); 304int ipoib_pkey_dev_delay_open(struct net_device *dev);
300 305
301#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 306#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
302int ipoib_create_debug_file(struct net_device *dev); 307void ipoib_create_debug_files(struct net_device *dev);
303void ipoib_delete_debug_file(struct net_device *dev); 308void ipoib_delete_debug_files(struct net_device *dev);
304int ipoib_register_debugfs(void); 309int ipoib_register_debugfs(void);
305void ipoib_unregister_debugfs(void); 310void ipoib_unregister_debugfs(void);
306#else 311#else
307static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; } 312static inline void ipoib_create_debug_files(struct net_device *dev) { }
308static inline void ipoib_delete_debug_file(struct net_device *dev) { } 313static inline void ipoib_delete_debug_files(struct net_device *dev) { }
309static inline int ipoib_register_debugfs(void) { return 0; } 314static inline int ipoib_register_debugfs(void) { return 0; }
310static inline void ipoib_unregister_debugfs(void) { } 315static inline void ipoib_unregister_debugfs(void) { }
311#endif 316#endif
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 38b150f775e7..685258e34034 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -43,6 +43,18 @@ struct file_operations;
43 43
44static struct dentry *ipoib_root; 44static struct dentry *ipoib_root;
45 45
46static void format_gid(union ib_gid *gid, char *buf)
47{
48 int i, n;
49
50 for (n = 0, i = 0; i < 8; ++i) {
51 n += sprintf(buf + n, "%x",
52 be16_to_cpu(((__be16 *) gid->raw)[i]));
53 if (i < 7)
54 buf[n++] = ':';
55 }
56}
57
46static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos) 58static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
47{ 59{
48 struct ipoib_mcast_iter *iter; 60 struct ipoib_mcast_iter *iter;
@@ -54,7 +66,7 @@ static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
54 66
55 while (n--) { 67 while (n--) {
56 if (ipoib_mcast_iter_next(iter)) { 68 if (ipoib_mcast_iter_next(iter)) {
57 ipoib_mcast_iter_free(iter); 69 kfree(iter);
58 return NULL; 70 return NULL;
59 } 71 }
60 } 72 }
@@ -70,7 +82,7 @@ static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
70 (*pos)++; 82 (*pos)++;
71 83
72 if (ipoib_mcast_iter_next(iter)) { 84 if (ipoib_mcast_iter_next(iter)) {
73 ipoib_mcast_iter_free(iter); 85 kfree(iter);
74 return NULL; 86 return NULL;
75 } 87 }
76 88
@@ -87,32 +99,32 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
87 struct ipoib_mcast_iter *iter = iter_ptr; 99 struct ipoib_mcast_iter *iter = iter_ptr;
88 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; 100 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
89 union ib_gid mgid; 101 union ib_gid mgid;
90 int i, n;
91 unsigned long created; 102 unsigned long created;
92 unsigned int queuelen, complete, send_only; 103 unsigned int queuelen, complete, send_only;
93 104
94 if (iter) { 105 if (!iter)
95 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen, 106 return 0;
96 &complete, &send_only);
97 107
98 for (n = 0, i = 0; i < sizeof mgid / 2; ++i) { 108 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
99 n += sprintf(gid_buf + n, "%x", 109 &complete, &send_only);
100 be16_to_cpu(((__be16 *) mgid.raw)[i]));
101 if (i < sizeof mgid / 2 - 1)
102 gid_buf[n++] = ':';
103 }
104 }
105 110
106 seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf); 111 format_gid(&mgid, gid_buf);
107 112
108 seq_printf(file, 113 seq_printf(file,
109 " created: %10ld queuelen: %4d complete: %d send_only: %d\n", 114 "GID: %s\n"
110 created, queuelen, complete, send_only); 115 " created: %10ld\n"
116 " queuelen: %9d\n"
117 " complete: %9s\n"
118 " send_only: %8s\n"
119 "\n",
120 gid_buf, created, queuelen,
121 complete ? "yes" : "no",
122 send_only ? "yes" : "no");
111 123
112 return 0; 124 return 0;
113} 125}
114 126
115static struct seq_operations ipoib_seq_ops = { 127static struct seq_operations ipoib_mcg_seq_ops = {
116 .start = ipoib_mcg_seq_start, 128 .start = ipoib_mcg_seq_start,
117 .next = ipoib_mcg_seq_next, 129 .next = ipoib_mcg_seq_next,
118 .stop = ipoib_mcg_seq_stop, 130 .stop = ipoib_mcg_seq_stop,
@@ -124,7 +136,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
124 struct seq_file *seq; 136 struct seq_file *seq;
125 int ret; 137 int ret;
126 138
127 ret = seq_open(file, &ipoib_seq_ops); 139 ret = seq_open(file, &ipoib_mcg_seq_ops);
128 if (ret) 140 if (ret)
129 return ret; 141 return ret;
130 142
@@ -134,7 +146,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
134 return 0; 146 return 0;
135} 147}
136 148
137static struct file_operations ipoib_fops = { 149static struct file_operations ipoib_mcg_fops = {
138 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
139 .open = ipoib_mcg_open, 151 .open = ipoib_mcg_open,
140 .read = seq_read, 152 .read = seq_read,
@@ -142,25 +154,138 @@ static struct file_operations ipoib_fops = {
142 .release = seq_release 154 .release = seq_release
143}; 155};
144 156
145int ipoib_create_debug_file(struct net_device *dev) 157static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
158{
159 struct ipoib_path_iter *iter;
160 loff_t n = *pos;
161
162 iter = ipoib_path_iter_init(file->private);
163 if (!iter)
164 return NULL;
165
166 while (n--) {
167 if (ipoib_path_iter_next(iter)) {
168 kfree(iter);
169 return NULL;
170 }
171 }
172
173 return iter;
174}
175
176static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
177 loff_t *pos)
178{
179 struct ipoib_path_iter *iter = iter_ptr;
180
181 (*pos)++;
182
183 if (ipoib_path_iter_next(iter)) {
184 kfree(iter);
185 return NULL;
186 }
187
188 return iter;
189}
190
191static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
192{
193 /* nothing for now */
194}
195
196static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
197{
198 struct ipoib_path_iter *iter = iter_ptr;
199 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
200 struct ipoib_path path;
201 int rate;
202
203 if (!iter)
204 return 0;
205
206 ipoib_path_iter_read(iter, &path);
207
208 format_gid(&path.pathrec.dgid, gid_buf);
209
210 seq_printf(file,
211 "GID: %s\n"
212 " complete: %6s\n",
213 gid_buf, path.pathrec.dlid ? "yes" : "no");
214
215 if (path.pathrec.dlid) {
216 rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
217
218 seq_printf(file,
219 " DLID: 0x%04x\n"
220 " SL: %12d\n"
221 " rate: %*d%s Gb/sec\n",
222 be16_to_cpu(path.pathrec.dlid),
223 path.pathrec.sl,
224 10 - ((rate % 10) ? 2 : 0),
225 rate / 10, rate % 10 ? ".5" : "");
226 }
227
228 seq_putc(file, '\n');
229
230 return 0;
231}
232
233static struct seq_operations ipoib_path_seq_ops = {
234 .start = ipoib_path_seq_start,
235 .next = ipoib_path_seq_next,
236 .stop = ipoib_path_seq_stop,
237 .show = ipoib_path_seq_show,
238};
239
240static int ipoib_path_open(struct inode *inode, struct file *file)
241{
242 struct seq_file *seq;
243 int ret;
244
245 ret = seq_open(file, &ipoib_path_seq_ops);
246 if (ret)
247 return ret;
248
249 seq = file->private_data;
250 seq->private = inode->u.generic_ip;
251
252 return 0;
253}
254
255static struct file_operations ipoib_path_fops = {
256 .owner = THIS_MODULE,
257 .open = ipoib_path_open,
258 .read = seq_read,
259 .llseek = seq_lseek,
260 .release = seq_release
261};
262
263void ipoib_create_debug_files(struct net_device *dev)
146{ 264{
147 struct ipoib_dev_priv *priv = netdev_priv(dev); 265 struct ipoib_dev_priv *priv = netdev_priv(dev);
148 char name[IFNAMSIZ + sizeof "_mcg"]; 266 char name[IFNAMSIZ + sizeof "_path"];
149 267
150 snprintf(name, sizeof name, "%s_mcg", dev->name); 268 snprintf(name, sizeof name, "%s_mcg", dev->name);
151
152 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, 269 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
153 ipoib_root, dev, &ipoib_fops); 270 ipoib_root, dev, &ipoib_mcg_fops);
154 271 if (!priv->mcg_dentry)
155 return priv->mcg_dentry ? 0 : -ENOMEM; 272 ipoib_warn(priv, "failed to create mcg debug file\n");
273
274 snprintf(name, sizeof name, "%s_path", dev->name);
275 priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
276 ipoib_root, dev, &ipoib_path_fops);
277 if (!priv->path_dentry)
278 ipoib_warn(priv, "failed to create path debug file\n");
156} 279}
157 280
158void ipoib_delete_debug_file(struct net_device *dev) 281void ipoib_delete_debug_files(struct net_device *dev)
159{ 282{
160 struct ipoib_dev_priv *priv = netdev_priv(dev); 283 struct ipoib_dev_priv *priv = netdev_priv(dev);
161 284
162 if (priv->mcg_dentry) 285 if (priv->mcg_dentry)
163 debugfs_remove(priv->mcg_dentry); 286 debugfs_remove(priv->mcg_dentry);
287 if (priv->path_dentry)
288 debugfs_remove(priv->path_dentry);
164} 289}
165 290
166int ipoib_register_debugfs(void) 291int ipoib_register_debugfs(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ce0296273e76..2fa30751f362 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_debug_level, int, 0644);
58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); 58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
59#endif 59#endif
60 60
61struct ipoib_path_iter {
62 struct net_device *dev;
63 struct ipoib_path path;
64};
65
61static const u8 ipv4_bcast_addr[] = { 66static const u8 ipv4_bcast_addr[] = {
62 0x00, 0xff, 0xff, 0xff, 67 0x00, 0xff, 0xff, 0xff,
63 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, 68 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
@@ -250,6 +255,64 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
250 kfree(path); 255 kfree(path);
251} 256}
252 257
258#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
259
260struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev)
261{
262 struct ipoib_path_iter *iter;
263
264 iter = kmalloc(sizeof *iter, GFP_KERNEL);
265 if (!iter)
266 return NULL;
267
268 iter->dev = dev;
269 memset(iter->path.pathrec.dgid.raw, 0, 16);
270
271 if (ipoib_path_iter_next(iter)) {
272 kfree(iter);
273 return NULL;
274 }
275
276 return iter;
277}
278
279int ipoib_path_iter_next(struct ipoib_path_iter *iter)
280{
281 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
282 struct rb_node *n;
283 struct ipoib_path *path;
284 int ret = 1;
285
286 spin_lock_irq(&priv->lock);
287
288 n = rb_first(&priv->path_tree);
289
290 while (n) {
291 path = rb_entry(n, struct ipoib_path, rb_node);
292
293 if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw,
294 sizeof (union ib_gid)) < 0) {
295 iter->path = *path;
296 ret = 0;
297 break;
298 }
299
300 n = rb_next(n);
301 }
302
303 spin_unlock_irq(&priv->lock);
304
305 return ret;
306}
307
308void ipoib_path_iter_read(struct ipoib_path_iter *iter,
309 struct ipoib_path *path)
310{
311 *path = iter->path;
312}
313
314#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
315
253void ipoib_flush_paths(struct net_device *dev) 316void ipoib_flush_paths(struct net_device *dev)
254{ 317{
255 struct ipoib_dev_priv *priv = netdev_priv(dev); 318 struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -763,7 +826,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
763{ 826{
764 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv; 827 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;
765 828
766 ipoib_delete_debug_file(dev); 829 ipoib_delete_debug_files(dev);
767 830
768 /* Delete any child interfaces first */ 831 /* Delete any child interfaces first */
769 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { 832 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
@@ -972,8 +1035,7 @@ static struct net_device *ipoib_add_port(const char *format,
972 goto register_failed; 1035 goto register_failed;
973 } 1036 }
974 1037
975 if (ipoib_create_debug_file(priv->dev)) 1038 ipoib_create_debug_files(priv->dev);
976 goto debug_failed;
977 1039
978 if (ipoib_add_pkey_attr(priv->dev)) 1040 if (ipoib_add_pkey_attr(priv->dev))
979 goto sysfs_failed; 1041 goto sysfs_failed;
@@ -987,9 +1049,7 @@ static struct net_device *ipoib_add_port(const char *format,
987 return priv->dev; 1049 return priv->dev;
988 1050
989sysfs_failed: 1051sysfs_failed:
990 ipoib_delete_debug_file(priv->dev); 1052 ipoib_delete_debug_files(priv->dev);
991
992debug_failed:
993 unregister_netdev(priv->dev); 1053 unregister_netdev(priv->dev);
994 1054
995register_failed: 1055register_failed:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3ecf78a9493a..c33ed87f9dff 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -120,12 +120,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
120 if (mcast->ah) 120 if (mcast->ah)
121 ipoib_put_ah(mcast->ah); 121 ipoib_put_ah(mcast->ah);
122 122
123 while (!skb_queue_empty(&mcast->pkt_queue)) { 123 while (!skb_queue_empty(&mcast->pkt_queue))
124 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 124 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
125
126 skb->dev = dev;
127 dev_kfree_skb_any(skb);
128 }
129 125
130 kfree(mcast); 126 kfree(mcast);
131} 127}
@@ -317,13 +313,8 @@ ipoib_mcast_sendonly_join_complete(int status,
317 IPOIB_GID_ARG(mcast->mcmember.mgid), status); 313 IPOIB_GID_ARG(mcast->mcmember.mgid), status);
318 314
319 /* Flush out any queued packets */ 315 /* Flush out any queued packets */
320 while (!skb_queue_empty(&mcast->pkt_queue)) { 316 while (!skb_queue_empty(&mcast->pkt_queue))
321 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 317 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
322
323 skb->dev = dev;
324
325 dev_kfree_skb_any(skb);
326 }
327 318
328 /* Clear the busy flag so we try again */ 319 /* Clear the busy flag so we try again */
329 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); 320 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -928,21 +919,16 @@ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
928 return NULL; 919 return NULL;
929 920
930 iter->dev = dev; 921 iter->dev = dev;
931 memset(iter->mgid.raw, 0, sizeof iter->mgid); 922 memset(iter->mgid.raw, 0, 16);
932 923
933 if (ipoib_mcast_iter_next(iter)) { 924 if (ipoib_mcast_iter_next(iter)) {
934 ipoib_mcast_iter_free(iter); 925 kfree(iter);
935 return NULL; 926 return NULL;
936 } 927 }
937 928
938 return iter; 929 return iter;
939} 930}
940 931
941void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter)
942{
943 kfree(iter);
944}
945
946int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter) 932int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter)
947{ 933{
948 struct ipoib_dev_priv *priv = netdev_priv(iter->dev); 934 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 332d730e60c2..d280b341a37f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -113,8 +113,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
113 113
114 priv->parent = ppriv->dev; 114 priv->parent = ppriv->dev;
115 115
116 if (ipoib_create_debug_file(priv->dev)) 116 ipoib_create_debug_files(priv->dev);
117 goto debug_failed;
118 117
119 if (ipoib_add_pkey_attr(priv->dev)) 118 if (ipoib_add_pkey_attr(priv->dev))
120 goto sysfs_failed; 119 goto sysfs_failed;
@@ -130,9 +129,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
130 return 0; 129 return 0;
131 130
132sysfs_failed: 131sysfs_failed:
133 ipoib_delete_debug_file(priv->dev); 132 ipoib_delete_debug_files(priv->dev);
134
135debug_failed:
136 unregister_netdev(priv->dev); 133 unregister_netdev(priv->dev);
137 134
138register_failed: 135register_failed:
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2687e34aa5bc..321a3a10e69b 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -32,7 +32,6 @@
32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $ 32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $
33 */ 33 */
34 34
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/init.h> 36#include <linux/init.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 0879915b14d5..c8ae2bb054e0 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -669,7 +669,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name); 669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
670 if (dev->phys) 670 if (dev->phys)
671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys); 671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
672 if (dev->phys) 672 if (dev->uniq)
673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); 673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
674 674
675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); 675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
diff --git a/drivers/isdn/divert/divert_init.c b/drivers/isdn/divert/divert_init.c
index 434e684f5dbb..2f7c9fc2e898 100644
--- a/drivers/isdn/divert/divert_init.c
+++ b/drivers/isdn/divert/divert_init.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/version.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16 15
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 0b0ea26023e5..1b37d86d5ee1 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
11 11
12#include <linux/config.h> 12#include <linux/config.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
17#ifdef CONFIG_PROC_FS 16#ifdef CONFIG_PROC_FS
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 0bfd698726a6..f1a1f9a9b88e 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -9,7 +9,6 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/version.h>
13#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
14 13
15#include "isdn_divert.h" 14#include "isdn_divert.h"
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index b4d795d40154..dc7ef957e897 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -23,7 +23,6 @@
23 * o tx_skb at PH_DEACTIVATE time 23 * o tx_skb at PH_DEACTIVATE time
24 */ 24 */
25 25
26#include <linux/version.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/pci.h> 28#include <linux/pci.h>
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 2cf5d1a6df6c..8e192a3a3490 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -25,7 +25,6 @@
25 */ 25 */
26 26
27#include <linux/config.h> 27#include <linux/config.h>
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 1fd3d4e5f284..acc1d3cceebb 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/signal.h> 14#include <linux/signal.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/skbuff.h> 16#include <linux/skbuff.h>
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 12c8137b5161..cb791f8e793a 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -13,7 +13,6 @@
13#include <linux/config.h> 13#include <linux/config.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/version.h>
17#include <linux/poll.h> 16#include <linux/poll.h>
18#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index babec8157ae6..aa01628d74c6 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/version.h>
18#include <linux/signal.h> 17#include <linux/signal.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/netdevice.h> 19#include <linux/netdevice.h>
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 87f59a0e2a95..40e56143c768 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/version.h>
16#include <linux/poll.h> 15#include <linux/poll.h>
17#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
18#include <linux/pci.h> 17#include <linux/pci.h>
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4d57011c5737..6c26f1efabd5 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/proc_fs.h> 15#include <linux/proc_fs.h>
17#include <linux/pci.h> 16#include <linux/pci.h>
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8a7d54a5c97d..4643df097bfe 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -14,7 +14,6 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/poll.h> 17#include <linux/poll.h>
19#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
20#include <linux/isdn.h> 19#include <linux/isdn.h>
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index 9028cc3b5071..7d7245fb0b32 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -35,7 +35,6 @@ typedef struct icn_cdef {
35#ifdef __KERNEL__ 35#ifdef __KERNEL__
36/* Kernel includes */ 36/* Kernel includes */
37 37
38#include <linux/version.h>
39#include <linux/errno.h> 38#include <linux/errno.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
41#include <linux/major.h> 40#include <linux/major.h>
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h
index 8fb7bc1bfe0f..d699fe53e1c3 100644
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -33,7 +33,6 @@ typedef struct isdnloop_sdef {
33#ifdef __KERNEL__ 33#ifdef __KERNEL__
34/* Kernel includes */ 34/* Kernel includes */
35 35
36#include <linux/version.h>
37#include <linux/errno.h> 36#include <linux/errno.h>
38#include <linux/fs.h> 37#include <linux/fs.h>
39#include <linux/major.h> 38#include <linux/major.h>
diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h
index 4611da6e9231..5286e0c810a9 100644
--- a/drivers/isdn/sc/includes.h
+++ b/drivers/isdn/sc/includes.h
@@ -4,7 +4,6 @@
4 * 4 *
5 */ 5 */
6 6
7#include <linux/version.h>
8#include <linux/errno.h> 7#include <linux/errno.h>
9#include <asm/io.h> 8#include <asm/io.h>
10#include <linux/delay.h> 9#include <linux/delay.h>
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 01654fcabc52..51315302a85e 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/version.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/init.h> 26#include <linux/init.h>
@@ -272,7 +271,8 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
272 return ERR_PTR(-ENOMEM); 271 return ERR_PTR(-ENOMEM);
273 272
274 ITERATE_RDEV(mddev, rdev, tmp) { 273 ITERATE_RDEV(mddev, rdev, tmp) {
275 if (! rdev->in_sync || rdev->faulty) 274 if (! test_bit(In_sync, &rdev->flags)
275 || test_bit(Faulty, &rdev->flags))
276 continue; 276 continue;
277 277
278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); 278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
@@ -292,7 +292,8 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
292 struct list_head *tmp; 292 struct list_head *tmp;
293 293
294 ITERATE_RDEV(mddev, rdev, tmp) 294 ITERATE_RDEV(mddev, rdev, tmp)
295 if (rdev->in_sync && !rdev->faulty) 295 if (test_bit(In_sync, &rdev->flags)
296 && !test_bit(Faulty, &rdev->flags))
296 md_super_write(mddev, rdev, 297 md_super_write(mddev, rdev,
297 (rdev->sb_offset<<1) + offset 298 (rdev->sb_offset<<1) + offset
298 + page->index * (PAGE_SIZE/512), 299 + page->index * (PAGE_SIZE/512),
@@ -300,7 +301,7 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
300 page); 301 page);
301 302
302 if (wait) 303 if (wait)
303 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 304 md_super_wait(mddev);
304 return 0; 305 return 0;
305} 306}
306 307
@@ -481,7 +482,8 @@ static int bitmap_read_sb(struct bitmap *bitmap)
481 /* verify that the bitmap-specific fields are valid */ 482 /* verify that the bitmap-specific fields are valid */
482 if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) 483 if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
483 reason = "bad magic"; 484 reason = "bad magic";
484 else if (sb->version != cpu_to_le32(BITMAP_MAJOR)) 485 else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
486 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
485 reason = "unrecognized superblock version"; 487 reason = "unrecognized superblock version";
486 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4)) 488 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
487 reason = "bitmap chunksize out of range (512B - 4MB)"; 489 reason = "bitmap chunksize out of range (512B - 4MB)";
@@ -526,6 +528,8 @@ success:
526 bitmap->daemon_lastrun = jiffies; 528 bitmap->daemon_lastrun = jiffies;
527 bitmap->max_write_behind = write_behind; 529 bitmap->max_write_behind = write_behind;
528 bitmap->flags |= sb->state; 530 bitmap->flags |= sb->state;
531 if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
532 bitmap->flags |= BITMAP_HOSTENDIAN;
529 bitmap->events_cleared = le64_to_cpu(sb->events_cleared); 533 bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
530 if (sb->state & BITMAP_STALE) 534 if (sb->state & BITMAP_STALE)
531 bitmap->events_cleared = bitmap->mddev->events; 535 bitmap->events_cleared = bitmap->mddev->events;
@@ -763,7 +767,10 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
763 767
764 /* set the bit */ 768 /* set the bit */
765 kaddr = kmap_atomic(page, KM_USER0); 769 kaddr = kmap_atomic(page, KM_USER0);
766 set_bit(bit, kaddr); 770 if (bitmap->flags & BITMAP_HOSTENDIAN)
771 set_bit(bit, kaddr);
772 else
773 ext2_set_bit(bit, kaddr);
767 kunmap_atomic(kaddr, KM_USER0); 774 kunmap_atomic(kaddr, KM_USER0);
768 PRINTK("set file bit %lu page %lu\n", bit, page->index); 775 PRINTK("set file bit %lu page %lu\n", bit, page->index);
769 776
@@ -821,8 +828,7 @@ int bitmap_unplug(struct bitmap *bitmap)
821 wake_up_process(bitmap->writeback_daemon->tsk)); 828 wake_up_process(bitmap->writeback_daemon->tsk));
822 spin_unlock_irq(&bitmap->write_lock); 829 spin_unlock_irq(&bitmap->write_lock);
823 } else 830 } else
824 wait_event(bitmap->mddev->sb_wait, 831 md_super_wait(bitmap->mddev);
825 atomic_read(&bitmap->mddev->pending_writes)==0);
826 } 832 }
827 return 0; 833 return 0;
828} 834}
@@ -890,6 +896,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
890 oldindex = ~0L; 896 oldindex = ~0L;
891 897
892 for (i = 0; i < chunks; i++) { 898 for (i = 0; i < chunks; i++) {
899 int b;
893 index = file_page_index(i); 900 index = file_page_index(i);
894 bit = file_page_offset(i); 901 bit = file_page_offset(i);
895 if (index != oldindex) { /* this is a new page, read it in */ 902 if (index != oldindex) { /* this is a new page, read it in */
@@ -938,7 +945,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
938 945
939 bitmap->filemap[bitmap->file_pages++] = page; 946 bitmap->filemap[bitmap->file_pages++] = page;
940 } 947 }
941 if (test_bit(bit, page_address(page))) { 948 if (bitmap->flags & BITMAP_HOSTENDIAN)
949 b = test_bit(bit, page_address(page));
950 else
951 b = ext2_test_bit(bit, page_address(page));
952 if (b) {
942 /* if the disk bit is set, set the memory bit */ 953 /* if the disk bit is set, set the memory bit */
943 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), 954 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
944 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) 955 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
@@ -1096,7 +1107,10 @@ int bitmap_daemon_work(struct bitmap *bitmap)
1096 -1); 1107 -1);
1097 1108
1098 /* clear the bit */ 1109 /* clear the bit */
1099 clear_bit(file_page_offset(j), page_address(page)); 1110 if (bitmap->flags & BITMAP_HOSTENDIAN)
1111 clear_bit(file_page_offset(j), page_address(page));
1112 else
1113 ext2_clear_bit(file_page_offset(j), page_address(page));
1100 } 1114 }
1101 } 1115 }
1102 spin_unlock_irqrestore(&bitmap->lock, flags); 1116 spin_unlock_irqrestore(&bitmap->lock, flags);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9ecf51ee596f..adf960d8a7c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -131,6 +131,8 @@ static ctl_table raid_root_table[] = {
131 131
132static struct block_device_operations md_fops; 132static struct block_device_operations md_fops;
133 133
134static int start_readonly;
135
134/* 136/*
135 * Enables to iterate over all existing md arrays 137 * Enables to iterate over all existing md arrays
136 * all_mddevs_lock protects this list. 138 * all_mddevs_lock protects this list.
@@ -181,7 +183,7 @@ static void mddev_put(mddev_t *mddev)
181 if (!mddev->raid_disks && list_empty(&mddev->disks)) { 183 if (!mddev->raid_disks && list_empty(&mddev->disks)) {
182 list_del(&mddev->all_mddevs); 184 list_del(&mddev->all_mddevs);
183 blk_put_queue(mddev->queue); 185 blk_put_queue(mddev->queue);
184 kfree(mddev); 186 kobject_unregister(&mddev->kobj);
185 } 187 }
186 spin_unlock(&all_mddevs_lock); 188 spin_unlock(&all_mddevs_lock);
187} 189}
@@ -330,18 +332,46 @@ static void free_disk_sb(mdk_rdev_t * rdev)
330static int super_written(struct bio *bio, unsigned int bytes_done, int error) 332static int super_written(struct bio *bio, unsigned int bytes_done, int error)
331{ 333{
332 mdk_rdev_t *rdev = bio->bi_private; 334 mdk_rdev_t *rdev = bio->bi_private;
335 mddev_t *mddev = rdev->mddev;
333 if (bio->bi_size) 336 if (bio->bi_size)
334 return 1; 337 return 1;
335 338
336 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) 339 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
337 md_error(rdev->mddev, rdev); 340 md_error(mddev, rdev);
338 341
339 if (atomic_dec_and_test(&rdev->mddev->pending_writes)) 342 if (atomic_dec_and_test(&mddev->pending_writes))
340 wake_up(&rdev->mddev->sb_wait); 343 wake_up(&mddev->sb_wait);
341 bio_put(bio); 344 bio_put(bio);
342 return 0; 345 return 0;
343} 346}
344 347
348static int super_written_barrier(struct bio *bio, unsigned int bytes_done, int error)
349{
350 struct bio *bio2 = bio->bi_private;
351 mdk_rdev_t *rdev = bio2->bi_private;
352 mddev_t *mddev = rdev->mddev;
353 if (bio->bi_size)
354 return 1;
355
356 if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
357 error == -EOPNOTSUPP) {
358 unsigned long flags;
359 /* barriers don't appear to be supported :-( */
360 set_bit(BarriersNotsupp, &rdev->flags);
361 mddev->barriers_work = 0;
362 spin_lock_irqsave(&mddev->write_lock, flags);
363 bio2->bi_next = mddev->biolist;
364 mddev->biolist = bio2;
365 spin_unlock_irqrestore(&mddev->write_lock, flags);
366 wake_up(&mddev->sb_wait);
367 bio_put(bio);
368 return 0;
369 }
370 bio_put(bio2);
371 bio->bi_private = rdev;
372 return super_written(bio, bytes_done, error);
373}
374
345void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, 375void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
346 sector_t sector, int size, struct page *page) 376 sector_t sector, int size, struct page *page)
347{ 377{
@@ -350,16 +380,54 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
350 * and decrement it on completion, waking up sb_wait 380 * and decrement it on completion, waking up sb_wait
351 * if zero is reached. 381 * if zero is reached.
352 * If an error occurred, call md_error 382 * If an error occurred, call md_error
383 *
384 * As we might need to resubmit the request if BIO_RW_BARRIER
385 * causes ENOTSUPP, we allocate a spare bio...
353 */ 386 */
354 struct bio *bio = bio_alloc(GFP_NOIO, 1); 387 struct bio *bio = bio_alloc(GFP_NOIO, 1);
388 int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
355 389
356 bio->bi_bdev = rdev->bdev; 390 bio->bi_bdev = rdev->bdev;
357 bio->bi_sector = sector; 391 bio->bi_sector = sector;
358 bio_add_page(bio, page, size, 0); 392 bio_add_page(bio, page, size, 0);
359 bio->bi_private = rdev; 393 bio->bi_private = rdev;
360 bio->bi_end_io = super_written; 394 bio->bi_end_io = super_written;
395 bio->bi_rw = rw;
396
361 atomic_inc(&mddev->pending_writes); 397 atomic_inc(&mddev->pending_writes);
362 submit_bio((1<<BIO_RW)|(1<<BIO_RW_SYNC), bio); 398 if (!test_bit(BarriersNotsupp, &rdev->flags)) {
399 struct bio *rbio;
400 rw |= (1<<BIO_RW_BARRIER);
401 rbio = bio_clone(bio, GFP_NOIO);
402 rbio->bi_private = bio;
403 rbio->bi_end_io = super_written_barrier;
404 submit_bio(rw, rbio);
405 } else
406 submit_bio(rw, bio);
407}
408
409void md_super_wait(mddev_t *mddev)
410{
411 /* wait for all superblock writes that were scheduled to complete.
412 * if any had to be retried (due to BARRIER problems), retry them
413 */
414 DEFINE_WAIT(wq);
415 for(;;) {
416 prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE);
417 if (atomic_read(&mddev->pending_writes)==0)
418 break;
419 while (mddev->biolist) {
420 struct bio *bio;
421 spin_lock_irq(&mddev->write_lock);
422 bio = mddev->biolist;
423 mddev->biolist = bio->bi_next ;
424 bio->bi_next = NULL;
425 spin_unlock_irq(&mddev->write_lock);
426 submit_bio(bio->bi_rw, bio);
427 }
428 schedule();
429 }
430 finish_wait(&mddev->sb_wait, &wq);
363} 431}
364 432
365static int bi_complete(struct bio *bio, unsigned int bytes_done, int error) 433static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
@@ -610,7 +678,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
610 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); 678 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page);
611 679
612 rdev->raid_disk = -1; 680 rdev->raid_disk = -1;
613 rdev->in_sync = 0; 681 rdev->flags = 0;
614 if (mddev->raid_disks == 0) { 682 if (mddev->raid_disks == 0) {
615 mddev->major_version = 0; 683 mddev->major_version = 0;
616 mddev->minor_version = sb->minor_version; 684 mddev->minor_version = sb->minor_version;
@@ -671,21 +739,19 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
671 return 0; 739 return 0;
672 740
673 if (mddev->level != LEVEL_MULTIPATH) { 741 if (mddev->level != LEVEL_MULTIPATH) {
674 rdev->faulty = 0;
675 rdev->flags = 0;
676 desc = sb->disks + rdev->desc_nr; 742 desc = sb->disks + rdev->desc_nr;
677 743
678 if (desc->state & (1<<MD_DISK_FAULTY)) 744 if (desc->state & (1<<MD_DISK_FAULTY))
679 rdev->faulty = 1; 745 set_bit(Faulty, &rdev->flags);
680 else if (desc->state & (1<<MD_DISK_SYNC) && 746 else if (desc->state & (1<<MD_DISK_SYNC) &&
681 desc->raid_disk < mddev->raid_disks) { 747 desc->raid_disk < mddev->raid_disks) {
682 rdev->in_sync = 1; 748 set_bit(In_sync, &rdev->flags);
683 rdev->raid_disk = desc->raid_disk; 749 rdev->raid_disk = desc->raid_disk;
684 } 750 }
685 if (desc->state & (1<<MD_DISK_WRITEMOSTLY)) 751 if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
686 set_bit(WriteMostly, &rdev->flags); 752 set_bit(WriteMostly, &rdev->flags);
687 } else /* MULTIPATH are always insync */ 753 } else /* MULTIPATH are always insync */
688 rdev->in_sync = 1; 754 set_bit(In_sync, &rdev->flags);
689 return 0; 755 return 0;
690} 756}
691 757
@@ -699,6 +765,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
699 mdk_rdev_t *rdev2; 765 mdk_rdev_t *rdev2;
700 int next_spare = mddev->raid_disks; 766 int next_spare = mddev->raid_disks;
701 767
768
702 /* make rdev->sb match mddev data.. 769 /* make rdev->sb match mddev data..
703 * 770 *
704 * 1/ zero out disks 771 * 1/ zero out disks
@@ -758,23 +825,27 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
758 sb->disks[0].state = (1<<MD_DISK_REMOVED); 825 sb->disks[0].state = (1<<MD_DISK_REMOVED);
759 ITERATE_RDEV(mddev,rdev2,tmp) { 826 ITERATE_RDEV(mddev,rdev2,tmp) {
760 mdp_disk_t *d; 827 mdp_disk_t *d;
761 if (rdev2->raid_disk >= 0 && rdev2->in_sync && !rdev2->faulty) 828 int desc_nr;
762 rdev2->desc_nr = rdev2->raid_disk; 829 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
830 && !test_bit(Faulty, &rdev2->flags))
831 desc_nr = rdev2->raid_disk;
763 else 832 else
764 rdev2->desc_nr = next_spare++; 833 desc_nr = next_spare++;
834 rdev2->desc_nr = desc_nr;
765 d = &sb->disks[rdev2->desc_nr]; 835 d = &sb->disks[rdev2->desc_nr];
766 nr_disks++; 836 nr_disks++;
767 d->number = rdev2->desc_nr; 837 d->number = rdev2->desc_nr;
768 d->major = MAJOR(rdev2->bdev->bd_dev); 838 d->major = MAJOR(rdev2->bdev->bd_dev);
769 d->minor = MINOR(rdev2->bdev->bd_dev); 839 d->minor = MINOR(rdev2->bdev->bd_dev);
770 if (rdev2->raid_disk >= 0 && rdev->in_sync && !rdev2->faulty) 840 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
841 && !test_bit(Faulty, &rdev2->flags))
771 d->raid_disk = rdev2->raid_disk; 842 d->raid_disk = rdev2->raid_disk;
772 else 843 else
773 d->raid_disk = rdev2->desc_nr; /* compatibility */ 844 d->raid_disk = rdev2->desc_nr; /* compatibility */
774 if (rdev2->faulty) { 845 if (test_bit(Faulty, &rdev2->flags)) {
775 d->state = (1<<MD_DISK_FAULTY); 846 d->state = (1<<MD_DISK_FAULTY);
776 failed++; 847 failed++;
777 } else if (rdev2->in_sync) { 848 } else if (test_bit(In_sync, &rdev2->flags)) {
778 d->state = (1<<MD_DISK_ACTIVE); 849 d->state = (1<<MD_DISK_ACTIVE);
779 d->state |= (1<<MD_DISK_SYNC); 850 d->state |= (1<<MD_DISK_SYNC);
780 active++; 851 active++;
@@ -787,7 +858,6 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
787 if (test_bit(WriteMostly, &rdev2->flags)) 858 if (test_bit(WriteMostly, &rdev2->flags))
788 d->state |= (1<<MD_DISK_WRITEMOSTLY); 859 d->state |= (1<<MD_DISK_WRITEMOSTLY);
789 } 860 }
790
791 /* now set the "removed" and "faulty" bits on any missing devices */ 861 /* now set the "removed" and "faulty" bits on any missing devices */
792 for (i=0 ; i < mddev->raid_disks ; i++) { 862 for (i=0 ; i < mddev->raid_disks ; i++) {
793 mdp_disk_t *d = &sb->disks[i]; 863 mdp_disk_t *d = &sb->disks[i];
@@ -944,7 +1014,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
944 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); 1014 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page);
945 1015
946 rdev->raid_disk = -1; 1016 rdev->raid_disk = -1;
947 rdev->in_sync = 0; 1017 rdev->flags = 0;
948 if (mddev->raid_disks == 0) { 1018 if (mddev->raid_disks == 0) {
949 mddev->major_version = 1; 1019 mddev->major_version = 1;
950 mddev->patch_version = 0; 1020 mddev->patch_version = 0;
@@ -996,22 +1066,19 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
996 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); 1066 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
997 switch(role) { 1067 switch(role) {
998 case 0xffff: /* spare */ 1068 case 0xffff: /* spare */
999 rdev->faulty = 0;
1000 break; 1069 break;
1001 case 0xfffe: /* faulty */ 1070 case 0xfffe: /* faulty */
1002 rdev->faulty = 1; 1071 set_bit(Faulty, &rdev->flags);
1003 break; 1072 break;
1004 default: 1073 default:
1005 rdev->in_sync = 1; 1074 set_bit(In_sync, &rdev->flags);
1006 rdev->faulty = 0;
1007 rdev->raid_disk = role; 1075 rdev->raid_disk = role;
1008 break; 1076 break;
1009 } 1077 }
1010 rdev->flags = 0;
1011 if (sb->devflags & WriteMostly1) 1078 if (sb->devflags & WriteMostly1)
1012 set_bit(WriteMostly, &rdev->flags); 1079 set_bit(WriteMostly, &rdev->flags);
1013 } else /* MULTIPATH are always insync */ 1080 } else /* MULTIPATH are always insync */
1014 rdev->in_sync = 1; 1081 set_bit(In_sync, &rdev->flags);
1015 1082
1016 return 0; 1083 return 0;
1017} 1084}
@@ -1055,9 +1122,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1055 1122
1056 ITERATE_RDEV(mddev,rdev2,tmp) { 1123 ITERATE_RDEV(mddev,rdev2,tmp) {
1057 i = rdev2->desc_nr; 1124 i = rdev2->desc_nr;
1058 if (rdev2->faulty) 1125 if (test_bit(Faulty, &rdev2->flags))
1059 sb->dev_roles[i] = cpu_to_le16(0xfffe); 1126 sb->dev_roles[i] = cpu_to_le16(0xfffe);
1060 else if (rdev2->in_sync) 1127 else if (test_bit(In_sync, &rdev2->flags))
1061 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); 1128 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
1062 else 1129 else
1063 sb->dev_roles[i] = cpu_to_le16(0xffff); 1130 sb->dev_roles[i] = cpu_to_le16(0xffff);
@@ -1115,6 +1182,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1115{ 1182{
1116 mdk_rdev_t *same_pdev; 1183 mdk_rdev_t *same_pdev;
1117 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; 1184 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
1185 struct kobject *ko;
1118 1186
1119 if (rdev->mddev) { 1187 if (rdev->mddev) {
1120 MD_BUG(); 1188 MD_BUG();
@@ -1143,10 +1211,22 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1143 if (find_rdev_nr(mddev, rdev->desc_nr)) 1211 if (find_rdev_nr(mddev, rdev->desc_nr))
1144 return -EBUSY; 1212 return -EBUSY;
1145 } 1213 }
1214 bdevname(rdev->bdev,b);
1215 if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
1216 return -ENOMEM;
1146 1217
1147 list_add(&rdev->same_set, &mddev->disks); 1218 list_add(&rdev->same_set, &mddev->disks);
1148 rdev->mddev = mddev; 1219 rdev->mddev = mddev;
1149 printk(KERN_INFO "md: bind<%s>\n", bdevname(rdev->bdev,b)); 1220 printk(KERN_INFO "md: bind<%s>\n", b);
1221
1222 rdev->kobj.parent = &mddev->kobj;
1223 kobject_add(&rdev->kobj);
1224
1225 if (rdev->bdev->bd_part)
1226 ko = &rdev->bdev->bd_part->kobj;
1227 else
1228 ko = &rdev->bdev->bd_disk->kobj;
1229 sysfs_create_link(&rdev->kobj, ko, "block");
1150 return 0; 1230 return 0;
1151} 1231}
1152 1232
@@ -1160,6 +1240,8 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
1160 list_del_init(&rdev->same_set); 1240 list_del_init(&rdev->same_set);
1161 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1241 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
1162 rdev->mddev = NULL; 1242 rdev->mddev = NULL;
1243 sysfs_remove_link(&rdev->kobj, "block");
1244 kobject_del(&rdev->kobj);
1163} 1245}
1164 1246
1165/* 1247/*
@@ -1215,7 +1297,7 @@ static void export_rdev(mdk_rdev_t * rdev)
1215 md_autodetect_dev(rdev->bdev->bd_dev); 1297 md_autodetect_dev(rdev->bdev->bd_dev);
1216#endif 1298#endif
1217 unlock_rdev(rdev); 1299 unlock_rdev(rdev);
1218 kfree(rdev); 1300 kobject_put(&rdev->kobj);
1219} 1301}
1220 1302
1221static void kick_rdev_from_array(mdk_rdev_t * rdev) 1303static void kick_rdev_from_array(mdk_rdev_t * rdev)
@@ -1287,7 +1369,8 @@ static void print_rdev(mdk_rdev_t *rdev)
1287 char b[BDEVNAME_SIZE]; 1369 char b[BDEVNAME_SIZE];
1288 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n", 1370 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
1289 bdevname(rdev->bdev,b), (unsigned long long)rdev->size, 1371 bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
1290 rdev->faulty, rdev->in_sync, rdev->desc_nr); 1372 test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
1373 rdev->desc_nr);
1291 if (rdev->sb_loaded) { 1374 if (rdev->sb_loaded) {
1292 printk(KERN_INFO "md: rdev superblock:\n"); 1375 printk(KERN_INFO "md: rdev superblock:\n");
1293 print_sb((mdp_super_t*)page_address(rdev->sb_page)); 1376 print_sb((mdp_super_t*)page_address(rdev->sb_page));
@@ -1344,7 +1427,7 @@ static void md_update_sb(mddev_t * mddev)
1344 int sync_req; 1427 int sync_req;
1345 1428
1346repeat: 1429repeat:
1347 spin_lock(&mddev->write_lock); 1430 spin_lock_irq(&mddev->write_lock);
1348 sync_req = mddev->in_sync; 1431 sync_req = mddev->in_sync;
1349 mddev->utime = get_seconds(); 1432 mddev->utime = get_seconds();
1350 mddev->events ++; 1433 mddev->events ++;
@@ -1367,11 +1450,11 @@ repeat:
1367 */ 1450 */
1368 if (!mddev->persistent) { 1451 if (!mddev->persistent) {
1369 mddev->sb_dirty = 0; 1452 mddev->sb_dirty = 0;
1370 spin_unlock(&mddev->write_lock); 1453 spin_unlock_irq(&mddev->write_lock);
1371 wake_up(&mddev->sb_wait); 1454 wake_up(&mddev->sb_wait);
1372 return; 1455 return;
1373 } 1456 }
1374 spin_unlock(&mddev->write_lock); 1457 spin_unlock_irq(&mddev->write_lock);
1375 1458
1376 dprintk(KERN_INFO 1459 dprintk(KERN_INFO
1377 "md: updating %s RAID superblock on device (in sync %d)\n", 1460 "md: updating %s RAID superblock on device (in sync %d)\n",
@@ -1381,11 +1464,11 @@ repeat:
1381 ITERATE_RDEV(mddev,rdev,tmp) { 1464 ITERATE_RDEV(mddev,rdev,tmp) {
1382 char b[BDEVNAME_SIZE]; 1465 char b[BDEVNAME_SIZE];
1383 dprintk(KERN_INFO "md: "); 1466 dprintk(KERN_INFO "md: ");
1384 if (rdev->faulty) 1467 if (test_bit(Faulty, &rdev->flags))
1385 dprintk("(skipping faulty "); 1468 dprintk("(skipping faulty ");
1386 1469
1387 dprintk("%s ", bdevname(rdev->bdev,b)); 1470 dprintk("%s ", bdevname(rdev->bdev,b));
1388 if (!rdev->faulty) { 1471 if (!test_bit(Faulty, &rdev->flags)) {
1389 md_super_write(mddev,rdev, 1472 md_super_write(mddev,rdev,
1390 rdev->sb_offset<<1, rdev->sb_size, 1473 rdev->sb_offset<<1, rdev->sb_size,
1391 rdev->sb_page); 1474 rdev->sb_page);
@@ -1399,21 +1482,106 @@ repeat:
1399 /* only need to write one superblock... */ 1482 /* only need to write one superblock... */
1400 break; 1483 break;
1401 } 1484 }
1402 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 1485 md_super_wait(mddev);
1403 /* if there was a failure, sb_dirty was set to 1, and we re-write super */ 1486 /* if there was a failure, sb_dirty was set to 1, and we re-write super */
1404 1487
1405 spin_lock(&mddev->write_lock); 1488 spin_lock_irq(&mddev->write_lock);
1406 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) { 1489 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
1407 /* have to write it out again */ 1490 /* have to write it out again */
1408 spin_unlock(&mddev->write_lock); 1491 spin_unlock_irq(&mddev->write_lock);
1409 goto repeat; 1492 goto repeat;
1410 } 1493 }
1411 mddev->sb_dirty = 0; 1494 mddev->sb_dirty = 0;
1412 spin_unlock(&mddev->write_lock); 1495 spin_unlock_irq(&mddev->write_lock);
1413 wake_up(&mddev->sb_wait); 1496 wake_up(&mddev->sb_wait);
1414 1497
1415} 1498}
1416 1499
1500struct rdev_sysfs_entry {
1501 struct attribute attr;
1502 ssize_t (*show)(mdk_rdev_t *, char *);
1503 ssize_t (*store)(mdk_rdev_t *, const char *, size_t);
1504};
1505
1506static ssize_t
1507state_show(mdk_rdev_t *rdev, char *page)
1508{
1509 char *sep = "";
1510 int len=0;
1511
1512 if (test_bit(Faulty, &rdev->flags)) {
1513 len+= sprintf(page+len, "%sfaulty",sep);
1514 sep = ",";
1515 }
1516 if (test_bit(In_sync, &rdev->flags)) {
1517 len += sprintf(page+len, "%sin_sync",sep);
1518 sep = ",";
1519 }
1520 if (!test_bit(Faulty, &rdev->flags) &&
1521 !test_bit(In_sync, &rdev->flags)) {
1522 len += sprintf(page+len, "%sspare", sep);
1523 sep = ",";
1524 }
1525 return len+sprintf(page+len, "\n");
1526}
1527
1528static struct rdev_sysfs_entry
1529rdev_state = __ATTR_RO(state);
1530
1531static ssize_t
1532super_show(mdk_rdev_t *rdev, char *page)
1533{
1534 if (rdev->sb_loaded && rdev->sb_size) {
1535 memcpy(page, page_address(rdev->sb_page), rdev->sb_size);
1536 return rdev->sb_size;
1537 } else
1538 return 0;
1539}
1540static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
1541
1542static struct attribute *rdev_default_attrs[] = {
1543 &rdev_state.attr,
1544 &rdev_super.attr,
1545 NULL,
1546};
1547static ssize_t
1548rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1549{
1550 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1551 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1552
1553 if (!entry->show)
1554 return -EIO;
1555 return entry->show(rdev, page);
1556}
1557
1558static ssize_t
1559rdev_attr_store(struct kobject *kobj, struct attribute *attr,
1560 const char *page, size_t length)
1561{
1562 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1563 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1564
1565 if (!entry->store)
1566 return -EIO;
1567 return entry->store(rdev, page, length);
1568}
1569
1570static void rdev_free(struct kobject *ko)
1571{
1572 mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
1573 kfree(rdev);
1574}
1575static struct sysfs_ops rdev_sysfs_ops = {
1576 .show = rdev_attr_show,
1577 .store = rdev_attr_store,
1578};
1579static struct kobj_type rdev_ktype = {
1580 .release = rdev_free,
1581 .sysfs_ops = &rdev_sysfs_ops,
1582 .default_attrs = rdev_default_attrs,
1583};
1584
1417/* 1585/*
1418 * Import a device. If 'super_format' >= 0, then sanity check the superblock 1586 * Import a device. If 'super_format' >= 0, then sanity check the superblock
1419 * 1587 *
@@ -1445,11 +1613,15 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
1445 if (err) 1613 if (err)
1446 goto abort_free; 1614 goto abort_free;
1447 1615
1616 rdev->kobj.parent = NULL;
1617 rdev->kobj.ktype = &rdev_ktype;
1618 kobject_init(&rdev->kobj);
1619
1448 rdev->desc_nr = -1; 1620 rdev->desc_nr = -1;
1449 rdev->faulty = 0; 1621 rdev->flags = 0;
1450 rdev->in_sync = 0;
1451 rdev->data_offset = 0; 1622 rdev->data_offset = 0;
1452 atomic_set(&rdev->nr_pending, 0); 1623 atomic_set(&rdev->nr_pending, 0);
1624 atomic_set(&rdev->read_errors, 0);
1453 1625
1454 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; 1626 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
1455 if (!size) { 1627 if (!size) {
@@ -1537,7 +1709,7 @@ static void analyze_sbs(mddev_t * mddev)
1537 if (mddev->level == LEVEL_MULTIPATH) { 1709 if (mddev->level == LEVEL_MULTIPATH) {
1538 rdev->desc_nr = i++; 1710 rdev->desc_nr = i++;
1539 rdev->raid_disk = rdev->desc_nr; 1711 rdev->raid_disk = rdev->desc_nr;
1540 rdev->in_sync = 1; 1712 set_bit(In_sync, &rdev->flags);
1541 } 1713 }
1542 } 1714 }
1543 1715
@@ -1551,6 +1723,162 @@ static void analyze_sbs(mddev_t * mddev)
1551 1723
1552} 1724}
1553 1725
1726static ssize_t
1727level_show(mddev_t *mddev, char *page)
1728{
1729 mdk_personality_t *p = mddev->pers;
1730 if (p == NULL && mddev->raid_disks == 0)
1731 return 0;
1732 if (mddev->level >= 0)
1733 return sprintf(page, "RAID-%d\n", mddev->level);
1734 else
1735 return sprintf(page, "%s\n", p->name);
1736}
1737
1738static struct md_sysfs_entry md_level = __ATTR_RO(level);
1739
1740static ssize_t
1741raid_disks_show(mddev_t *mddev, char *page)
1742{
1743 if (mddev->raid_disks == 0)
1744 return 0;
1745 return sprintf(page, "%d\n", mddev->raid_disks);
1746}
1747
1748static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks);
1749
1750static ssize_t
1751action_show(mddev_t *mddev, char *page)
1752{
1753 char *type = "idle";
1754 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1755 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
1756 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
1757 if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1758 type = "resync";
1759 else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
1760 type = "check";
1761 else
1762 type = "repair";
1763 } else
1764 type = "recover";
1765 }
1766 return sprintf(page, "%s\n", type);
1767}
1768
1769static ssize_t
1770action_store(mddev_t *mddev, const char *page, size_t len)
1771{
1772 if (!mddev->pers || !mddev->pers->sync_request)
1773 return -EINVAL;
1774
1775 if (strcmp(page, "idle")==0 || strcmp(page, "idle\n")==0) {
1776 if (mddev->sync_thread) {
1777 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
1778 md_unregister_thread(mddev->sync_thread);
1779 mddev->sync_thread = NULL;
1780 mddev->recovery = 0;
1781 }
1782 return len;
1783 }
1784
1785 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1786 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
1787 return -EBUSY;
1788 if (strcmp(page, "resync")==0 || strcmp(page, "resync\n")==0 ||
1789 strcmp(page, "recover")==0 || strcmp(page, "recover\n")==0)
1790 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1791 else {
1792 if (strcmp(page, "check")==0 || strcmp(page, "check\n")==0)
1793 set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
1794 else if (strcmp(page, "repair")!=0 && strcmp(page, "repair\n")!=0)
1795 return -EINVAL;
1796 set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
1797 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
1798 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1799 }
1800 md_wakeup_thread(mddev->thread);
1801 return len;
1802}
1803
1804static ssize_t
1805mismatch_cnt_show(mddev_t *mddev, char *page)
1806{
1807 return sprintf(page, "%llu\n",
1808 (unsigned long long) mddev->resync_mismatches);
1809}
1810
1811static struct md_sysfs_entry
1812md_scan_mode = __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
1813
1814
1815static struct md_sysfs_entry
1816md_mismatches = __ATTR_RO(mismatch_cnt);
1817
1818static struct attribute *md_default_attrs[] = {
1819 &md_level.attr,
1820 &md_raid_disks.attr,
1821 NULL,
1822};
1823
1824static struct attribute *md_redundancy_attrs[] = {
1825 &md_scan_mode.attr,
1826 &md_mismatches.attr,
1827 NULL,
1828};
1829static struct attribute_group md_redundancy_group = {
1830 .name = NULL,
1831 .attrs = md_redundancy_attrs,
1832};
1833
1834
1835static ssize_t
1836md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1837{
1838 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1839 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1840 ssize_t rv;
1841
1842 if (!entry->show)
1843 return -EIO;
1844 mddev_lock(mddev);
1845 rv = entry->show(mddev, page);
1846 mddev_unlock(mddev);
1847 return rv;
1848}
1849
1850static ssize_t
1851md_attr_store(struct kobject *kobj, struct attribute *attr,
1852 const char *page, size_t length)
1853{
1854 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1855 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1856 ssize_t rv;
1857
1858 if (!entry->store)
1859 return -EIO;
1860 mddev_lock(mddev);
1861 rv = entry->store(mddev, page, length);
1862 mddev_unlock(mddev);
1863 return rv;
1864}
1865
1866static void md_free(struct kobject *ko)
1867{
1868 mddev_t *mddev = container_of(ko, mddev_t, kobj);
1869 kfree(mddev);
1870}
1871
1872static struct sysfs_ops md_sysfs_ops = {
1873 .show = md_attr_show,
1874 .store = md_attr_store,
1875};
1876static struct kobj_type md_ktype = {
1877 .release = md_free,
1878 .sysfs_ops = &md_sysfs_ops,
1879 .default_attrs = md_default_attrs,
1880};
1881
1554int mdp_major = 0; 1882int mdp_major = 0;
1555 1883
1556static struct kobject *md_probe(dev_t dev, int *part, void *data) 1884static struct kobject *md_probe(dev_t dev, int *part, void *data)
@@ -1592,6 +1920,11 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
1592 add_disk(disk); 1920 add_disk(disk);
1593 mddev->gendisk = disk; 1921 mddev->gendisk = disk;
1594 up(&disks_sem); 1922 up(&disks_sem);
1923 mddev->kobj.parent = &disk->kobj;
1924 mddev->kobj.k_name = NULL;
1925 snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
1926 mddev->kobj.ktype = &md_ktype;
1927 kobject_register(&mddev->kobj);
1595 return NULL; 1928 return NULL;
1596} 1929}
1597 1930
@@ -1663,7 +1996,7 @@ static int do_md_run(mddev_t * mddev)
1663 1996
1664 /* devices must have minimum size of one chunk */ 1997 /* devices must have minimum size of one chunk */
1665 ITERATE_RDEV(mddev,rdev,tmp) { 1998 ITERATE_RDEV(mddev,rdev,tmp) {
1666 if (rdev->faulty) 1999 if (test_bit(Faulty, &rdev->flags))
1667 continue; 2000 continue;
1668 if (rdev->size < chunk_size / 1024) { 2001 if (rdev->size < chunk_size / 1024) {
1669 printk(KERN_WARNING 2002 printk(KERN_WARNING
@@ -1691,7 +2024,7 @@ static int do_md_run(mddev_t * mddev)
1691 * Also find largest hardsector size 2024 * Also find largest hardsector size
1692 */ 2025 */
1693 ITERATE_RDEV(mddev,rdev,tmp) { 2026 ITERATE_RDEV(mddev,rdev,tmp) {
1694 if (rdev->faulty) 2027 if (test_bit(Faulty, &rdev->flags))
1695 continue; 2028 continue;
1696 sync_blockdev(rdev->bdev); 2029 sync_blockdev(rdev->bdev);
1697 invalidate_bdev(rdev->bdev, 0); 2030 invalidate_bdev(rdev->bdev, 0);
@@ -1715,6 +2048,10 @@ static int do_md_run(mddev_t * mddev)
1715 2048
1716 mddev->recovery = 0; 2049 mddev->recovery = 0;
1717 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ 2050 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
2051 mddev->barriers_work = 1;
2052
2053 if (start_readonly)
2054 mddev->ro = 2; /* read-only, but switch on first write */
1718 2055
1719 /* before we start the array running, initialise the bitmap */ 2056 /* before we start the array running, initialise the bitmap */
1720 err = bitmap_create(mddev); 2057 err = bitmap_create(mddev);
@@ -1730,12 +2067,24 @@ static int do_md_run(mddev_t * mddev)
1730 bitmap_destroy(mddev); 2067 bitmap_destroy(mddev);
1731 return err; 2068 return err;
1732 } 2069 }
2070 if (mddev->pers->sync_request)
2071 sysfs_create_group(&mddev->kobj, &md_redundancy_group);
2072 else if (mddev->ro == 2) /* auto-readonly not meaningful */
2073 mddev->ro = 0;
2074
1733 atomic_set(&mddev->writes_pending,0); 2075 atomic_set(&mddev->writes_pending,0);
1734 mddev->safemode = 0; 2076 mddev->safemode = 0;
1735 mddev->safemode_timer.function = md_safemode_timeout; 2077 mddev->safemode_timer.function = md_safemode_timeout;
1736 mddev->safemode_timer.data = (unsigned long) mddev; 2078 mddev->safemode_timer.data = (unsigned long) mddev;
1737 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */ 2079 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */
1738 mddev->in_sync = 1; 2080 mddev->in_sync = 1;
2081
2082 ITERATE_RDEV(mddev,rdev,tmp)
2083 if (rdev->raid_disk >= 0) {
2084 char nm[20];
2085 sprintf(nm, "rd%d", rdev->raid_disk);
2086 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
2087 }
1739 2088
1740 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2089 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1741 md_wakeup_thread(mddev->thread); 2090 md_wakeup_thread(mddev->thread);
@@ -1821,16 +2170,19 @@ static int do_md_stop(mddev_t * mddev, int ro)
1821 2170
1822 if (ro) { 2171 if (ro) {
1823 err = -ENXIO; 2172 err = -ENXIO;
1824 if (mddev->ro) 2173 if (mddev->ro==1)
1825 goto out; 2174 goto out;
1826 mddev->ro = 1; 2175 mddev->ro = 1;
1827 } else { 2176 } else {
1828 bitmap_flush(mddev); 2177 bitmap_flush(mddev);
1829 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 2178 md_super_wait(mddev);
1830 if (mddev->ro) 2179 if (mddev->ro)
1831 set_disk_ro(disk, 0); 2180 set_disk_ro(disk, 0);
1832 blk_queue_make_request(mddev->queue, md_fail_request); 2181 blk_queue_make_request(mddev->queue, md_fail_request);
1833 mddev->pers->stop(mddev); 2182 mddev->pers->stop(mddev);
2183 if (mddev->pers->sync_request)
2184 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
2185
1834 module_put(mddev->pers->owner); 2186 module_put(mddev->pers->owner);
1835 mddev->pers = NULL; 2187 mddev->pers = NULL;
1836 if (mddev->ro) 2188 if (mddev->ro)
@@ -1857,9 +2209,18 @@ static int do_md_stop(mddev_t * mddev, int ro)
1857 * Free resources if final stop 2209 * Free resources if final stop
1858 */ 2210 */
1859 if (!ro) { 2211 if (!ro) {
2212 mdk_rdev_t *rdev;
2213 struct list_head *tmp;
1860 struct gendisk *disk; 2214 struct gendisk *disk;
1861 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); 2215 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
1862 2216
2217 ITERATE_RDEV(mddev,rdev,tmp)
2218 if (rdev->raid_disk >= 0) {
2219 char nm[20];
2220 sprintf(nm, "rd%d", rdev->raid_disk);
2221 sysfs_remove_link(&mddev->kobj, nm);
2222 }
2223
1863 export_array(mddev); 2224 export_array(mddev);
1864 2225
1865 mddev->array_size = 0; 2226 mddev->array_size = 0;
@@ -2012,7 +2373,7 @@ static int autostart_array(dev_t startdev)
2012 return err; 2373 return err;
2013 } 2374 }
2014 2375
2015 if (start_rdev->faulty) { 2376 if (test_bit(Faulty, &start_rdev->flags)) {
2016 printk(KERN_WARNING 2377 printk(KERN_WARNING
2017 "md: can not autostart based on faulty %s!\n", 2378 "md: can not autostart based on faulty %s!\n",
2018 bdevname(start_rdev->bdev,b)); 2379 bdevname(start_rdev->bdev,b));
@@ -2071,11 +2432,11 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
2071 nr=working=active=failed=spare=0; 2432 nr=working=active=failed=spare=0;
2072 ITERATE_RDEV(mddev,rdev,tmp) { 2433 ITERATE_RDEV(mddev,rdev,tmp) {
2073 nr++; 2434 nr++;
2074 if (rdev->faulty) 2435 if (test_bit(Faulty, &rdev->flags))
2075 failed++; 2436 failed++;
2076 else { 2437 else {
2077 working++; 2438 working++;
2078 if (rdev->in_sync) 2439 if (test_bit(In_sync, &rdev->flags))
2079 active++; 2440 active++;
2080 else 2441 else
2081 spare++; 2442 spare++;
@@ -2166,9 +2527,9 @@ static int get_disk_info(mddev_t * mddev, void __user * arg)
2166 info.minor = MINOR(rdev->bdev->bd_dev); 2527 info.minor = MINOR(rdev->bdev->bd_dev);
2167 info.raid_disk = rdev->raid_disk; 2528 info.raid_disk = rdev->raid_disk;
2168 info.state = 0; 2529 info.state = 0;
2169 if (rdev->faulty) 2530 if (test_bit(Faulty, &rdev->flags))
2170 info.state |= (1<<MD_DISK_FAULTY); 2531 info.state |= (1<<MD_DISK_FAULTY);
2171 else if (rdev->in_sync) { 2532 else if (test_bit(In_sync, &rdev->flags)) {
2172 info.state |= (1<<MD_DISK_ACTIVE); 2533 info.state |= (1<<MD_DISK_ACTIVE);
2173 info.state |= (1<<MD_DISK_SYNC); 2534 info.state |= (1<<MD_DISK_SYNC);
2174 } 2535 }
@@ -2261,7 +2622,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2261 validate_super(mddev, rdev); 2622 validate_super(mddev, rdev);
2262 rdev->saved_raid_disk = rdev->raid_disk; 2623 rdev->saved_raid_disk = rdev->raid_disk;
2263 2624
2264 rdev->in_sync = 0; /* just to be sure */ 2625 clear_bit(In_sync, &rdev->flags); /* just to be sure */
2265 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2626 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2266 set_bit(WriteMostly, &rdev->flags); 2627 set_bit(WriteMostly, &rdev->flags);
2267 2628
@@ -2299,11 +2660,11 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2299 else 2660 else
2300 rdev->raid_disk = -1; 2661 rdev->raid_disk = -1;
2301 2662
2302 rdev->faulty = 0; 2663 rdev->flags = 0;
2664
2303 if (rdev->raid_disk < mddev->raid_disks) 2665 if (rdev->raid_disk < mddev->raid_disks)
2304 rdev->in_sync = (info->state & (1<<MD_DISK_SYNC)); 2666 if (info->state & (1<<MD_DISK_SYNC))
2305 else 2667 set_bit(In_sync, &rdev->flags);
2306 rdev->in_sync = 0;
2307 2668
2308 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2669 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2309 set_bit(WriteMostly, &rdev->flags); 2670 set_bit(WriteMostly, &rdev->flags);
@@ -2402,14 +2763,14 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
2402 goto abort_export; 2763 goto abort_export;
2403 } 2764 }
2404 2765
2405 if (rdev->faulty) { 2766 if (test_bit(Faulty, &rdev->flags)) {
2406 printk(KERN_WARNING 2767 printk(KERN_WARNING
2407 "md: can not hot-add faulty %s disk to %s!\n", 2768 "md: can not hot-add faulty %s disk to %s!\n",
2408 bdevname(rdev->bdev,b), mdname(mddev)); 2769 bdevname(rdev->bdev,b), mdname(mddev));
2409 err = -EINVAL; 2770 err = -EINVAL;
2410 goto abort_export; 2771 goto abort_export;
2411 } 2772 }
2412 rdev->in_sync = 0; 2773 clear_bit(In_sync, &rdev->flags);
2413 rdev->desc_nr = -1; 2774 rdev->desc_nr = -1;
2414 bind_rdev_to_array(rdev, mddev); 2775 bind_rdev_to_array(rdev, mddev);
2415 2776
@@ -2929,12 +3290,22 @@ static int md_ioctl(struct inode *inode, struct file *file,
2929 3290
2930 /* 3291 /*
2931 * The remaining ioctls are changing the state of the 3292 * The remaining ioctls are changing the state of the
2932 * superblock, so we do not allow read-only arrays 3293 * superblock, so we do not allow them on read-only arrays.
2933 * here: 3294 * However non-MD ioctls (e.g. get-size) will still come through
3295 * here and hit the 'default' below, so only disallow
3296 * 'md' ioctls, and switch to rw mode if started auto-readonly.
2934 */ 3297 */
2935 if (mddev->ro) { 3298 if (_IOC_TYPE(cmd) == MD_MAJOR &&
2936 err = -EROFS; 3299 mddev->ro && mddev->pers) {
2937 goto abort_unlock; 3300 if (mddev->ro == 2) {
3301 mddev->ro = 0;
3302 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3303 md_wakeup_thread(mddev->thread);
3304
3305 } else {
3306 err = -EROFS;
3307 goto abort_unlock;
3308 }
2938 } 3309 }
2939 3310
2940 switch (cmd) 3311 switch (cmd)
@@ -3064,21 +3435,17 @@ static int md_thread(void * arg)
3064 */ 3435 */
3065 3436
3066 allow_signal(SIGKILL); 3437 allow_signal(SIGKILL);
3067 complete(thread->event);
3068 while (!kthread_should_stop()) { 3438 while (!kthread_should_stop()) {
3069 void (*run)(mddev_t *);
3070 3439
3071 wait_event_interruptible_timeout(thread->wqueue, 3440 wait_event_timeout(thread->wqueue,
3072 test_bit(THREAD_WAKEUP, &thread->flags) 3441 test_bit(THREAD_WAKEUP, &thread->flags)
3073 || kthread_should_stop(), 3442 || kthread_should_stop(),
3074 thread->timeout); 3443 thread->timeout);
3075 try_to_freeze(); 3444 try_to_freeze();
3076 3445
3077 clear_bit(THREAD_WAKEUP, &thread->flags); 3446 clear_bit(THREAD_WAKEUP, &thread->flags);
3078 3447
3079 run = thread->run; 3448 thread->run(thread->mddev);
3080 if (run)
3081 run(thread->mddev);
3082 } 3449 }
3083 3450
3084 return 0; 3451 return 0;
@@ -3097,7 +3464,6 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3097 const char *name) 3464 const char *name)
3098{ 3465{
3099 mdk_thread_t *thread; 3466 mdk_thread_t *thread;
3100 struct completion event;
3101 3467
3102 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL); 3468 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
3103 if (!thread) 3469 if (!thread)
@@ -3106,18 +3472,14 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3106 memset(thread, 0, sizeof(mdk_thread_t)); 3472 memset(thread, 0, sizeof(mdk_thread_t));
3107 init_waitqueue_head(&thread->wqueue); 3473 init_waitqueue_head(&thread->wqueue);
3108 3474
3109 init_completion(&event);
3110 thread->event = &event;
3111 thread->run = run; 3475 thread->run = run;
3112 thread->mddev = mddev; 3476 thread->mddev = mddev;
3113 thread->name = name;
3114 thread->timeout = MAX_SCHEDULE_TIMEOUT; 3477 thread->timeout = MAX_SCHEDULE_TIMEOUT;
3115 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev)); 3478 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev));
3116 if (IS_ERR(thread->tsk)) { 3479 if (IS_ERR(thread->tsk)) {
3117 kfree(thread); 3480 kfree(thread);
3118 return NULL; 3481 return NULL;
3119 } 3482 }
3120 wait_for_completion(&event);
3121 return thread; 3483 return thread;
3122} 3484}
3123 3485
@@ -3136,7 +3498,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
3136 return; 3498 return;
3137 } 3499 }
3138 3500
3139 if (!rdev || rdev->faulty) 3501 if (!rdev || test_bit(Faulty, &rdev->flags))
3140 return; 3502 return;
3141/* 3503/*
3142 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", 3504 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
@@ -3322,8 +3684,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
3322 seq_printf(seq, "%s : %sactive", mdname(mddev), 3684 seq_printf(seq, "%s : %sactive", mdname(mddev),
3323 mddev->pers ? "" : "in"); 3685 mddev->pers ? "" : "in");
3324 if (mddev->pers) { 3686 if (mddev->pers) {
3325 if (mddev->ro) 3687 if (mddev->ro==1)
3326 seq_printf(seq, " (read-only)"); 3688 seq_printf(seq, " (read-only)");
3689 if (mddev->ro==2)
3690 seq_printf(seq, "(auto-read-only)");
3327 seq_printf(seq, " %s", mddev->pers->name); 3691 seq_printf(seq, " %s", mddev->pers->name);
3328 } 3692 }
3329 3693
@@ -3334,7 +3698,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
3334 bdevname(rdev->bdev,b), rdev->desc_nr); 3698 bdevname(rdev->bdev,b), rdev->desc_nr);
3335 if (test_bit(WriteMostly, &rdev->flags)) 3699 if (test_bit(WriteMostly, &rdev->flags))
3336 seq_printf(seq, "(W)"); 3700 seq_printf(seq, "(W)");
3337 if (rdev->faulty) { 3701 if (test_bit(Faulty, &rdev->flags)) {
3338 seq_printf(seq, "(F)"); 3702 seq_printf(seq, "(F)");
3339 continue; 3703 continue;
3340 } else if (rdev->raid_disk < 0) 3704 } else if (rdev->raid_disk < 0)
@@ -3363,11 +3727,15 @@ static int md_seq_show(struct seq_file *seq, void *v)
3363 if (mddev->pers) { 3727 if (mddev->pers) {
3364 mddev->pers->status (seq, mddev); 3728 mddev->pers->status (seq, mddev);
3365 seq_printf(seq, "\n "); 3729 seq_printf(seq, "\n ");
3366 if (mddev->curr_resync > 2) { 3730 if (mddev->pers->sync_request) {
3367 status_resync (seq, mddev); 3731 if (mddev->curr_resync > 2) {
3368 seq_printf(seq, "\n "); 3732 status_resync (seq, mddev);
3369 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) 3733 seq_printf(seq, "\n ");
3370 seq_printf(seq, " resync=DELAYED\n "); 3734 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
3735 seq_printf(seq, "\tresync=DELAYED\n ");
3736 else if (mddev->recovery_cp < MaxSector)
3737 seq_printf(seq, "\tresync=PENDING\n ");
3738 }
3371 } else 3739 } else
3372 seq_printf(seq, "\n "); 3740 seq_printf(seq, "\n ");
3373 3741
@@ -3504,15 +3872,22 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
3504 if (bio_data_dir(bi) != WRITE) 3872 if (bio_data_dir(bi) != WRITE)
3505 return; 3873 return;
3506 3874
3875 BUG_ON(mddev->ro == 1);
3876 if (mddev->ro == 2) {
3877 /* need to switch to read/write */
3878 mddev->ro = 0;
3879 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3880 md_wakeup_thread(mddev->thread);
3881 }
3507 atomic_inc(&mddev->writes_pending); 3882 atomic_inc(&mddev->writes_pending);
3508 if (mddev->in_sync) { 3883 if (mddev->in_sync) {
3509 spin_lock(&mddev->write_lock); 3884 spin_lock_irq(&mddev->write_lock);
3510 if (mddev->in_sync) { 3885 if (mddev->in_sync) {
3511 mddev->in_sync = 0; 3886 mddev->in_sync = 0;
3512 mddev->sb_dirty = 1; 3887 mddev->sb_dirty = 1;
3513 md_wakeup_thread(mddev->thread); 3888 md_wakeup_thread(mddev->thread);
3514 } 3889 }
3515 spin_unlock(&mddev->write_lock); 3890 spin_unlock_irq(&mddev->write_lock);
3516 } 3891 }
3517 wait_event(mddev->sb_wait, mddev->sb_dirty==0); 3892 wait_event(mddev->sb_wait, mddev->sb_dirty==0);
3518} 3893}
@@ -3568,9 +3943,7 @@ static void md_do_sync(mddev_t *mddev)
3568 mddev->curr_resync = 2; 3943 mddev->curr_resync = 2;
3569 3944
3570 try_again: 3945 try_again:
3571 if (signal_pending(current) || 3946 if (kthread_should_stop()) {
3572 kthread_should_stop()) {
3573 flush_signals(current);
3574 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 3947 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3575 goto skip; 3948 goto skip;
3576 } 3949 }
@@ -3590,9 +3963,8 @@ static void md_do_sync(mddev_t *mddev)
3590 * time 'round when curr_resync == 2 3963 * time 'round when curr_resync == 2
3591 */ 3964 */
3592 continue; 3965 continue;
3593 prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE); 3966 prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
3594 if (!signal_pending(current) && 3967 if (!kthread_should_stop() &&
3595 !kthread_should_stop() &&
3596 mddev2->curr_resync >= mddev->curr_resync) { 3968 mddev2->curr_resync >= mddev->curr_resync) {
3597 printk(KERN_INFO "md: delaying resync of %s" 3969 printk(KERN_INFO "md: delaying resync of %s"
3598 " until %s has finished resync (they" 3970 " until %s has finished resync (they"
@@ -3608,12 +3980,13 @@ static void md_do_sync(mddev_t *mddev)
3608 } 3980 }
3609 } while (mddev->curr_resync < 2); 3981 } while (mddev->curr_resync < 2);
3610 3982
3611 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) 3983 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
3612 /* resync follows the size requested by the personality, 3984 /* resync follows the size requested by the personality,
3613 * which defaults to physical size, but can be virtual size 3985 * which defaults to physical size, but can be virtual size
3614 */ 3986 */
3615 max_sectors = mddev->resync_max_sectors; 3987 max_sectors = mddev->resync_max_sectors;
3616 else 3988 mddev->resync_mismatches = 0;
3989 } else
3617 /* recovery follows the physical size of devices */ 3990 /* recovery follows the physical size of devices */
3618 max_sectors = mddev->size << 1; 3991 max_sectors = mddev->size << 1;
3619 3992
@@ -3626,7 +3999,8 @@ static void md_do_sync(mddev_t *mddev)
3626 3999
3627 is_mddev_idle(mddev); /* this also initializes IO event counters */ 4000 is_mddev_idle(mddev); /* this also initializes IO event counters */
3628 /* we don't use the checkpoint if there's a bitmap */ 4001 /* we don't use the checkpoint if there's a bitmap */
3629 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap) 4002 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap
4003 && ! test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
3630 j = mddev->recovery_cp; 4004 j = mddev->recovery_cp;
3631 else 4005 else
3632 j = 0; 4006 j = 0;
@@ -3699,13 +4073,12 @@ static void md_do_sync(mddev_t *mddev)
3699 } 4073 }
3700 4074
3701 4075
3702 if (signal_pending(current) || kthread_should_stop()) { 4076 if (kthread_should_stop()) {
3703 /* 4077 /*
3704 * got a signal, exit. 4078 * got a signal, exit.
3705 */ 4079 */
3706 printk(KERN_INFO 4080 printk(KERN_INFO
3707 "md: md_do_sync() got signal ... exiting\n"); 4081 "md: md_do_sync() got signal ... exiting\n");
3708 flush_signals(current);
3709 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 4082 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3710 goto out; 4083 goto out;
3711 } 4084 }
@@ -3727,7 +4100,7 @@ static void md_do_sync(mddev_t *mddev)
3727 if (currspeed > sysctl_speed_limit_min) { 4100 if (currspeed > sysctl_speed_limit_min) {
3728 if ((currspeed > sysctl_speed_limit_max) || 4101 if ((currspeed > sysctl_speed_limit_max) ||
3729 !is_mddev_idle(mddev)) { 4102 !is_mddev_idle(mddev)) {
3730 msleep_interruptible(250); 4103 msleep(250);
3731 goto repeat; 4104 goto repeat;
3732 } 4105 }
3733 } 4106 }
@@ -3820,7 +4193,7 @@ void md_check_recovery(mddev_t *mddev)
3820 if (mddev_trylock(mddev)==0) { 4193 if (mddev_trylock(mddev)==0) {
3821 int spares =0; 4194 int spares =0;
3822 4195
3823 spin_lock(&mddev->write_lock); 4196 spin_lock_irq(&mddev->write_lock);
3824 if (mddev->safemode && !atomic_read(&mddev->writes_pending) && 4197 if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
3825 !mddev->in_sync && mddev->recovery_cp == MaxSector) { 4198 !mddev->in_sync && mddev->recovery_cp == MaxSector) {
3826 mddev->in_sync = 1; 4199 mddev->in_sync = 1;
@@ -3828,7 +4201,7 @@ void md_check_recovery(mddev_t *mddev)
3828 } 4201 }
3829 if (mddev->safemode == 1) 4202 if (mddev->safemode == 1)
3830 mddev->safemode = 0; 4203 mddev->safemode = 0;
3831 spin_unlock(&mddev->write_lock); 4204 spin_unlock_irq(&mddev->write_lock);
3832 4205
3833 if (mddev->sb_dirty) 4206 if (mddev->sb_dirty)
3834 md_update_sb(mddev); 4207 md_update_sb(mddev);
@@ -3864,9 +4237,13 @@ void md_check_recovery(mddev_t *mddev)
3864 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4237 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3865 goto unlock; 4238 goto unlock;
3866 } 4239 }
3867 if (mddev->recovery) 4240 /* Clear some bits that don't mean anything, but
3868 /* probably just the RECOVERY_NEEDED flag */ 4241 * might be left set
3869 mddev->recovery = 0; 4242 */
4243 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4244 clear_bit(MD_RECOVERY_ERR, &mddev->recovery);
4245 clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
4246 clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
3870 4247
3871 /* no recovery is running. 4248 /* no recovery is running.
3872 * remove any failed drives, then 4249 * remove any failed drives, then
@@ -3876,31 +4253,41 @@ void md_check_recovery(mddev_t *mddev)
3876 */ 4253 */
3877 ITERATE_RDEV(mddev,rdev,rtmp) 4254 ITERATE_RDEV(mddev,rdev,rtmp)
3878 if (rdev->raid_disk >= 0 && 4255 if (rdev->raid_disk >= 0 &&
3879 (rdev->faulty || ! rdev->in_sync) && 4256 (test_bit(Faulty, &rdev->flags) || ! test_bit(In_sync, &rdev->flags)) &&
3880 atomic_read(&rdev->nr_pending)==0) { 4257 atomic_read(&rdev->nr_pending)==0) {
3881 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) 4258 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) {
4259 char nm[20];
4260 sprintf(nm,"rd%d", rdev->raid_disk);
4261 sysfs_remove_link(&mddev->kobj, nm);
3882 rdev->raid_disk = -1; 4262 rdev->raid_disk = -1;
4263 }
3883 } 4264 }
3884 4265
3885 if (mddev->degraded) { 4266 if (mddev->degraded) {
3886 ITERATE_RDEV(mddev,rdev,rtmp) 4267 ITERATE_RDEV(mddev,rdev,rtmp)
3887 if (rdev->raid_disk < 0 4268 if (rdev->raid_disk < 0
3888 && !rdev->faulty) { 4269 && !test_bit(Faulty, &rdev->flags)) {
3889 if (mddev->pers->hot_add_disk(mddev,rdev)) 4270 if (mddev->pers->hot_add_disk(mddev,rdev)) {
4271 char nm[20];
4272 sprintf(nm, "rd%d", rdev->raid_disk);
4273 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
3890 spares++; 4274 spares++;
3891 else 4275 } else
3892 break; 4276 break;
3893 } 4277 }
3894 } 4278 }
3895 4279
3896 if (!spares && (mddev->recovery_cp == MaxSector )) { 4280 if (spares) {
3897 /* nothing we can do ... */ 4281 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4282 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
4283 } else if (mddev->recovery_cp < MaxSector) {
4284 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4285 } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
4286 /* nothing to be done ... */
3898 goto unlock; 4287 goto unlock;
3899 } 4288
3900 if (mddev->pers->sync_request) { 4289 if (mddev->pers->sync_request) {
3901 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); 4290 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
3902 if (!spares)
3903 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
3904 if (spares && mddev->bitmap && ! mddev->bitmap->file) { 4291 if (spares && mddev->bitmap && ! mddev->bitmap->file) {
3905 /* We are adding a device or devices to an array 4292 /* We are adding a device or devices to an array
3906 * which has the bitmap stored on all devices. 4293 * which has the bitmap stored on all devices.
@@ -3975,7 +4362,7 @@ static int __init md_init(void)
3975 " MD_SB_DISKS=%d\n", 4362 " MD_SB_DISKS=%d\n",
3976 MD_MAJOR_VERSION, MD_MINOR_VERSION, 4363 MD_MAJOR_VERSION, MD_MINOR_VERSION,
3977 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); 4364 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
3978 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR, 4365 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
3979 BITMAP_MINOR); 4366 BITMAP_MINOR);
3980 4367
3981 if (register_blkdev(MAJOR_NR, "md")) 4368 if (register_blkdev(MAJOR_NR, "md"))
@@ -4039,7 +4426,7 @@ static void autostart_arrays(int part)
4039 if (IS_ERR(rdev)) 4426 if (IS_ERR(rdev))
4040 continue; 4427 continue;
4041 4428
4042 if (rdev->faulty) { 4429 if (test_bit(Faulty, &rdev->flags)) {
4043 MD_BUG(); 4430 MD_BUG();
4044 continue; 4431 continue;
4045 } 4432 }
@@ -4086,6 +4473,23 @@ static __exit void md_exit(void)
4086module_init(md_init) 4473module_init(md_init)
4087module_exit(md_exit) 4474module_exit(md_exit)
4088 4475
4476static int get_ro(char *buffer, struct kernel_param *kp)
4477{
4478 return sprintf(buffer, "%d", start_readonly);
4479}
4480static int set_ro(const char *val, struct kernel_param *kp)
4481{
4482 char *e;
4483 int num = simple_strtoul(val, &e, 10);
4484 if (*val && (*e == '\0' || *e == '\n')) {
4485 start_readonly = num;
4486 return 0;;
4487 }
4488 return -EINVAL;
4489}
4490
4491module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
4492
4089EXPORT_SYMBOL(register_md_personality); 4493EXPORT_SYMBOL(register_md_personality);
4090EXPORT_SYMBOL(unregister_md_personality); 4494EXPORT_SYMBOL(unregister_md_personality);
4091EXPORT_SYMBOL(md_error); 4495EXPORT_SYMBOL(md_error);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index c06f4474192b..145cdc5ad008 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -63,8 +63,8 @@ static int multipath_map (multipath_conf_t *conf)
63 63
64 rcu_read_lock(); 64 rcu_read_lock();
65 for (i = 0; i < disks; i++) { 65 for (i = 0; i < disks; i++) {
66 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 66 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
67 if (rdev && rdev->in_sync) { 67 if (rdev && test_bit(In_sync, &rdev->flags)) {
68 atomic_inc(&rdev->nr_pending); 68 atomic_inc(&rdev->nr_pending);
69 rcu_read_unlock(); 69 rcu_read_unlock();
70 return i; 70 return i;
@@ -139,8 +139,9 @@ static void unplug_slaves(mddev_t *mddev)
139 139
140 rcu_read_lock(); 140 rcu_read_lock();
141 for (i=0; i<mddev->raid_disks; i++) { 141 for (i=0; i<mddev->raid_disks; i++) {
142 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 142 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
143 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 143 if (rdev && !test_bit(Faulty, &rdev->flags)
144 && atomic_read(&rdev->nr_pending)) {
144 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 145 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
145 146
146 atomic_inc(&rdev->nr_pending); 147 atomic_inc(&rdev->nr_pending);
@@ -211,7 +212,7 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
211 for (i = 0; i < conf->raid_disks; i++) 212 for (i = 0; i < conf->raid_disks; i++)
212 seq_printf (seq, "%s", 213 seq_printf (seq, "%s",
213 conf->multipaths[i].rdev && 214 conf->multipaths[i].rdev &&
214 conf->multipaths[i].rdev->in_sync ? "U" : "_"); 215 test_bit(In_sync, &conf->multipaths[i].rdev->flags) ? "U" : "_");
215 seq_printf (seq, "]"); 216 seq_printf (seq, "]");
216} 217}
217 218
@@ -224,8 +225,8 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk,
224 225
225 rcu_read_lock(); 226 rcu_read_lock();
226 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 227 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
227 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 228 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
228 if (rdev && !rdev->faulty) { 229 if (rdev && !test_bit(Faulty, &rdev->flags)) {
229 struct block_device *bdev = rdev->bdev; 230 struct block_device *bdev = rdev->bdev;
230 request_queue_t *r_queue = bdev_get_queue(bdev); 231 request_queue_t *r_queue = bdev_get_queue(bdev);
231 232
@@ -265,10 +266,10 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
265 /* 266 /*
266 * Mark disk as unusable 267 * Mark disk as unusable
267 */ 268 */
268 if (!rdev->faulty) { 269 if (!test_bit(Faulty, &rdev->flags)) {
269 char b[BDEVNAME_SIZE]; 270 char b[BDEVNAME_SIZE];
270 rdev->in_sync = 0; 271 clear_bit(In_sync, &rdev->flags);
271 rdev->faulty = 1; 272 set_bit(Faulty, &rdev->flags);
272 mddev->sb_dirty = 1; 273 mddev->sb_dirty = 1;
273 conf->working_disks--; 274 conf->working_disks--;
274 printk(KERN_ALERT "multipath: IO failure on %s," 275 printk(KERN_ALERT "multipath: IO failure on %s,"
@@ -298,7 +299,7 @@ static void print_multipath_conf (multipath_conf_t *conf)
298 tmp = conf->multipaths + i; 299 tmp = conf->multipaths + i;
299 if (tmp->rdev) 300 if (tmp->rdev)
300 printk(" disk%d, o:%d, dev:%s\n", 301 printk(" disk%d, o:%d, dev:%s\n",
301 i,!tmp->rdev->faulty, 302 i,!test_bit(Faulty, &tmp->rdev->flags),
302 bdevname(tmp->rdev->bdev,b)); 303 bdevname(tmp->rdev->bdev,b));
303 } 304 }
304} 305}
@@ -330,8 +331,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
330 331
331 conf->working_disks++; 332 conf->working_disks++;
332 rdev->raid_disk = path; 333 rdev->raid_disk = path;
333 rdev->in_sync = 1; 334 set_bit(In_sync, &rdev->flags);
334 p->rdev = rdev; 335 rcu_assign_pointer(p->rdev, rdev);
335 found = 1; 336 found = 1;
336 } 337 }
337 338
@@ -350,7 +351,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
350 351
351 rdev = p->rdev; 352 rdev = p->rdev;
352 if (rdev) { 353 if (rdev) {
353 if (rdev->in_sync || 354 if (test_bit(In_sync, &rdev->flags) ||
354 atomic_read(&rdev->nr_pending)) { 355 atomic_read(&rdev->nr_pending)) {
355 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number); 356 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number);
356 err = -EBUSY; 357 err = -EBUSY;
@@ -482,7 +483,7 @@ static int multipath_run (mddev_t *mddev)
482 mddev->queue->max_sectors > (PAGE_SIZE>>9)) 483 mddev->queue->max_sectors > (PAGE_SIZE>>9))
483 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 484 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
484 485
485 if (!rdev->faulty) 486 if (!test_bit(Faulty, &rdev->flags))
486 conf->working_disks++; 487 conf->working_disks++;
487 } 488 }
488 489
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e16f473bcf46..2da9d3ba902d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -301,7 +301,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
301{ 301{
302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); 303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
304 int mirror, behind; 304 int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
305 conf_t *conf = mddev_to_conf(r1_bio->mddev); 305 conf_t *conf = mddev_to_conf(r1_bio->mddev);
306 306
307 if (bio->bi_size) 307 if (bio->bi_size)
@@ -311,47 +311,54 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
311 if (r1_bio->bios[mirror] == bio) 311 if (r1_bio->bios[mirror] == bio)
312 break; 312 break;
313 313
314 /* 314 if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
315 * this branch is our 'one mirror IO has finished' event handler: 315 set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
316 */ 316 set_bit(R1BIO_BarrierRetry, &r1_bio->state);
317 if (!uptodate) { 317 r1_bio->mddev->barriers_work = 0;
318 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); 318 } else {
319 /* an I/O failed, we can't clear the bitmap */
320 set_bit(R1BIO_Degraded, &r1_bio->state);
321 } else
322 /* 319 /*
323 * Set R1BIO_Uptodate in our master bio, so that 320 * this branch is our 'one mirror IO has finished' event handler:
324 * we will return a good error code for to the higher
325 * levels even if IO on some other mirrored buffer fails.
326 *
327 * The 'master' represents the composite IO operation to
328 * user-side. So if something waits for IO, then it will
329 * wait for the 'master' bio.
330 */ 321 */
331 set_bit(R1BIO_Uptodate, &r1_bio->state); 322 r1_bio->bios[mirror] = NULL;
332 323 bio_put(bio);
333 update_head_pos(mirror, r1_bio); 324 if (!uptodate) {
334 325 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
335 behind = test_bit(R1BIO_BehindIO, &r1_bio->state); 326 /* an I/O failed, we can't clear the bitmap */
336 if (behind) { 327 set_bit(R1BIO_Degraded, &r1_bio->state);
337 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags)) 328 } else
338 atomic_dec(&r1_bio->behind_remaining); 329 /*
339 330 * Set R1BIO_Uptodate in our master bio, so that
340 /* In behind mode, we ACK the master bio once the I/O has safely 331 * we will return a good error code for to the higher
341 * reached all non-writemostly disks. Setting the Returned bit 332 * levels even if IO on some other mirrored buffer fails.
342 * ensures that this gets done only once -- we don't ever want to 333 *
343 * return -EIO here, instead we'll wait */ 334 * The 'master' represents the composite IO operation to
344 335 * user-side. So if something waits for IO, then it will
345 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) && 336 * wait for the 'master' bio.
346 test_bit(R1BIO_Uptodate, &r1_bio->state)) { 337 */
347 /* Maybe we can return now */ 338 set_bit(R1BIO_Uptodate, &r1_bio->state);
348 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) { 339
349 struct bio *mbio = r1_bio->master_bio; 340 update_head_pos(mirror, r1_bio);
350 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n", 341
351 (unsigned long long) mbio->bi_sector, 342 if (behind) {
352 (unsigned long long) mbio->bi_sector + 343 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
353 (mbio->bi_size >> 9) - 1); 344 atomic_dec(&r1_bio->behind_remaining);
354 bio_endio(mbio, mbio->bi_size, 0); 345
346 /* In behind mode, we ACK the master bio once the I/O has safely
347 * reached all non-writemostly disks. Setting the Returned bit
348 * ensures that this gets done only once -- we don't ever want to
349 * return -EIO here, instead we'll wait */
350
351 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
352 test_bit(R1BIO_Uptodate, &r1_bio->state)) {
353 /* Maybe we can return now */
354 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
355 struct bio *mbio = r1_bio->master_bio;
356 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
357 (unsigned long long) mbio->bi_sector,
358 (unsigned long long) mbio->bi_sector +
359 (mbio->bi_size >> 9) - 1);
360 bio_endio(mbio, mbio->bi_size, 0);
361 }
355 } 362 }
356 } 363 }
357 } 364 }
@@ -361,8 +368,16 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
361 * already. 368 * already.
362 */ 369 */
363 if (atomic_dec_and_test(&r1_bio->remaining)) { 370 if (atomic_dec_and_test(&r1_bio->remaining)) {
371 if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
372 reschedule_retry(r1_bio);
373 /* Don't dec_pending yet, we want to hold
374 * the reference over the retry
375 */
376 return 0;
377 }
364 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { 378 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
365 /* free extra copy of the data pages */ 379 /* free extra copy of the data pages */
380/* FIXME bio has been freed!!! */
366 int i = bio->bi_vcnt; 381 int i = bio->bi_vcnt;
367 while (i--) 382 while (i--)
368 __free_page(bio->bi_io_vec[i].bv_page); 383 __free_page(bio->bi_io_vec[i].bv_page);
@@ -416,12 +431,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
416 /* Choose the first operation device, for consistancy */ 431 /* Choose the first operation device, for consistancy */
417 new_disk = 0; 432 new_disk = 0;
418 433
419 for (rdev = conf->mirrors[new_disk].rdev; 434 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
420 !rdev || !rdev->in_sync 435 !rdev || !test_bit(In_sync, &rdev->flags)
421 || test_bit(WriteMostly, &rdev->flags); 436 || test_bit(WriteMostly, &rdev->flags);
422 rdev = conf->mirrors[++new_disk].rdev) { 437 rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
423 438
424 if (rdev && rdev->in_sync) 439 if (rdev && test_bit(In_sync, &rdev->flags))
425 wonly_disk = new_disk; 440 wonly_disk = new_disk;
426 441
427 if (new_disk == conf->raid_disks - 1) { 442 if (new_disk == conf->raid_disks - 1) {
@@ -434,12 +449,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
434 449
435 450
436 /* make sure the disk is operational */ 451 /* make sure the disk is operational */
437 for (rdev = conf->mirrors[new_disk].rdev; 452 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
438 !rdev || !rdev->in_sync || 453 !rdev || !test_bit(In_sync, &rdev->flags) ||
439 test_bit(WriteMostly, &rdev->flags); 454 test_bit(WriteMostly, &rdev->flags);
440 rdev = conf->mirrors[new_disk].rdev) { 455 rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
441 456
442 if (rdev && rdev->in_sync) 457 if (rdev && test_bit(In_sync, &rdev->flags))
443 wonly_disk = new_disk; 458 wonly_disk = new_disk;
444 459
445 if (new_disk <= 0) 460 if (new_disk <= 0)
@@ -474,10 +489,10 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
474 disk = conf->raid_disks; 489 disk = conf->raid_disks;
475 disk--; 490 disk--;
476 491
477 rdev = conf->mirrors[disk].rdev; 492 rdev = rcu_dereference(conf->mirrors[disk].rdev);
478 493
479 if (!rdev || 494 if (!rdev ||
480 !rdev->in_sync || 495 !test_bit(In_sync, &rdev->flags) ||
481 test_bit(WriteMostly, &rdev->flags)) 496 test_bit(WriteMostly, &rdev->flags))
482 continue; 497 continue;
483 498
@@ -496,11 +511,11 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
496 511
497 512
498 if (new_disk >= 0) { 513 if (new_disk >= 0) {
499 rdev = conf->mirrors[new_disk].rdev; 514 rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
500 if (!rdev) 515 if (!rdev)
501 goto retry; 516 goto retry;
502 atomic_inc(&rdev->nr_pending); 517 atomic_inc(&rdev->nr_pending);
503 if (!rdev->in_sync) { 518 if (!test_bit(In_sync, &rdev->flags)) {
504 /* cannot risk returning a device that failed 519 /* cannot risk returning a device that failed
505 * before we inc'ed nr_pending 520 * before we inc'ed nr_pending
506 */ 521 */
@@ -522,8 +537,8 @@ static void unplug_slaves(mddev_t *mddev)
522 537
523 rcu_read_lock(); 538 rcu_read_lock();
524 for (i=0; i<mddev->raid_disks; i++) { 539 for (i=0; i<mddev->raid_disks; i++) {
525 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 540 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
526 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 541 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
527 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 542 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
528 543
529 atomic_inc(&rdev->nr_pending); 544 atomic_inc(&rdev->nr_pending);
@@ -556,8 +571,8 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
556 571
557 rcu_read_lock(); 572 rcu_read_lock();
558 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 573 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
559 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 574 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
560 if (rdev && !rdev->faulty) { 575 if (rdev && !test_bit(Faulty, &rdev->flags)) {
561 struct block_device *bdev = rdev->bdev; 576 struct block_device *bdev = rdev->bdev;
562 request_queue_t *r_queue = bdev_get_queue(bdev); 577 request_queue_t *r_queue = bdev_get_queue(bdev);
563 578
@@ -648,8 +663,9 @@ static int make_request(request_queue_t *q, struct bio * bio)
648 struct bio_list bl; 663 struct bio_list bl;
649 struct page **behind_pages = NULL; 664 struct page **behind_pages = NULL;
650 const int rw = bio_data_dir(bio); 665 const int rw = bio_data_dir(bio);
666 int do_barriers;
651 667
652 if (unlikely(bio_barrier(bio))) { 668 if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
653 bio_endio(bio, bio->bi_size, -EOPNOTSUPP); 669 bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
654 return 0; 670 return 0;
655 } 671 }
@@ -728,10 +744,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
728#endif 744#endif
729 rcu_read_lock(); 745 rcu_read_lock();
730 for (i = 0; i < disks; i++) { 746 for (i = 0; i < disks; i++) {
731 if ((rdev=conf->mirrors[i].rdev) != NULL && 747 if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
732 !rdev->faulty) { 748 !test_bit(Faulty, &rdev->flags)) {
733 atomic_inc(&rdev->nr_pending); 749 atomic_inc(&rdev->nr_pending);
734 if (rdev->faulty) { 750 if (test_bit(Faulty, &rdev->flags)) {
735 atomic_dec(&rdev->nr_pending); 751 atomic_dec(&rdev->nr_pending);
736 r1_bio->bios[i] = NULL; 752 r1_bio->bios[i] = NULL;
737 } else 753 } else
@@ -759,6 +775,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
759 atomic_set(&r1_bio->remaining, 0); 775 atomic_set(&r1_bio->remaining, 0);
760 atomic_set(&r1_bio->behind_remaining, 0); 776 atomic_set(&r1_bio->behind_remaining, 0);
761 777
778 do_barriers = bio->bi_rw & BIO_RW_BARRIER;
779 if (do_barriers)
780 set_bit(R1BIO_Barrier, &r1_bio->state);
781
762 bio_list_init(&bl); 782 bio_list_init(&bl);
763 for (i = 0; i < disks; i++) { 783 for (i = 0; i < disks; i++) {
764 struct bio *mbio; 784 struct bio *mbio;
@@ -771,7 +791,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
771 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; 791 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
772 mbio->bi_bdev = conf->mirrors[i].rdev->bdev; 792 mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
773 mbio->bi_end_io = raid1_end_write_request; 793 mbio->bi_end_io = raid1_end_write_request;
774 mbio->bi_rw = WRITE; 794 mbio->bi_rw = WRITE | do_barriers;
775 mbio->bi_private = r1_bio; 795 mbio->bi_private = r1_bio;
776 796
777 if (behind_pages) { 797 if (behind_pages) {
@@ -824,7 +844,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 844 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 845 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 846 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 847 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 848 seq_printf(seq, "]");
829} 849}
830 850
@@ -840,14 +860,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
840 * next level up know. 860 * next level up know.
841 * else mark the drive as failed 861 * else mark the drive as failed
842 */ 862 */
843 if (rdev->in_sync 863 if (test_bit(In_sync, &rdev->flags)
844 && conf->working_disks == 1) 864 && conf->working_disks == 1)
845 /* 865 /*
846 * Don't fail the drive, act as though we were just a 866 * Don't fail the drive, act as though we were just a
847 * normal single drive 867 * normal single drive
848 */ 868 */
849 return; 869 return;
850 if (rdev->in_sync) { 870 if (test_bit(In_sync, &rdev->flags)) {
851 mddev->degraded++; 871 mddev->degraded++;
852 conf->working_disks--; 872 conf->working_disks--;
853 /* 873 /*
@@ -855,8 +875,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
855 */ 875 */
856 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 876 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
857 } 877 }
858 rdev->in_sync = 0; 878 clear_bit(In_sync, &rdev->flags);
859 rdev->faulty = 1; 879 set_bit(Faulty, &rdev->flags);
860 mddev->sb_dirty = 1; 880 mddev->sb_dirty = 1;
861 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" 881 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
862 " Operation continuing on %d devices\n", 882 " Operation continuing on %d devices\n",
@@ -881,7 +901,7 @@ static void print_conf(conf_t *conf)
881 tmp = conf->mirrors + i; 901 tmp = conf->mirrors + i;
882 if (tmp->rdev) 902 if (tmp->rdev)
883 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 903 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
884 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 904 i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags),
885 bdevname(tmp->rdev->bdev,b)); 905 bdevname(tmp->rdev->bdev,b));
886 } 906 }
887} 907}
@@ -913,11 +933,11 @@ static int raid1_spare_active(mddev_t *mddev)
913 for (i = 0; i < conf->raid_disks; i++) { 933 for (i = 0; i < conf->raid_disks; i++) {
914 tmp = conf->mirrors + i; 934 tmp = conf->mirrors + i;
915 if (tmp->rdev 935 if (tmp->rdev
916 && !tmp->rdev->faulty 936 && !test_bit(Faulty, &tmp->rdev->flags)
917 && !tmp->rdev->in_sync) { 937 && !test_bit(In_sync, &tmp->rdev->flags)) {
918 conf->working_disks++; 938 conf->working_disks++;
919 mddev->degraded--; 939 mddev->degraded--;
920 tmp->rdev->in_sync = 1; 940 set_bit(In_sync, &tmp->rdev->flags);
921 } 941 }
922 } 942 }
923 943
@@ -954,7 +974,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
954 found = 1; 974 found = 1;
955 if (rdev->saved_raid_disk != mirror) 975 if (rdev->saved_raid_disk != mirror)
956 conf->fullsync = 1; 976 conf->fullsync = 1;
957 p->rdev = rdev; 977 rcu_assign_pointer(p->rdev, rdev);
958 break; 978 break;
959 } 979 }
960 980
@@ -972,7 +992,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
972 print_conf(conf); 992 print_conf(conf);
973 rdev = p->rdev; 993 rdev = p->rdev;
974 if (rdev) { 994 if (rdev) {
975 if (rdev->in_sync || 995 if (test_bit(In_sync, &rdev->flags) ||
976 atomic_read(&rdev->nr_pending)) { 996 atomic_read(&rdev->nr_pending)) {
977 err = -EBUSY; 997 err = -EBUSY;
978 goto abort; 998 goto abort;
@@ -1153,6 +1173,36 @@ static void raid1d(mddev_t *mddev)
1153 if (test_bit(R1BIO_IsSync, &r1_bio->state)) { 1173 if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
1154 sync_request_write(mddev, r1_bio); 1174 sync_request_write(mddev, r1_bio);
1155 unplug = 1; 1175 unplug = 1;
1176 } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
1177 /* some requests in the r1bio were BIO_RW_BARRIER
1178 * requests which failed with -ENOTSUPP. Hohumm..
1179 * Better resubmit without the barrier.
1180 * We know which devices to resubmit for, because
1181 * all others have had their bios[] entry cleared.
1182 */
1183 int i;
1184 clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
1185 clear_bit(R1BIO_Barrier, &r1_bio->state);
1186 for (i=0; i < conf->raid_disks; i++)
1187 if (r1_bio->bios[i]) {
1188 struct bio_vec *bvec;
1189 int j;
1190
1191 bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
1192 /* copy pages from the failed bio, as
1193 * this might be a write-behind device */
1194 __bio_for_each_segment(bvec, bio, j, 0)
1195 bvec->bv_page = bio_iovec_idx(r1_bio->bios[i], j)->bv_page;
1196 bio_put(r1_bio->bios[i]);
1197 bio->bi_sector = r1_bio->sector +
1198 conf->mirrors[i].rdev->data_offset;
1199 bio->bi_bdev = conf->mirrors[i].rdev->bdev;
1200 bio->bi_end_io = raid1_end_write_request;
1201 bio->bi_rw = WRITE;
1202 bio->bi_private = r1_bio;
1203 r1_bio->bios[i] = bio;
1204 generic_make_request(bio);
1205 }
1156 } else { 1206 } else {
1157 int disk; 1207 int disk;
1158 bio = r1_bio->bios[r1_bio->read_disk]; 1208 bio = r1_bio->bios[r1_bio->read_disk];
@@ -1260,7 +1310,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1260 * This call the bitmap_start_sync doesn't actually record anything 1310 * This call the bitmap_start_sync doesn't actually record anything
1261 */ 1311 */
1262 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1312 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1263 !conf->fullsync) { 1313 !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1264 /* We can skip this block, and probably several more */ 1314 /* We can skip this block, and probably several more */
1265 *skipped = 1; 1315 *skipped = 1;
1266 return sync_blocks; 1316 return sync_blocks;
@@ -1282,11 +1332,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1282 /* make sure disk is operational */ 1332 /* make sure disk is operational */
1283 wonly = disk; 1333 wonly = disk;
1284 while (conf->mirrors[disk].rdev == NULL || 1334 while (conf->mirrors[disk].rdev == NULL ||
1285 !conf->mirrors[disk].rdev->in_sync || 1335 !test_bit(In_sync, &conf->mirrors[disk].rdev->flags) ||
1286 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags) 1336 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags)
1287 ) { 1337 ) {
1288 if (conf->mirrors[disk].rdev && 1338 if (conf->mirrors[disk].rdev &&
1289 conf->mirrors[disk].rdev->in_sync) 1339 test_bit(In_sync, &conf->mirrors[disk].rdev->flags))
1290 wonly = disk; 1340 wonly = disk;
1291 if (disk <= 0) 1341 if (disk <= 0)
1292 disk = conf->raid_disks; 1342 disk = conf->raid_disks;
@@ -1333,11 +1383,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1333 bio->bi_rw = READ; 1383 bio->bi_rw = READ;
1334 bio->bi_end_io = end_sync_read; 1384 bio->bi_end_io = end_sync_read;
1335 } else if (conf->mirrors[i].rdev == NULL || 1385 } else if (conf->mirrors[i].rdev == NULL ||
1336 conf->mirrors[i].rdev->faulty) { 1386 test_bit(Faulty, &conf->mirrors[i].rdev->flags)) {
1337 still_degraded = 1; 1387 still_degraded = 1;
1338 continue; 1388 continue;
1339 } else if (!conf->mirrors[i].rdev->in_sync || 1389 } else if (!test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
1340 sector_nr + RESYNC_SECTORS > mddev->recovery_cp) { 1390 sector_nr + RESYNC_SECTORS > mddev->recovery_cp ||
1391 test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1341 bio->bi_rw = WRITE; 1392 bio->bi_rw = WRITE;
1342 bio->bi_end_io = end_sync_write; 1393 bio->bi_end_io = end_sync_write;
1343 write_targets ++; 1394 write_targets ++;
@@ -1371,8 +1422,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1371 break; 1422 break;
1372 if (sync_blocks == 0) { 1423 if (sync_blocks == 0) {
1373 if (!bitmap_start_sync(mddev->bitmap, sector_nr, 1424 if (!bitmap_start_sync(mddev->bitmap, sector_nr,
1374 &sync_blocks, still_degraded) && 1425 &sync_blocks, still_degraded) &&
1375 !conf->fullsync) 1426 !conf->fullsync &&
1427 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1376 break; 1428 break;
1377 if (sync_blocks < (PAGE_SIZE>>9)) 1429 if (sync_blocks < (PAGE_SIZE>>9))
1378 BUG(); 1430 BUG();
@@ -1478,7 +1530,7 @@ static int run(mddev_t *mddev)
1478 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 1530 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
1479 1531
1480 disk->head_position = 0; 1532 disk->head_position = 0;
1481 if (!rdev->faulty && rdev->in_sync) 1533 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1482 conf->working_disks++; 1534 conf->working_disks++;
1483 } 1535 }
1484 conf->raid_disks = mddev->raid_disks; 1536 conf->raid_disks = mddev->raid_disks;
@@ -1518,7 +1570,7 @@ static int run(mddev_t *mddev)
1518 */ 1570 */
1519 for (j = 0; j < conf->raid_disks && 1571 for (j = 0; j < conf->raid_disks &&
1520 (!conf->mirrors[j].rdev || 1572 (!conf->mirrors[j].rdev ||
1521 !conf->mirrors[j].rdev->in_sync) ; j++) 1573 !test_bit(In_sync, &conf->mirrors[j].rdev->flags)) ; j++)
1522 /* nothing */; 1574 /* nothing */;
1523 conf->last_used = j; 1575 conf->last_used = j;
1524 1576
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index bbe40e9cf923..867f06ae33d9 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -496,6 +496,7 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
496 int disk, slot, nslot; 496 int disk, slot, nslot;
497 const int sectors = r10_bio->sectors; 497 const int sectors = r10_bio->sectors;
498 sector_t new_distance, current_distance; 498 sector_t new_distance, current_distance;
499 mdk_rdev_t *rdev;
499 500
500 raid10_find_phys(conf, r10_bio); 501 raid10_find_phys(conf, r10_bio);
501 rcu_read_lock(); 502 rcu_read_lock();
@@ -510,8 +511,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
510 slot = 0; 511 slot = 0;
511 disk = r10_bio->devs[slot].devnum; 512 disk = r10_bio->devs[slot].devnum;
512 513
513 while (!conf->mirrors[disk].rdev || 514 while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
514 !conf->mirrors[disk].rdev->in_sync) { 515 !test_bit(In_sync, &rdev->flags)) {
515 slot++; 516 slot++;
516 if (slot == conf->copies) { 517 if (slot == conf->copies) {
517 slot = 0; 518 slot = 0;
@@ -527,8 +528,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
527 /* make sure the disk is operational */ 528 /* make sure the disk is operational */
528 slot = 0; 529 slot = 0;
529 disk = r10_bio->devs[slot].devnum; 530 disk = r10_bio->devs[slot].devnum;
530 while (!conf->mirrors[disk].rdev || 531 while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
531 !conf->mirrors[disk].rdev->in_sync) { 532 !test_bit(In_sync, &rdev->flags)) {
532 slot ++; 533 slot ++;
533 if (slot == conf->copies) { 534 if (slot == conf->copies) {
534 disk = -1; 535 disk = -1;
@@ -547,11 +548,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
547 int ndisk = r10_bio->devs[nslot].devnum; 548 int ndisk = r10_bio->devs[nslot].devnum;
548 549
549 550
550 if (!conf->mirrors[ndisk].rdev || 551 if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL ||
551 !conf->mirrors[ndisk].rdev->in_sync) 552 !test_bit(In_sync, &rdev->flags))
552 continue; 553 continue;
553 554
554 if (!atomic_read(&conf->mirrors[ndisk].rdev->nr_pending)) { 555 if (!atomic_read(&rdev->nr_pending)) {
555 disk = ndisk; 556 disk = ndisk;
556 slot = nslot; 557 slot = nslot;
557 break; 558 break;
@@ -569,7 +570,7 @@ rb_out:
569 r10_bio->read_slot = slot; 570 r10_bio->read_slot = slot;
570/* conf->next_seq_sect = this_sector + sectors;*/ 571/* conf->next_seq_sect = this_sector + sectors;*/
571 572
572 if (disk >= 0 && conf->mirrors[disk].rdev) 573 if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL)
573 atomic_inc(&conf->mirrors[disk].rdev->nr_pending); 574 atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
574 rcu_read_unlock(); 575 rcu_read_unlock();
575 576
@@ -583,8 +584,8 @@ static void unplug_slaves(mddev_t *mddev)
583 584
584 rcu_read_lock(); 585 rcu_read_lock();
585 for (i=0; i<mddev->raid_disks; i++) { 586 for (i=0; i<mddev->raid_disks; i++) {
586 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 587 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
587 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 588 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
588 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 589 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
589 590
590 atomic_inc(&rdev->nr_pending); 591 atomic_inc(&rdev->nr_pending);
@@ -614,8 +615,8 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
614 615
615 rcu_read_lock(); 616 rcu_read_lock();
616 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 617 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
617 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 618 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
618 if (rdev && !rdev->faulty) { 619 if (rdev && !test_bit(Faulty, &rdev->flags)) {
619 struct block_device *bdev = rdev->bdev; 620 struct block_device *bdev = rdev->bdev;
620 request_queue_t *r_queue = bdev_get_queue(bdev); 621 request_queue_t *r_queue = bdev_get_queue(bdev);
621 622
@@ -768,9 +769,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
768 rcu_read_lock(); 769 rcu_read_lock();
769 for (i = 0; i < conf->copies; i++) { 770 for (i = 0; i < conf->copies; i++) {
770 int d = r10_bio->devs[i].devnum; 771 int d = r10_bio->devs[i].devnum;
771 if (conf->mirrors[d].rdev && 772 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[d].rdev);
772 !conf->mirrors[d].rdev->faulty) { 773 if (rdev &&
773 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 774 !test_bit(Faulty, &rdev->flags)) {
775 atomic_inc(&rdev->nr_pending);
774 r10_bio->devs[i].bio = bio; 776 r10_bio->devs[i].bio = bio;
775 } else 777 } else
776 r10_bio->devs[i].bio = NULL; 778 r10_bio->devs[i].bio = NULL;
@@ -824,7 +826,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 826 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 827 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 828 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 829 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 830 seq_printf(seq, "]");
829} 831}
830 832
@@ -839,7 +841,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
839 * next level up know. 841 * next level up know.
840 * else mark the drive as failed 842 * else mark the drive as failed
841 */ 843 */
842 if (rdev->in_sync 844 if (test_bit(In_sync, &rdev->flags)
843 && conf->working_disks == 1) 845 && conf->working_disks == 1)
844 /* 846 /*
845 * Don't fail the drive, just return an IO error. 847 * Don't fail the drive, just return an IO error.
@@ -849,7 +851,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
849 * really dead" tests... 851 * really dead" tests...
850 */ 852 */
851 return; 853 return;
852 if (rdev->in_sync) { 854 if (test_bit(In_sync, &rdev->flags)) {
853 mddev->degraded++; 855 mddev->degraded++;
854 conf->working_disks--; 856 conf->working_disks--;
855 /* 857 /*
@@ -857,8 +859,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
857 */ 859 */
858 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 860 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
859 } 861 }
860 rdev->in_sync = 0; 862 clear_bit(In_sync, &rdev->flags);
861 rdev->faulty = 1; 863 set_bit(Faulty, &rdev->flags);
862 mddev->sb_dirty = 1; 864 mddev->sb_dirty = 1;
863 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" 865 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
864 " Operation continuing on %d devices\n", 866 " Operation continuing on %d devices\n",
@@ -883,7 +885,8 @@ static void print_conf(conf_t *conf)
883 tmp = conf->mirrors + i; 885 tmp = conf->mirrors + i;
884 if (tmp->rdev) 886 if (tmp->rdev)
885 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 887 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
886 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 888 i, !test_bit(In_sync, &tmp->rdev->flags),
889 !test_bit(Faulty, &tmp->rdev->flags),
887 bdevname(tmp->rdev->bdev,b)); 890 bdevname(tmp->rdev->bdev,b));
888 } 891 }
889} 892}
@@ -936,11 +939,11 @@ static int raid10_spare_active(mddev_t *mddev)
936 for (i = 0; i < conf->raid_disks; i++) { 939 for (i = 0; i < conf->raid_disks; i++) {
937 tmp = conf->mirrors + i; 940 tmp = conf->mirrors + i;
938 if (tmp->rdev 941 if (tmp->rdev
939 && !tmp->rdev->faulty 942 && !test_bit(Faulty, &tmp->rdev->flags)
940 && !tmp->rdev->in_sync) { 943 && !test_bit(In_sync, &tmp->rdev->flags)) {
941 conf->working_disks++; 944 conf->working_disks++;
942 mddev->degraded--; 945 mddev->degraded--;
943 tmp->rdev->in_sync = 1; 946 set_bit(In_sync, &tmp->rdev->flags);
944 } 947 }
945 } 948 }
946 949
@@ -980,7 +983,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
980 p->head_position = 0; 983 p->head_position = 0;
981 rdev->raid_disk = mirror; 984 rdev->raid_disk = mirror;
982 found = 1; 985 found = 1;
983 p->rdev = rdev; 986 rcu_assign_pointer(p->rdev, rdev);
984 break; 987 break;
985 } 988 }
986 989
@@ -998,7 +1001,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
998 print_conf(conf); 1001 print_conf(conf);
999 rdev = p->rdev; 1002 rdev = p->rdev;
1000 if (rdev) { 1003 if (rdev) {
1001 if (rdev->in_sync || 1004 if (test_bit(In_sync, &rdev->flags) ||
1002 atomic_read(&rdev->nr_pending)) { 1005 atomic_read(&rdev->nr_pending)) {
1003 err = -EBUSY; 1006 err = -EBUSY;
1004 goto abort; 1007 goto abort;
@@ -1414,7 +1417,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1414 1417
1415 for (i=0 ; i<conf->raid_disks; i++) 1418 for (i=0 ; i<conf->raid_disks; i++)
1416 if (conf->mirrors[i].rdev && 1419 if (conf->mirrors[i].rdev &&
1417 !conf->mirrors[i].rdev->in_sync) { 1420 !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) {
1418 /* want to reconstruct this device */ 1421 /* want to reconstruct this device */
1419 r10bio_t *rb2 = r10_bio; 1422 r10bio_t *rb2 = r10_bio;
1420 1423
@@ -1435,7 +1438,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1435 for (j=0; j<conf->copies;j++) { 1438 for (j=0; j<conf->copies;j++) {
1436 int d = r10_bio->devs[j].devnum; 1439 int d = r10_bio->devs[j].devnum;
1437 if (conf->mirrors[d].rdev && 1440 if (conf->mirrors[d].rdev &&
1438 conf->mirrors[d].rdev->in_sync) { 1441 test_bit(In_sync, &conf->mirrors[d].rdev->flags)) {
1439 /* This is where we read from */ 1442 /* This is where we read from */
1440 bio = r10_bio->devs[0].bio; 1443 bio = r10_bio->devs[0].bio;
1441 bio->bi_next = biolist; 1444 bio->bi_next = biolist;
@@ -1511,7 +1514,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1511 bio = r10_bio->devs[i].bio; 1514 bio = r10_bio->devs[i].bio;
1512 bio->bi_end_io = NULL; 1515 bio->bi_end_io = NULL;
1513 if (conf->mirrors[d].rdev == NULL || 1516 if (conf->mirrors[d].rdev == NULL ||
1514 conf->mirrors[d].rdev->faulty) 1517 test_bit(Faulty, &conf->mirrors[d].rdev->flags))
1515 continue; 1518 continue;
1516 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 1519 atomic_inc(&conf->mirrors[d].rdev->nr_pending);
1517 atomic_inc(&r10_bio->remaining); 1520 atomic_inc(&r10_bio->remaining);
@@ -1697,7 +1700,7 @@ static int run(mddev_t *mddev)
1697 mddev->queue->max_sectors = (PAGE_SIZE>>9); 1700 mddev->queue->max_sectors = (PAGE_SIZE>>9);
1698 1701
1699 disk->head_position = 0; 1702 disk->head_position = 0;
1700 if (!rdev->faulty && rdev->in_sync) 1703 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1701 conf->working_disks++; 1704 conf->working_disks++;
1702 } 1705 }
1703 conf->raid_disks = mddev->raid_disks; 1706 conf->raid_disks = mddev->raid_disks;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 1223e98ecd70..e2a40283e323 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -293,9 +293,31 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
293 return sh; 293 return sh;
294} 294}
295 295
296static int grow_stripes(raid5_conf_t *conf, int num) 296static int grow_one_stripe(raid5_conf_t *conf)
297{ 297{
298 struct stripe_head *sh; 298 struct stripe_head *sh;
299 sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
300 if (!sh)
301 return 0;
302 memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
303 sh->raid_conf = conf;
304 spin_lock_init(&sh->lock);
305
306 if (grow_buffers(sh, conf->raid_disks)) {
307 shrink_buffers(sh, conf->raid_disks);
308 kmem_cache_free(conf->slab_cache, sh);
309 return 0;
310 }
311 /* we just created an active stripe so... */
312 atomic_set(&sh->count, 1);
313 atomic_inc(&conf->active_stripes);
314 INIT_LIST_HEAD(&sh->lru);
315 release_stripe(sh);
316 return 1;
317}
318
319static int grow_stripes(raid5_conf_t *conf, int num)
320{
299 kmem_cache_t *sc; 321 kmem_cache_t *sc;
300 int devs = conf->raid_disks; 322 int devs = conf->raid_disks;
301 323
@@ -308,48 +330,39 @@ static int grow_stripes(raid5_conf_t *conf, int num)
308 return 1; 330 return 1;
309 conf->slab_cache = sc; 331 conf->slab_cache = sc;
310 while (num--) { 332 while (num--) {
311 sh = kmem_cache_alloc(sc, GFP_KERNEL); 333 if (!grow_one_stripe(conf))
312 if (!sh)
313 return 1;
314 memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
315 sh->raid_conf = conf;
316 spin_lock_init(&sh->lock);
317
318 if (grow_buffers(sh, conf->raid_disks)) {
319 shrink_buffers(sh, conf->raid_disks);
320 kmem_cache_free(sc, sh);
321 return 1; 334 return 1;
322 }
323 /* we just created an active stripe so... */
324 atomic_set(&sh->count, 1);
325 atomic_inc(&conf->active_stripes);
326 INIT_LIST_HEAD(&sh->lru);
327 release_stripe(sh);
328 } 335 }
329 return 0; 336 return 0;
330} 337}
331 338
332static void shrink_stripes(raid5_conf_t *conf) 339static int drop_one_stripe(raid5_conf_t *conf)
333{ 340{
334 struct stripe_head *sh; 341 struct stripe_head *sh;
335 342
336 while (1) { 343 spin_lock_irq(&conf->device_lock);
337 spin_lock_irq(&conf->device_lock); 344 sh = get_free_stripe(conf);
338 sh = get_free_stripe(conf); 345 spin_unlock_irq(&conf->device_lock);
339 spin_unlock_irq(&conf->device_lock); 346 if (!sh)
340 if (!sh) 347 return 0;
341 break; 348 if (atomic_read(&sh->count))
342 if (atomic_read(&sh->count)) 349 BUG();
343 BUG(); 350 shrink_buffers(sh, conf->raid_disks);
344 shrink_buffers(sh, conf->raid_disks); 351 kmem_cache_free(conf->slab_cache, sh);
345 kmem_cache_free(conf->slab_cache, sh); 352 atomic_dec(&conf->active_stripes);
346 atomic_dec(&conf->active_stripes); 353 return 1;
347 } 354}
355
356static void shrink_stripes(raid5_conf_t *conf)
357{
358 while (drop_one_stripe(conf))
359 ;
360
348 kmem_cache_destroy(conf->slab_cache); 361 kmem_cache_destroy(conf->slab_cache);
349 conf->slab_cache = NULL; 362 conf->slab_cache = NULL;
350} 363}
351 364
352static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done, 365static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done,
353 int error) 366 int error)
354{ 367{
355 struct stripe_head *sh = bi->bi_private; 368 struct stripe_head *sh = bi->bi_private;
@@ -401,10 +414,35 @@ static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done,
401 } 414 }
402#else 415#else
403 set_bit(R5_UPTODATE, &sh->dev[i].flags); 416 set_bit(R5_UPTODATE, &sh->dev[i].flags);
404#endif 417#endif
418 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
419 printk("R5: read error corrected!!\n");
420 clear_bit(R5_ReadError, &sh->dev[i].flags);
421 clear_bit(R5_ReWrite, &sh->dev[i].flags);
422 }
423 if (atomic_read(&conf->disks[i].rdev->read_errors))
424 atomic_set(&conf->disks[i].rdev->read_errors, 0);
405 } else { 425 } else {
406 md_error(conf->mddev, conf->disks[i].rdev); 426 int retry = 0;
407 clear_bit(R5_UPTODATE, &sh->dev[i].flags); 427 clear_bit(R5_UPTODATE, &sh->dev[i].flags);
428 atomic_inc(&conf->disks[i].rdev->read_errors);
429 if (conf->mddev->degraded)
430 printk("R5: read error not correctable.\n");
431 else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
432 /* Oh, no!!! */
433 printk("R5: read error NOT corrected!!\n");
434 else if (atomic_read(&conf->disks[i].rdev->read_errors)
435 > conf->max_nr_stripes)
436 printk("raid5: Too many read errors, failing device.\n");
437 else
438 retry = 1;
439 if (retry)
440 set_bit(R5_ReadError, &sh->dev[i].flags);
441 else {
442 clear_bit(R5_ReadError, &sh->dev[i].flags);
443 clear_bit(R5_ReWrite, &sh->dev[i].flags);
444 md_error(conf->mddev, conf->disks[i].rdev);
445 }
408 } 446 }
409 rdev_dec_pending(conf->disks[i].rdev, conf->mddev); 447 rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
410#if 0 448#if 0
@@ -487,19 +525,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
487 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 525 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
488 PRINTK("raid5: error called\n"); 526 PRINTK("raid5: error called\n");
489 527
490 if (!rdev->faulty) { 528 if (!test_bit(Faulty, &rdev->flags)) {
491 mddev->sb_dirty = 1; 529 mddev->sb_dirty = 1;
492 if (rdev->in_sync) { 530 if (test_bit(In_sync, &rdev->flags)) {
493 conf->working_disks--; 531 conf->working_disks--;
494 mddev->degraded++; 532 mddev->degraded++;
495 conf->failed_disks++; 533 conf->failed_disks++;
496 rdev->in_sync = 0; 534 clear_bit(In_sync, &rdev->flags);
497 /* 535 /*
498 * if recovery was running, make sure it aborts. 536 * if recovery was running, make sure it aborts.
499 */ 537 */
500 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 538 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
501 } 539 }
502 rdev->faulty = 1; 540 set_bit(Faulty, &rdev->flags);
503 printk (KERN_ALERT 541 printk (KERN_ALERT
504 "raid5: Disk failure on %s, disabling device." 542 "raid5: Disk failure on %s, disabling device."
505 " Operation continuing on %d devices\n", 543 " Operation continuing on %d devices\n",
@@ -965,7 +1003,13 @@ static void handle_stripe(struct stripe_head *sh)
965 } 1003 }
966 if (dev->written) written++; 1004 if (dev->written) written++;
967 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1005 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
968 if (!rdev || !rdev->in_sync) { 1006 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1007 /* The ReadError flag wil just be confusing now */
1008 clear_bit(R5_ReadError, &dev->flags);
1009 clear_bit(R5_ReWrite, &dev->flags);
1010 }
1011 if (!rdev || !test_bit(In_sync, &rdev->flags)
1012 || test_bit(R5_ReadError, &dev->flags)) {
969 failed++; 1013 failed++;
970 failed_num = i; 1014 failed_num = i;
971 } else 1015 } else
@@ -980,6 +1024,14 @@ static void handle_stripe(struct stripe_head *sh)
980 if (failed > 1 && to_read+to_write+written) { 1024 if (failed > 1 && to_read+to_write+written) {
981 for (i=disks; i--; ) { 1025 for (i=disks; i--; ) {
982 int bitmap_end = 0; 1026 int bitmap_end = 0;
1027
1028 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
1029 mdk_rdev_t *rdev = conf->disks[i].rdev;
1030 if (rdev && test_bit(In_sync, &rdev->flags))
1031 /* multiple read failures in one stripe */
1032 md_error(conf->mddev, rdev);
1033 }
1034
983 spin_lock_irq(&conf->device_lock); 1035 spin_lock_irq(&conf->device_lock);
984 /* fail all writes first */ 1036 /* fail all writes first */
985 bi = sh->dev[i].towrite; 1037 bi = sh->dev[i].towrite;
@@ -1015,7 +1067,8 @@ static void handle_stripe(struct stripe_head *sh)
1015 } 1067 }
1016 1068
1017 /* fail any reads if this device is non-operational */ 1069 /* fail any reads if this device is non-operational */
1018 if (!test_bit(R5_Insync, &sh->dev[i].flags)) { 1070 if (!test_bit(R5_Insync, &sh->dev[i].flags) ||
1071 test_bit(R5_ReadError, &sh->dev[i].flags)) {
1019 bi = sh->dev[i].toread; 1072 bi = sh->dev[i].toread;
1020 sh->dev[i].toread = NULL; 1073 sh->dev[i].toread = NULL;
1021 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) 1074 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
@@ -1247,6 +1300,11 @@ static void handle_stripe(struct stripe_head *sh)
1247 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { 1300 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) {
1248 /* parity is correct (on disc, not in buffer any more) */ 1301 /* parity is correct (on disc, not in buffer any more) */
1249 set_bit(STRIPE_INSYNC, &sh->state); 1302 set_bit(STRIPE_INSYNC, &sh->state);
1303 } else {
1304 conf->mddev->resync_mismatches += STRIPE_SECTORS;
1305 if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
1306 /* don't try to repair!! */
1307 set_bit(STRIPE_INSYNC, &sh->state);
1250 } 1308 }
1251 } 1309 }
1252 if (!test_bit(STRIPE_INSYNC, &sh->state)) { 1310 if (!test_bit(STRIPE_INSYNC, &sh->state)) {
@@ -1274,7 +1332,27 @@ static void handle_stripe(struct stripe_head *sh)
1274 md_done_sync(conf->mddev, STRIPE_SECTORS,1); 1332 md_done_sync(conf->mddev, STRIPE_SECTORS,1);
1275 clear_bit(STRIPE_SYNCING, &sh->state); 1333 clear_bit(STRIPE_SYNCING, &sh->state);
1276 } 1334 }
1277 1335
1336 /* If the failed drive is just a ReadError, then we might need to progress
1337 * the repair/check process
1338 */
1339 if (failed == 1 && ! conf->mddev->ro &&
1340 test_bit(R5_ReadError, &sh->dev[failed_num].flags)
1341 && !test_bit(R5_LOCKED, &sh->dev[failed_num].flags)
1342 && test_bit(R5_UPTODATE, &sh->dev[failed_num].flags)
1343 ) {
1344 dev = &sh->dev[failed_num];
1345 if (!test_bit(R5_ReWrite, &dev->flags)) {
1346 set_bit(R5_Wantwrite, &dev->flags);
1347 set_bit(R5_ReWrite, &dev->flags);
1348 set_bit(R5_LOCKED, &dev->flags);
1349 } else {
1350 /* let's read it back */
1351 set_bit(R5_Wantread, &dev->flags);
1352 set_bit(R5_LOCKED, &dev->flags);
1353 }
1354 }
1355
1278 spin_unlock(&sh->lock); 1356 spin_unlock(&sh->lock);
1279 1357
1280 while ((bi=return_bi)) { 1358 while ((bi=return_bi)) {
@@ -1305,8 +1383,8 @@ static void handle_stripe(struct stripe_head *sh)
1305 bi->bi_end_io = raid5_end_read_request; 1383 bi->bi_end_io = raid5_end_read_request;
1306 1384
1307 rcu_read_lock(); 1385 rcu_read_lock();
1308 rdev = conf->disks[i].rdev; 1386 rdev = rcu_dereference(conf->disks[i].rdev);
1309 if (rdev && rdev->faulty) 1387 if (rdev && test_bit(Faulty, &rdev->flags))
1310 rdev = NULL; 1388 rdev = NULL;
1311 if (rdev) 1389 if (rdev)
1312 atomic_inc(&rdev->nr_pending); 1390 atomic_inc(&rdev->nr_pending);
@@ -1379,8 +1457,8 @@ static void unplug_slaves(mddev_t *mddev)
1379 1457
1380 rcu_read_lock(); 1458 rcu_read_lock();
1381 for (i=0; i<mddev->raid_disks; i++) { 1459 for (i=0; i<mddev->raid_disks; i++) {
1382 mdk_rdev_t *rdev = conf->disks[i].rdev; 1460 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1383 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1461 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1384 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1462 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1385 1463
1386 atomic_inc(&rdev->nr_pending); 1464 atomic_inc(&rdev->nr_pending);
@@ -1424,8 +1502,8 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk,
1424 1502
1425 rcu_read_lock(); 1503 rcu_read_lock();
1426 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1504 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1427 mdk_rdev_t *rdev = conf->disks[i].rdev; 1505 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1428 if (rdev && !rdev->faulty) { 1506 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1429 struct block_device *bdev = rdev->bdev; 1507 struct block_device *bdev = rdev->bdev;
1430 request_queue_t *r_queue = bdev_get_queue(bdev); 1508 request_queue_t *r_queue = bdev_get_queue(bdev);
1431 1509
@@ -1567,6 +1645,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1567 return rv; 1645 return rv;
1568 } 1646 }
1569 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1647 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1648 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
1570 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) { 1649 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
1571 /* we can skip this block, and probably more */ 1650 /* we can skip this block, and probably more */
1572 sync_blocks /= STRIPE_SECTORS; 1651 sync_blocks /= STRIPE_SECTORS;
@@ -1663,6 +1742,74 @@ static void raid5d (mddev_t *mddev)
1663 PRINTK("--- raid5d inactive\n"); 1742 PRINTK("--- raid5d inactive\n");
1664} 1743}
1665 1744
1745static ssize_t
1746raid5_show_stripe_cache_size(mddev_t *mddev, char *page)
1747{
1748 raid5_conf_t *conf = mddev_to_conf(mddev);
1749 if (conf)
1750 return sprintf(page, "%d\n", conf->max_nr_stripes);
1751 else
1752 return 0;
1753}
1754
1755static ssize_t
1756raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
1757{
1758 raid5_conf_t *conf = mddev_to_conf(mddev);
1759 char *end;
1760 int new;
1761 if (len >= PAGE_SIZE)
1762 return -EINVAL;
1763 if (!conf)
1764 return -ENODEV;
1765
1766 new = simple_strtoul(page, &end, 10);
1767 if (!*page || (*end && *end != '\n') )
1768 return -EINVAL;
1769 if (new <= 16 || new > 32768)
1770 return -EINVAL;
1771 while (new < conf->max_nr_stripes) {
1772 if (drop_one_stripe(conf))
1773 conf->max_nr_stripes--;
1774 else
1775 break;
1776 }
1777 while (new > conf->max_nr_stripes) {
1778 if (grow_one_stripe(conf))
1779 conf->max_nr_stripes++;
1780 else break;
1781 }
1782 return len;
1783}
1784
1785static struct md_sysfs_entry
1786raid5_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR,
1787 raid5_show_stripe_cache_size,
1788 raid5_store_stripe_cache_size);
1789
1790static ssize_t
1791stripe_cache_active_show(mddev_t *mddev, char *page)
1792{
1793 raid5_conf_t *conf = mddev_to_conf(mddev);
1794 if (conf)
1795 return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
1796 else
1797 return 0;
1798}
1799
1800static struct md_sysfs_entry
1801raid5_stripecache_active = __ATTR_RO(stripe_cache_active);
1802
1803static struct attribute *raid5_attrs[] = {
1804 &raid5_stripecache_size.attr,
1805 &raid5_stripecache_active.attr,
1806 NULL,
1807};
1808static struct attribute_group raid5_attrs_group = {
1809 .name = NULL,
1810 .attrs = raid5_attrs,
1811};
1812
1666static int run(mddev_t *mddev) 1813static int run(mddev_t *mddev)
1667{ 1814{
1668 raid5_conf_t *conf; 1815 raid5_conf_t *conf;
@@ -1709,7 +1856,7 @@ static int run(mddev_t *mddev)
1709 1856
1710 disk->rdev = rdev; 1857 disk->rdev = rdev;
1711 1858
1712 if (rdev->in_sync) { 1859 if (test_bit(In_sync, &rdev->flags)) {
1713 char b[BDEVNAME_SIZE]; 1860 char b[BDEVNAME_SIZE];
1714 printk(KERN_INFO "raid5: device %s operational as raid" 1861 printk(KERN_INFO "raid5: device %s operational as raid"
1715 " disk %d\n", bdevname(rdev->bdev,b), 1862 " disk %d\n", bdevname(rdev->bdev,b),
@@ -1804,6 +1951,7 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
1804 } 1951 }
1805 1952
1806 /* Ok, everything is just fine now */ 1953 /* Ok, everything is just fine now */
1954 sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
1807 1955
1808 if (mddev->bitmap) 1956 if (mddev->bitmap)
1809 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; 1957 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
@@ -1828,7 +1976,7 @@ abort:
1828 1976
1829 1977
1830 1978
1831static int stop (mddev_t *mddev) 1979static int stop(mddev_t *mddev)
1832{ 1980{
1833 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 1981 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
1834 1982
@@ -1837,6 +1985,7 @@ static int stop (mddev_t *mddev)
1837 shrink_stripes(conf); 1985 shrink_stripes(conf);
1838 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); 1986 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
1839 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 1987 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
1988 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
1840 kfree(conf); 1989 kfree(conf);
1841 mddev->private = NULL; 1990 mddev->private = NULL;
1842 return 0; 1991 return 0;
@@ -1887,7 +2036,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
1887 for (i = 0; i < conf->raid_disks; i++) 2036 for (i = 0; i < conf->raid_disks; i++)
1888 seq_printf (seq, "%s", 2037 seq_printf (seq, "%s",
1889 conf->disks[i].rdev && 2038 conf->disks[i].rdev &&
1890 conf->disks[i].rdev->in_sync ? "U" : "_"); 2039 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
1891 seq_printf (seq, "]"); 2040 seq_printf (seq, "]");
1892#if RAID5_DEBUG 2041#if RAID5_DEBUG
1893#define D(x) \ 2042#define D(x) \
@@ -1914,7 +2063,7 @@ static void print_raid5_conf (raid5_conf_t *conf)
1914 tmp = conf->disks + i; 2063 tmp = conf->disks + i;
1915 if (tmp->rdev) 2064 if (tmp->rdev)
1916 printk(" disk %d, o:%d, dev:%s\n", 2065 printk(" disk %d, o:%d, dev:%s\n",
1917 i, !tmp->rdev->faulty, 2066 i, !test_bit(Faulty, &tmp->rdev->flags),
1918 bdevname(tmp->rdev->bdev,b)); 2067 bdevname(tmp->rdev->bdev,b));
1919 } 2068 }
1920} 2069}
@@ -1928,12 +2077,12 @@ static int raid5_spare_active(mddev_t *mddev)
1928 for (i = 0; i < conf->raid_disks; i++) { 2077 for (i = 0; i < conf->raid_disks; i++) {
1929 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
1930 if (tmp->rdev 2079 if (tmp->rdev
1931 && !tmp->rdev->faulty 2080 && !test_bit(Faulty, &tmp->rdev->flags)
1932 && !tmp->rdev->in_sync) { 2081 && !test_bit(In_sync, &tmp->rdev->flags)) {
1933 mddev->degraded--; 2082 mddev->degraded--;
1934 conf->failed_disks--; 2083 conf->failed_disks--;
1935 conf->working_disks++; 2084 conf->working_disks++;
1936 tmp->rdev->in_sync = 1; 2085 set_bit(In_sync, &tmp->rdev->flags);
1937 } 2086 }
1938 } 2087 }
1939 print_raid5_conf(conf); 2088 print_raid5_conf(conf);
@@ -1950,7 +2099,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
1950 print_raid5_conf(conf); 2099 print_raid5_conf(conf);
1951 rdev = p->rdev; 2100 rdev = p->rdev;
1952 if (rdev) { 2101 if (rdev) {
1953 if (rdev->in_sync || 2102 if (test_bit(In_sync, &rdev->flags) ||
1954 atomic_read(&rdev->nr_pending)) { 2103 atomic_read(&rdev->nr_pending)) {
1955 err = -EBUSY; 2104 err = -EBUSY;
1956 goto abort; 2105 goto abort;
@@ -1985,12 +2134,12 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
1985 */ 2134 */
1986 for (disk=0; disk < mddev->raid_disks; disk++) 2135 for (disk=0; disk < mddev->raid_disks; disk++)
1987 if ((p=conf->disks + disk)->rdev == NULL) { 2136 if ((p=conf->disks + disk)->rdev == NULL) {
1988 rdev->in_sync = 0; 2137 clear_bit(In_sync, &rdev->flags);
1989 rdev->raid_disk = disk; 2138 rdev->raid_disk = disk;
1990 found = 1; 2139 found = 1;
1991 if (rdev->saved_raid_disk != disk) 2140 if (rdev->saved_raid_disk != disk)
1992 conf->fullsync = 1; 2141 conf->fullsync = 1;
1993 p->rdev = rdev; 2142 rcu_assign_pointer(p->rdev, rdev);
1994 break; 2143 break;
1995 } 2144 }
1996 print_raid5_conf(conf); 2145 print_raid5_conf(conf);
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 775786947701..eae5a35629c5 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -507,19 +507,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private; 507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
508 PRINTK("raid6: error called\n"); 508 PRINTK("raid6: error called\n");
509 509
510 if (!rdev->faulty) { 510 if (!test_bit(Faulty, &rdev->flags)) {
511 mddev->sb_dirty = 1; 511 mddev->sb_dirty = 1;
512 if (rdev->in_sync) { 512 if (test_bit(In_sync, &rdev->flags)) {
513 conf->working_disks--; 513 conf->working_disks--;
514 mddev->degraded++; 514 mddev->degraded++;
515 conf->failed_disks++; 515 conf->failed_disks++;
516 rdev->in_sync = 0; 516 clear_bit(In_sync, &rdev->flags);
517 /* 517 /*
518 * if recovery was running, make sure it aborts. 518 * if recovery was running, make sure it aborts.
519 */ 519 */
520 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 520 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
521 } 521 }
522 rdev->faulty = 1; 522 set_bit(Faulty, &rdev->flags);
523 printk (KERN_ALERT 523 printk (KERN_ALERT
524 "raid6: Disk failure on %s, disabling device." 524 "raid6: Disk failure on %s, disabling device."
525 " Operation continuing on %d devices\n", 525 " Operation continuing on %d devices\n",
@@ -1071,7 +1071,7 @@ static void handle_stripe(struct stripe_head *sh)
1071 } 1071 }
1072 if (dev->written) written++; 1072 if (dev->written) written++;
1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
1074 if (!rdev || !rdev->in_sync) { 1074 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1075 if ( failed < 2 ) 1075 if ( failed < 2 )
1076 failed_num[failed] = i; 1076 failed_num[failed] = i;
1077 failed++; 1077 failed++;
@@ -1464,8 +1464,8 @@ static void handle_stripe(struct stripe_head *sh)
1464 bi->bi_end_io = raid6_end_read_request; 1464 bi->bi_end_io = raid6_end_read_request;
1465 1465
1466 rcu_read_lock(); 1466 rcu_read_lock();
1467 rdev = conf->disks[i].rdev; 1467 rdev = rcu_dereference(conf->disks[i].rdev);
1468 if (rdev && rdev->faulty) 1468 if (rdev && test_bit(Faulty, &rdev->flags))
1469 rdev = NULL; 1469 rdev = NULL;
1470 if (rdev) 1470 if (rdev)
1471 atomic_inc(&rdev->nr_pending); 1471 atomic_inc(&rdev->nr_pending);
@@ -1538,8 +1538,8 @@ static void unplug_slaves(mddev_t *mddev)
1538 1538
1539 rcu_read_lock(); 1539 rcu_read_lock();
1540 for (i=0; i<mddev->raid_disks; i++) { 1540 for (i=0; i<mddev->raid_disks; i++) {
1541 mdk_rdev_t *rdev = conf->disks[i].rdev; 1541 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1542 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1542 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1544 1544
1545 atomic_inc(&rdev->nr_pending); 1545 atomic_inc(&rdev->nr_pending);
@@ -1583,8 +1583,8 @@ static int raid6_issue_flush(request_queue_t *q, struct gendisk *disk,
1583 1583
1584 rcu_read_lock(); 1584 rcu_read_lock();
1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1586 mdk_rdev_t *rdev = conf->disks[i].rdev; 1586 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1587 if (rdev && !rdev->faulty) { 1587 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1588 struct block_device *bdev = rdev->bdev; 1588 struct block_device *bdev = rdev->bdev;
1589 request_queue_t *r_queue = bdev_get_queue(bdev); 1589 request_queue_t *r_queue = bdev_get_queue(bdev);
1590 1590
@@ -1868,7 +1868,7 @@ static int run(mddev_t *mddev)
1868 1868
1869 disk->rdev = rdev; 1869 disk->rdev = rdev;
1870 1870
1871 if (rdev->in_sync) { 1871 if (test_bit(In_sync, &rdev->flags)) {
1872 char b[BDEVNAME_SIZE]; 1872 char b[BDEVNAME_SIZE];
1873 printk(KERN_INFO "raid6: device %s operational as raid" 1873 printk(KERN_INFO "raid6: device %s operational as raid"
1874 " disk %d\n", bdevname(rdev->bdev,b), 1874 " disk %d\n", bdevname(rdev->bdev,b),
@@ -2052,7 +2052,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
2052 for (i = 0; i < conf->raid_disks; i++) 2052 for (i = 0; i < conf->raid_disks; i++)
2053 seq_printf (seq, "%s", 2053 seq_printf (seq, "%s",
2054 conf->disks[i].rdev && 2054 conf->disks[i].rdev &&
2055 conf->disks[i].rdev->in_sync ? "U" : "_"); 2055 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
2056 seq_printf (seq, "]"); 2056 seq_printf (seq, "]");
2057#if RAID6_DUMPSTATE 2057#if RAID6_DUMPSTATE
2058 seq_printf (seq, "\n"); 2058 seq_printf (seq, "\n");
@@ -2078,7 +2078,7 @@ static void print_raid6_conf (raid6_conf_t *conf)
2078 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
2079 if (tmp->rdev) 2079 if (tmp->rdev)
2080 printk(" disk %d, o:%d, dev:%s\n", 2080 printk(" disk %d, o:%d, dev:%s\n",
2081 i, !tmp->rdev->faulty, 2081 i, !test_bit(Faulty, &tmp->rdev->flags),
2082 bdevname(tmp->rdev->bdev,b)); 2082 bdevname(tmp->rdev->bdev,b));
2083 } 2083 }
2084} 2084}
@@ -2092,12 +2092,12 @@ static int raid6_spare_active(mddev_t *mddev)
2092 for (i = 0; i < conf->raid_disks; i++) { 2092 for (i = 0; i < conf->raid_disks; i++) {
2093 tmp = conf->disks + i; 2093 tmp = conf->disks + i;
2094 if (tmp->rdev 2094 if (tmp->rdev
2095 && !tmp->rdev->faulty 2095 && !test_bit(Faulty, &tmp->rdev->flags)
2096 && !tmp->rdev->in_sync) { 2096 && !test_bit(In_sync, &tmp->rdev->flags)) {
2097 mddev->degraded--; 2097 mddev->degraded--;
2098 conf->failed_disks--; 2098 conf->failed_disks--;
2099 conf->working_disks++; 2099 conf->working_disks++;
2100 tmp->rdev->in_sync = 1; 2100 set_bit(In_sync, &tmp->rdev->flags);
2101 } 2101 }
2102 } 2102 }
2103 print_raid6_conf(conf); 2103 print_raid6_conf(conf);
@@ -2114,7 +2114,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number)
2114 print_raid6_conf(conf); 2114 print_raid6_conf(conf);
2115 rdev = p->rdev; 2115 rdev = p->rdev;
2116 if (rdev) { 2116 if (rdev) {
2117 if (rdev->in_sync || 2117 if (test_bit(In_sync, &rdev->flags) ||
2118 atomic_read(&rdev->nr_pending)) { 2118 atomic_read(&rdev->nr_pending)) {
2119 err = -EBUSY; 2119 err = -EBUSY;
2120 goto abort; 2120 goto abort;
@@ -2149,12 +2149,12 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
2149 */ 2149 */
2150 for (disk=0; disk < mddev->raid_disks; disk++) 2150 for (disk=0; disk < mddev->raid_disks; disk++)
2151 if ((p=conf->disks + disk)->rdev == NULL) { 2151 if ((p=conf->disks + disk)->rdev == NULL) {
2152 rdev->in_sync = 0; 2152 clear_bit(In_sync, &rdev->flags);
2153 rdev->raid_disk = disk; 2153 rdev->raid_disk = disk;
2154 found = 1; 2154 found = 1;
2155 if (rdev->saved_raid_disk != disk) 2155 if (rdev->saved_raid_disk != disk)
2156 conf->fullsync = 1; 2156 conf->fullsync = 1;
2157 p->rdev = rdev; 2157 rcu_assign_pointer(p->rdev, rdev);
2158 break; 2158 break;
2159 } 2159 }
2160 print_raid6_conf(conf); 2160 print_raid6_conf(conf);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 31fccb4f05d6..4b71fd6f7aed 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -116,7 +116,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
116 [ 46 ] = KEY_BLUE, 116 [ 46 ] = KEY_BLUE,
117 [ 24 ] = KEY_KPPLUS, /* fine tune + */ 117 [ 24 ] = KEY_KPPLUS, /* fine tune + */
118 [ 25 ] = KEY_KPMINUS, /* fine tune - */ 118 [ 25 ] = KEY_KPMINUS, /* fine tune - */
119 [ 33 ] = KEY_KPDOT, 119 [ 33 ] = KEY_KPDOT,
120 [ 19 ] = KEY_KPENTER, 120 [ 19 ] = KEY_KPENTER,
121 [ 34 ] = KEY_BACK, 121 [ 34 ] = KEY_BACK,
122 [ 35 ] = KEY_PLAYPAUSE, 122 [ 35 ] = KEY_PLAYPAUSE,
@@ -239,7 +239,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
239 dprintk(1,"%s: key event code=%d down=%d\n", 239 dprintk(1,"%s: key event code=%d down=%d\n",
240 dev->name,ir->keycode,ir->keypressed); 240 dev->name,ir->keycode,ir->keypressed);
241 input_report_key(dev,ir->keycode,ir->keypressed); 241 input_report_key(dev,ir->keycode,ir->keypressed);
242 input_sync(dev); 242 input_sync(dev);
243} 243}
244 244
245/* -------------------------------------------------------------------------- */ 245/* -------------------------------------------------------------------------- */
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 47e28b0ee951..a35330315f65 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -13,6 +13,8 @@
13#include "bcm3510.h" 13#include "bcm3510.h"
14#include "stv0297.h" 14#include "stv0297.h"
15#include "mt312.h" 15#include "mt312.h"
16#include "lgdt330x.h"
17#include "dvb-pll.h"
16 18
17/* lnb control */ 19/* lnb control */
18 20
@@ -234,7 +236,6 @@ static struct stv0299_config samsung_tbmu24112_config = {
234 .inittab = samsung_tbmu24112_inittab, 236 .inittab = samsung_tbmu24112_inittab,
235 .mclk = 88000000UL, 237 .mclk = 88000000UL,
236 .invert = 0, 238 .invert = 0,
237 .enhanced_tuning = 0,
238 .skip_reinit = 0, 239 .skip_reinit = 0,
239 .lock_output = STV0229_LOCKOUTPUT_LK, 240 .lock_output = STV0229_LOCKOUTPUT_LK,
240 .volt13_op0_op1 = STV0299_VOLT13_OP1, 241 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -296,6 +297,52 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
296 return request_firmware(fw, name, fc->dev); 297 return request_firmware(fw, name, fc->dev);
297} 298}
298 299
300static int lgdt3303_pll_set(struct dvb_frontend* fe,
301 struct dvb_frontend_parameters* params)
302{
303 struct flexcop_device *fc = fe->dvb->priv;
304 u8 buf[4];
305 struct i2c_msg msg =
306 { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 };
307 int err;
308
309 dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0);
310 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
311 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
312 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
313 printk(KERN_WARNING "lgdt3303: %s error "
314 "(addr %02x <- %02x, err = %i)\n",
315 __FUNCTION__, buf[0], buf[1], err);
316 if (err < 0)
317 return err;
318 else
319 return -EREMOTEIO;
320 }
321
322 buf[0] = 0x86 | 0x18;
323 buf[1] = 0x50;
324 msg.len = 2;
325 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
326 printk(KERN_WARNING "lgdt3303: %s error "
327 "(addr %02x <- %02x, err = %i)\n",
328 __FUNCTION__, buf[0], buf[1], err);
329 if (err < 0)
330 return err;
331 else
332 return -EREMOTEIO;
333 }
334
335 return 0;
336}
337
338static struct lgdt330x_config air2pc_atsc_hd5000_config = {
339 .demod_address = 0x59,
340 .demod_chip = LGDT3303,
341 .serial_mpeg = 0x04,
342 .pll_set = lgdt3303_pll_set,
343 .clock_polarity_flip = 1,
344};
345
299static struct nxt2002_config samsung_tbmv_config = { 346static struct nxt2002_config samsung_tbmv_config = {
300 .demod_address = 0x0a, 347 .demod_address = 0x0a,
301 .request_firmware = flexcop_fe_request_firmware, 348 .request_firmware = flexcop_fe_request_firmware,
@@ -458,6 +505,11 @@ int flexcop_frontend_init(struct flexcop_device *fc)
458 fc->dev_type = FC_AIR_ATSC2; 505 fc->dev_type = FC_AIR_ATSC2;
459 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); 506 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
460 } else 507 } else
508 /* try the air atsc 3nd generation (lgdt3303) */
509 if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
510 fc->dev_type = FC_AIR_ATSC3;
511 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
512 } else
461 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ 513 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
462 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { 514 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
463 fc->dev_type = FC_AIR_ATSC1; 515 fc->dev_type = FC_AIR_ATSC1;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 3a08d38b318a..62282d8dbfa8 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -51,6 +51,7 @@ const char *flexcop_device_names[] = {
51 "Sky2PC/SkyStar 2 DVB-S", 51 "Sky2PC/SkyStar 2 DVB-S",
52 "Sky2PC/SkyStar 2 DVB-S (old version)", 52 "Sky2PC/SkyStar 2 DVB-S (old version)",
53 "Cable2PC/CableStar 2 DVB-C", 53 "Cable2PC/CableStar 2 DVB-C",
54 "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
54}; 55};
55 56
56const char *flexcop_bus_names[] = { 57const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 4ae1eb5bfe98..23cc6431e2b8 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -26,6 +26,7 @@ typedef enum {
26 FC_SKY, 26 FC_SKY,
27 FC_SKY_OLD, 27 FC_SKY_OLD,
28 FC_CABLE, 28 FC_CABLE,
29 FC_AIR_ATSC3,
29} flexcop_device_type_t; 30} flexcop_device_type_t;
30 31
31typedef enum { 32typedef enum {
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 12873d435406..123ed96f6faa 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -193,6 +193,7 @@ static void flexcop_reset(struct flexcop_device *fc)
193 v204 = fc->read_ibi_reg(fc,misc_204); 193 v204 = fc->read_ibi_reg(fc,misc_204);
194 v204.misc_204.Per_reset_sig = 0; 194 v204.misc_204.Per_reset_sig = 0;
195 fc->write_ibi_reg(fc,misc_204,v204); 195 fc->write_ibi_reg(fc,misc_204,v204);
196 msleep(1);
196 v204.misc_204.Per_reset_sig = 1; 197 v204.misc_204.Per_reset_sig = 1;
197 fc->write_ibi_reg(fc,misc_204,v204); 198 fc->write_ibi_reg(fc,misc_204,v204);
198} 199}
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 1e85d16491b0..2337b41714e0 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -6,10 +6,12 @@ config DVB_BT8XX
6 select DVB_NXT6000 6 select DVB_NXT6000
7 select DVB_CX24110 7 select DVB_CX24110
8 select DVB_OR51211 8 select DVB_OR51211
9 select DVB_LGDT330X
9 help 10 help
10 Support for PCI cards based on the Bt8xx PCI bridge. Examples are 11 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, 12 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
12 the pcHDTV HD2000 cards, and certain AVerMedia cards. 13 the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
14 some AVerMedia cards.
13 15
14 Since these cards have no MPEG decoder onboard, they transmit 16 Since these cards have no MPEG decoder onboard, they transmit
15 only compressed MPEG data over the PCI bus, so you need 17 only compressed MPEG data over the PCI bus, so you need
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index b3c9d7327ac1..8977c7a313df 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -690,8 +690,8 @@ struct dst_types dst_tlist[] = {
690 .device_id = "DTT-CI", 690 .device_id = "DTT-CI",
691 .offset = 1, 691 .offset = 1,
692 .dst_type = DST_TYPE_IS_TERR, 692 .dst_type = DST_TYPE_IS_TERR,
693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE,
694 .dst_feature = 0 694 .dst_feature = DST_TYPE_HAS_CA
695 }, 695 },
696 696
697 { 697 {
@@ -796,6 +796,56 @@ static int dst_get_vendor(struct dst_state *state)
796 return 0; 796 return 0;
797} 797}
798 798
799static int dst_get_tuner_info(struct dst_state *state)
800{
801 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
802 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
803
804 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
805 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
806 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
807 if (dst_command(state, get_tuner_2, 8) < 0) {
808 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
809 return -1;
810 }
811 } else {
812 if (dst_command(state, get_tuner_1, 8) < 0) {
813 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
814 return -1;
815 }
816 }
817 memset(&state->board_info, '\0', 8);
818 memcpy(&state->board_info, &state->rxbuffer, 8);
819 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
820 if (state->board_info[1] == 0x0b) {
821 if (state->type_flags & DST_TYPE_HAS_TS204)
822 state->type_flags &= ~DST_TYPE_HAS_TS204;
823 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
824 dprintk(verbose, DST_INFO, 1, "DST type has TS=188");
825 } else {
826 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
827 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
828 state->type_flags |= DST_TYPE_HAS_TS204;
829 dprintk(verbose, DST_INFO, 1, "DST type has TS=204");
830 }
831 } else {
832 if (state->board_info[0] == 0xbc) {
833 if (state->type_flags & DST_TYPE_HAS_TS204)
834 state->type_flags &= ~DST_TYPE_HAS_TS204;
835 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
836 dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]);
837
838 } else if (state->board_info[0] == 0xcc) {
839 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
840 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
841 state->type_flags |= DST_TYPE_HAS_TS204;
842 dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]);
843 }
844 }
845
846 return 0;
847}
848
799static int dst_get_device_id(struct dst_state *state) 849static int dst_get_device_id(struct dst_state *state)
800{ 850{
801 u8 reply; 851 u8 reply;
@@ -855,15 +905,12 @@ static int dst_get_device_id(struct dst_state *state)
855 state->dst_type = use_dst_type; 905 state->dst_type = use_dst_type;
856 dst_type_flags_print(state->type_flags); 906 dst_type_flags_print(state->type_flags);
857 907
858 if (state->type_flags & DST_TYPE_HAS_TS204) {
859 dst_packsize(state, 204);
860 }
861
862 return 0; 908 return 0;
863} 909}
864 910
865static int dst_probe(struct dst_state *state) 911static int dst_probe(struct dst_state *state)
866{ 912{
913 sema_init(&state->dst_mutex, 1);
867 if ((rdc_8820_reset(state)) < 0) { 914 if ((rdc_8820_reset(state)) < 0) {
868 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); 915 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
869 return -1; 916 return -1;
@@ -886,6 +933,13 @@ static int dst_probe(struct dst_state *state)
886 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); 933 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
887 return 0; 934 return 0;
888 } 935 }
936 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
937 if (dst_get_tuner_info(state) < 0)
938 dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
939 }
940 if (state->type_flags & DST_TYPE_HAS_TS204) {
941 dst_packsize(state, 204);
942 }
889 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { 943 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
890 if (dst_fw_ver(state) < 0) { 944 if (dst_fw_ver(state) < 0) {
891 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); 945 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
@@ -907,21 +961,23 @@ static int dst_probe(struct dst_state *state)
907int dst_command(struct dst_state *state, u8 *data, u8 len) 961int dst_command(struct dst_state *state, u8 *data, u8 len)
908{ 962{
909 u8 reply; 963 u8 reply;
964
965 down(&state->dst_mutex);
910 if ((dst_comm_init(state)) < 0) { 966 if ((dst_comm_init(state)) < 0) {
911 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); 967 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
912 return -1; 968 goto error;
913 } 969 }
914 if (write_dst(state, data, len)) { 970 if (write_dst(state, data, len)) {
915 dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); 971 dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
916 if ((dst_error_recovery(state)) < 0) { 972 if ((dst_error_recovery(state)) < 0) {
917 dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); 973 dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
918 return -1; 974 goto error;
919 } 975 }
920 return -1; 976 goto error;
921 } 977 }
922 if ((dst_pio_disable(state)) < 0) { 978 if ((dst_pio_disable(state)) < 0) {
923 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); 979 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
924 return -1; 980 goto error;
925 } 981 }
926 if (state->type_flags & DST_TYPE_HAS_FW_1) 982 if (state->type_flags & DST_TYPE_HAS_FW_1)
927 udelay(3000); 983 udelay(3000);
@@ -929,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
929 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 985 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
930 if ((dst_error_recovery(state)) < 0) { 986 if ((dst_error_recovery(state)) < 0) {
931 dprintk(verbose, DST_INFO, 1, "Recovery Failed."); 987 dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
932 return -1; 988 goto error;
933 } 989 }
934 return -1; 990 goto error;
935 } 991 }
936 if (reply != ACK) { 992 if (reply != ACK) {
937 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); 993 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
938 return -1; 994 goto error;
939 } 995 }
940 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 996 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
941 return 0; 997 goto error;
942 if (state->type_flags & DST_TYPE_HAS_FW_1) 998 if (state->type_flags & DST_TYPE_HAS_FW_1)
943 udelay(3000); 999 udelay(3000);
944 else 1000 else
945 udelay(2000); 1001 udelay(2000);
946 if (!dst_wait_dst_ready(state, NO_DELAY)) 1002 if (!dst_wait_dst_ready(state, NO_DELAY))
947 return -1; 1003 goto error;
948 if (read_dst(state, state->rxbuffer, FIXED_COMM)) { 1004 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
949 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 1005 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
950 if ((dst_error_recovery(state)) < 0) { 1006 if ((dst_error_recovery(state)) < 0) {
951 dprintk(verbose, DST_INFO, 1, "Recovery failed."); 1007 dprintk(verbose, DST_INFO, 1, "Recovery failed.");
952 return -1; 1008 goto error;
953 } 1009 }
954 return -1; 1010 goto error;
955 } 1011 }
956 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 1012 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
957 dprintk(verbose, DST_INFO, 1, "checksum failure"); 1013 dprintk(verbose, DST_INFO, 1, "checksum failure");
958 return -1; 1014 goto error;
959 } 1015 }
960 1016 up(&state->dst_mutex);
961 return 0; 1017 return 0;
1018
1019error:
1020 up(&state->dst_mutex);
1021 return -EIO;
1022
962} 1023}
963EXPORT_SYMBOL(dst_command); 1024EXPORT_SYMBOL(dst_command);
964 1025
@@ -1016,7 +1077,7 @@ static int dst_get_tuna(struct dst_state *state)
1016 return 0; 1077 return 0;
1017 state->diseq_flags &= ~(HAS_LOCK); 1078 state->diseq_flags &= ~(HAS_LOCK);
1018 if (!dst_wait_dst_ready(state, NO_DELAY)) 1079 if (!dst_wait_dst_ready(state, NO_DELAY))
1019 return 0; 1080 return -EIO;
1020 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) 1081 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
1021 /* how to get variable length reply ???? */ 1082 /* how to get variable length reply ???? */
1022 retval = read_dst(state, state->rx_tuna, 10); 1083 retval = read_dst(state, state->rx_tuna, 10);
@@ -1024,22 +1085,27 @@ static int dst_get_tuna(struct dst_state *state)
1024 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 1085 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1025 if (retval < 0) { 1086 if (retval < 0) {
1026 dprintk(verbose, DST_DEBUG, 1, "read not successful"); 1087 dprintk(verbose, DST_DEBUG, 1, "read not successful");
1027 return 0; 1088 return retval;
1028 } 1089 }
1029 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1090 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1030 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1091 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1031 dprintk(verbose, DST_INFO, 1, "checksum failure ? "); 1092 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1032 return 0; 1093 return -EIO;
1033 } 1094 }
1034 } else { 1095 } else {
1035 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { 1096 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1036 dprintk(verbose, DST_INFO, 1, "checksum failure? "); 1097 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1037 return 0; 1098 return -EIO;
1038 } 1099 }
1039 } 1100 }
1040 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) 1101 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1041 return 0; 1102 return 0;
1042 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; 1103 if (state->dst_type == DST_TYPE_IS_SAT) {
1104 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1105 } else {
1106 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1107 }
1108 state->decode_freq = state->decode_freq * 1000;
1043 state->decode_lock = 1; 1109 state->decode_lock = 1;
1044 state->diseq_flags |= HAS_LOCK; 1110 state->diseq_flags |= HAS_LOCK;
1045 1111
@@ -1062,10 +1128,10 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1062 dst_set_voltage(fe, SEC_VOLTAGE_13); 1128 dst_set_voltage(fe, SEC_VOLTAGE_13);
1063 } 1129 }
1064 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 1130 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1065 1131 down(&state->dst_mutex);
1066 if ((dst_comm_init(state)) < 0) { 1132 if ((dst_comm_init(state)) < 0) {
1067 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); 1133 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1068 return -1; 1134 goto error;
1069 } 1135 }
1070 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1136 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1071 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1137 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
@@ -1077,23 +1143,29 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1077 if (retval < 0) { 1143 if (retval < 0) {
1078 dst_pio_disable(state); 1144 dst_pio_disable(state);
1079 dprintk(verbose, DST_DEBUG, 1, "write not successful"); 1145 dprintk(verbose, DST_DEBUG, 1, "write not successful");
1080 return retval; 1146 goto werr;
1081 } 1147 }
1082 if ((dst_pio_disable(state)) < 0) { 1148 if ((dst_pio_disable(state)) < 0) {
1083 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); 1149 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
1084 return -1; 1150 goto error;
1085 } 1151 }
1086 if ((read_dst(state, &reply, GET_ACK) < 0)) { 1152 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1087 dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); 1153 dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
1088 return -1; 1154 goto error;
1089 } 1155 }
1090 if (reply != ACK) { 1156 if (reply != ACK) {
1091 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); 1157 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
1092 return 0; 1158 goto error;
1093 } 1159 }
1094 state->diseq_flags |= ATTEMPT_TUNE; 1160 state->diseq_flags |= ATTEMPT_TUNE;
1095 1161 retval = dst_get_tuna(state);
1096 return dst_get_tuna(state); 1162werr:
1163 up(&state->dst_mutex);
1164 return retval;
1165
1166error:
1167 up(&state->dst_mutex);
1168 return -EIO;
1097} 1169}
1098 1170
1099/* 1171/*
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 6776a592045f..e6541aff3996 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -69,62 +69,53 @@ static int ca_set_pid(void)
69} 69}
70 70
71 71
72static int put_checksum(u8 *check_string, int length) 72static void put_checksum(u8 *check_string, int length)
73{ 73{
74 u8 i = 0, checksum = 0; 74 dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
75 75 dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length);
76 dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ==========================="); 76 check_string[length] = dst_check_sum (check_string, length);
77 dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length); 77 dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]);
78 dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
79
80 while (i < length) {
81 dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
82 checksum += check_string[i];
83 i++;
84 }
85 dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
86 dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
87 check_string[length] = ~checksum + 1;
88 dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
89 dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
90
91 return 0;
92} 78}
93 79
94static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) 80static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
95{ 81{
96 u8 reply; 82 u8 reply;
97 83
84 down(&state->dst_mutex);
98 dst_comm_init(state); 85 dst_comm_init(state);
99 msleep(65); 86 msleep(65);
100 87
101 if (write_dst(state, data, len)) { 88 if (write_dst(state, data, len)) {
102 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); 89 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
103 dst_error_recovery(state); 90 dst_error_recovery(state);
104 return -1; 91 goto error;
105 } 92 }
106 if ((dst_pio_disable(state)) < 0) { 93 if ((dst_pio_disable(state)) < 0) {
107 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); 94 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
108 return -1; 95 goto error;
109 } 96 }
110 if (read_dst(state, &reply, GET_ACK) < 0) { 97 if (read_dst(state, &reply, GET_ACK) < 0) {
111 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 98 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
112 dst_error_recovery(state); 99 dst_error_recovery(state);
113 return -1; 100 goto error;
114 } 101 }
115 if (read) { 102 if (read) {
116 if (! dst_wait_dst_ready(state, LONG_DELAY)) { 103 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
117 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); 104 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
118 return -1; 105 goto error;
119 } 106 }
120 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ 107 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
121 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 108 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
122 dst_error_recovery(state); 109 dst_error_recovery(state);
123 return -1; 110 goto error;
124 } 111 }
125 } 112 }
126 113 up(&state->dst_mutex);
127 return 0; 114 return 0;
115
116error:
117 up(&state->dst_mutex);
118 return -EIO;
128} 119}
129 120
130 121
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state)
166 return 0; 157 return 0;
167} 158}
168 159
169static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) 160static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
170{ 161{
171 int i; 162 int i;
172 u8 slot_cap[256]; 163 u8 slot_cap[256];
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
192 p_ca_caps->descr_num = slot_cap[7]; 183 p_ca_caps->descr_num = slot_cap[7];
193 p_ca_caps->descr_type = 1; 184 p_ca_caps->descr_type = 1;
194 185
195 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) 186 if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
196 return -EFAULT; 187 return -EFAULT;
197 188
198 return 0; 189 return 0;
199} 190}
200 191
201/* Need some more work */ 192/* Need some more work */
202static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 193static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
203{ 194{
204 return -EOPNOTSUPP; 195 return -EOPNOTSUPP;
205} 196}
206 197
207 198
208static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) 199static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
209{ 200{
210 int i; 201 int i;
211 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 202 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
212 203
213 u8 *slot_info = state->rxbuffer; 204 u8 *slot_info = state->messages;
214 205
215 put_checksum(&slot_command[0], 7); 206 put_checksum(&slot_command[0], 7);
216 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { 207 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
238 } else 229 } else
239 p_ca_slot_info->flags = 0; 230 p_ca_slot_info->flags = 0;
240 231
241 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) 232 if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
242 return -EFAULT; 233 return -EFAULT;
243 234
244 return 0; 235 return 0;
245} 236}
246 237
247 238
248static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 239static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
249{ 240{
250 u8 i = 0; 241 u8 i = 0;
251 u32 command = 0; 242 u32 command = 0;
252 243
253 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 244 if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
254 return -EFAULT; 245 return -EFAULT;
255 246
256 if (p_ca_message->msg) { 247 if (p_ca_message->msg) {
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
266 switch (command) { 257 switch (command) {
267 case CA_APP_INFO: 258 case CA_APP_INFO:
268 memcpy(p_ca_message->msg, state->messages, 128); 259 memcpy(p_ca_message->msg, state->messages, 128);
269 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) 260 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
270 return -EFAULT; 261 return -EFAULT;
271 break; 262 break;
272 } 263 }
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l
315 return 0; 306 return 0;
316} 307}
317 308
318u32 asn_1_decode(u8 *asn_1_array) 309static u32 asn_1_decode(u8 *asn_1_array)
319{ 310{
320 u8 length_field = 0, word_count = 0, count = 0; 311 u8 length_field = 0, word_count = 0, count = 0;
321 u32 length = 0; 312 u32 length = 0;
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array)
328 } else { 319 } else {
329 word_count = length_field & 0x7f; 320 word_count = length_field & 0x7f;
330 for (count = 0; count < word_count; count++) { 321 for (count = 0; count < word_count; count++) {
331 length = (length | asn_1_array[count + 1]) << 8; 322 length = length << 8;
323 length += asn_1_array[count + 1];
332 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); 324 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
333 } 325 }
334 } 326 }
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
399 return 0; 391 return 0;
400} 392}
401 393
402static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 394static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
403{ 395{
404 int i = 0; 396 int i = 0;
405 unsigned int ca_message_header_len; 397 unsigned int ca_message_header_len;
406 398
407 u32 command = 0; 399 u32 command = 0;
408 struct ca_msg *hw_buffer; 400 struct ca_msg *hw_buffer;
401 int result = 0;
409 402
410 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 403 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
411 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 404 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
413 } 406 }
414 dprintk(verbose, DST_CA_DEBUG, 1, " "); 407 dprintk(verbose, DST_CA_DEBUG, 1, " ");
415 408
416 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 409 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
417 return -EFAULT; 410 result = -EFAULT;
411 goto free_mem_and_exit;
412 }
413
418 414
419 if (p_ca_message->msg) { 415 if (p_ca_message->msg) {
420 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ 416 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
433 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); 429 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
434 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started 430 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
435 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); 431 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
436 return -1; 432 result = -1;
433 goto free_mem_and_exit;
437 } 434 }
438 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); 435 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
439 break; 436 break;
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
442 /* Have to handle the 2 basic types of cards here */ 439 /* Have to handle the 2 basic types of cards here */
443 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { 440 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
444 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); 441 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
445 return -1; 442 result = -1;
443 goto free_mem_and_exit;
446 } 444 }
447 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); 445 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
448 break; 446 break;
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
451 449
452 if ((ca_get_app_info(state)) < 0) { 450 if ((ca_get_app_info(state)) < 0) {
453 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); 451 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
454 return -1; 452 result = -1;
453 goto free_mem_and_exit;
455 } 454 }
456 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); 455 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
457 break; 456 break;
458 } 457 }
459 } 458 }
460 return 0; 459free_mem_and_exit:
460 kfree (hw_buffer);
461
462 return result;
461} 463}
462 464
463static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 465static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
464{ 466{
465 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 467 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
466 struct dst_state* state = (struct dst_state*) dvbdev->priv; 468 struct dst_state* state = (struct dst_state*) dvbdev->priv;
467 struct ca_slot_info *p_ca_slot_info; 469 struct ca_slot_info *p_ca_slot_info;
468 struct ca_caps *p_ca_caps; 470 struct ca_caps *p_ca_caps;
469 struct ca_msg *p_ca_message; 471 struct ca_msg *p_ca_message;
472 void __user *arg = (void __user *)ioctl_arg;
473 int result = 0;
470 474
471 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 475 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
472 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 476 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
486 dprintk(verbose, DST_CA_INFO, 1, " Sending message"); 490 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
487 if ((ca_send_message(state, p_ca_message, arg)) < 0) { 491 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
488 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); 492 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
489 return -1; 493 result = -1;
494 goto free_mem_and_exit;
490 } 495 }
491 break; 496 break;
492 case CA_GET_MSG: 497 case CA_GET_MSG:
493 dprintk(verbose, DST_CA_INFO, 1, " Getting message"); 498 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
494 if ((ca_get_message(state, p_ca_message, arg)) < 0) { 499 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
495 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); 500 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
496 return -1; 501 result = -1;
502 goto free_mem_and_exit;
497 } 503 }
498 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); 504 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
499 break; 505 break;
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
506 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); 512 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
507 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { 513 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
508 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); 514 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
509 return -1; 515 result = -1;
516 goto free_mem_and_exit;
510 } 517 }
511 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); 518 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
512 break; 519 break;
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
514 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); 521 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
515 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { 522 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
516 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); 523 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
517 return -1; 524 result = -1;
525 goto free_mem_and_exit;
518 } 526 }
519 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); 527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
520 break; 528 break;
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
522 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); 530 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
523 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { 531 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
524 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); 532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
525 return -1; 533 result = -1;
534 goto free_mem_and_exit;
526 } 535 }
527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); 536 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
528 break; 537 break;
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
530 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); 539 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
531 if ((ca_set_slot_descr()) < 0) { 540 if ((ca_set_slot_descr()) < 0) {
532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); 541 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
533 return -1; 542 result = -1;
543 goto free_mem_and_exit;
534 } 544 }
535 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); 545 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
536 break; 546 break;
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
538 dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); 548 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
539 if ((ca_set_pid()) < 0) { 549 if ((ca_set_pid()) < 0) {
540 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); 550 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
541 return -1; 551 result = -1;
552 goto free_mem_and_exit;
542 } 553 }
543 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); 554 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
544 default: 555 default:
545 return -EOPNOTSUPP; 556 result = -EOPNOTSUPP;
546 }; 557 };
558 free_mem_and_exit:
559 kfree (p_ca_message);
560 kfree (p_ca_slot_info);
561 kfree (p_ca_caps);
547 562
548 return 0; 563 return result;
549} 564}
550 565
551static int dst_ca_open(struct inode *inode, struct file *file) 566static int dst_ca_open(struct inode *inode, struct file *file)
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len
582 597
583static struct file_operations dst_ca_fops = { 598static struct file_operations dst_ca_fops = {
584 .owner = THIS_MODULE, 599 .owner = THIS_MODULE,
585 .ioctl = (void *)dst_ca_ioctl, 600 .ioctl = dst_ca_ioctl,
586 .open = dst_ca_open, 601 .open = dst_ca_open,
587 .release = dst_ca_release, 602 .release = dst_ca_release,
588 .read = dst_ca_read, 603 .read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3281a6ca3685..81557f38fe38 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,6 +22,7 @@
22#ifndef DST_COMMON_H 22#ifndef DST_COMMON_H
23#define DST_COMMON_H 23#define DST_COMMON_H
24 24
25#include <linux/smp_lock.h>
25#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
26#include <linux/device.h> 27#include <linux/device.h>
27#include "bt878.h" 28#include "bt878.h"
@@ -49,6 +50,7 @@
49#define DST_TYPE_HAS_FW_BUILD 64 50#define DST_TYPE_HAS_FW_BUILD 64
50#define DST_TYPE_HAS_OBS_REGS 128 51#define DST_TYPE_HAS_OBS_REGS 128
51#define DST_TYPE_HAS_INC_COUNT 256 52#define DST_TYPE_HAS_INC_COUNT 256
53#define DST_TYPE_HAS_MULTI_FE 512
52 54
53/* Card capability list */ 55/* Card capability list */
54 56
@@ -117,6 +119,9 @@ struct dst_state {
117 u8 fw_version[8]; 119 u8 fw_version[8];
118 u8 card_info[8]; 120 u8 card_info[8];
119 u8 vendor[8]; 121 u8 vendor[8];
122 u8 board_info[8];
123
124 struct semaphore dst_mutex;
120}; 125};
121 126
122struct dst_types { 127struct dst_types {
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index c5c7672cd538..2e398090cf63 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -34,6 +34,7 @@
34#include "dvb_frontend.h" 34#include "dvb_frontend.h"
35#include "dvb-bt8xx.h" 35#include "dvb-bt8xx.h"
36#include "bt878.h" 36#include "bt878.h"
37#include "dvb-pll.h"
37 38
38static int debug; 39static int debug;
39 40
@@ -279,7 +280,7 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
279 data[0] = (div >> 8) & 0x7f; 280 data[0] = (div >> 8) & 0x7f;
280 data[1] = div & 0xff; 281 data[1] = div & 0xff;
281 data[2] = ((div >> 10) & 0x60) | cfg; 282 data[2] = ((div >> 10) & 0x60) | cfg;
282 data[3] = cpump | band_select; 283 data[3] = (cpump << 6) | band_select;
283 284
284 i2c_transfer(card->i2c_adapter, &msg, 1); 285 i2c_transfer(card->i2c_adapter, &msg, 1);
285 return (div * 166666 - 36000000); 286 return (div * 166666 - 36000000);
@@ -522,9 +523,7 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
522 /* 523 /*
523 * Reset the frontend, must be called before trying 524 * Reset the frontend, must be called before trying
524 * to initialise the MT352 or mt352_attach 525 * to initialise the MT352 or mt352_attach
525 * will fail. 526 * will fail. Same goes for the nxt6000 frontend.
526 *
527 * Presumably not required for the NXT6000 frontend.
528 * 527 *
529 */ 528 */
530 529
@@ -546,14 +545,63 @@ static struct mt352_config digitv_alps_tded4_config = {
546 .pll_set = digitv_alps_tded4_pll_set, 545 .pll_set = digitv_alps_tded4_pll_set,
547}; 546};
548 547
548static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
549{
550 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
551 u8 buf[4];
552 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
553 int err;
554
555 dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0);
556 dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
557 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
558 if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) {
559 printk(KERN_WARNING "dvb-bt8xx: %s error "
560 "(addr %02x <- %02x, err = %i)\n",
561 __FUNCTION__, buf[0], buf[1], err);
562 if (err < 0)
563 return err;
564 else
565 return -EREMOTEIO;
566 }
567
568 /* Set the Auxiliary Byte. */
569 buf[2] &= ~0x20;
570 buf[2] |= 0x18;
571 buf[3] = 0x50;
572 i2c_transfer(card->i2c_adapter, &msg, 1);
573
574 return 0;
575}
576
577static struct lgdt330x_config tdvs_tua6034_config = {
578 .demod_address = 0x0e,
579 .demod_chip = LGDT3303,
580 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
581 .pll_set = tdvs_tua6034_pll_set,
582};
583
584static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
585{
586 /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
587
588 /* Pulse the reset line */
589 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
590 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */
591 msleep(100);
592
593 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
594 msleep(100);
595}
596
549static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 597static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
550{ 598{
551 int ret; 599 int ret;
552 struct dst_state* state = NULL; 600 struct dst_state* state = NULL;
553 601
554 switch(type) { 602 switch(type) {
555#ifdef BTTV_DVICO_DVBT_LITE 603#ifdef BTTV_BOARD_DVICO_DVBT_LITE
556 case BTTV_DVICO_DVBT_LITE: 604 case BTTV_BOARD_DVICO_DVBT_LITE:
557 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); 605 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
558 if (card->fe != NULL) { 606 if (card->fe != NULL) {
559 card->fe->ops->info.frequency_min = 174000000; 607 card->fe->ops->info.frequency_min = 174000000;
@@ -562,10 +610,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
562 break; 610 break;
563#endif 611#endif
564 612
565#ifdef BTTV_TWINHAN_VP3021 613#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
566 case BTTV_TWINHAN_VP3021: 614 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
615 lgdt330x_reset(card);
616 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
617 if (card->fe != NULL)
618 dprintk ("dvb_bt8xx: lgdt330x detected\n");
619 break;
620#endif
621
622#ifdef BTTV_BOARD_TWINHAN_VP3021
623 case BTTV_BOARD_TWINHAN_VP3021:
567#else 624#else
568 case BTTV_NEBULA_DIGITV: 625 case BTTV_BOARD_NEBULA_DIGITV:
569#endif 626#endif
570 /* 627 /*
571 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); 628 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
@@ -573,6 +630,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
573 */ 630 */
574 631
575 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ 632 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
633 digitv_alps_tded4_reset(card);
576 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); 634 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
577 if (card->fe != NULL) { 635 if (card->fe != NULL) {
578 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); 636 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
@@ -587,11 +645,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
587 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); 645 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
588 break; 646 break;
589 647
590 case BTTV_AVDVBT_761: 648 case BTTV_BOARD_AVDVBT_761:
591 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter); 649 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
592 break; 650 break;
593 651
594 case BTTV_AVDVBT_771: 652 case BTTV_BOARD_AVDVBT_771:
595 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); 653 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
596 if (card->fe != NULL) { 654 if (card->fe != NULL) {
597 card->fe->ops->info.frequency_min = 174000000; 655 card->fe->ops->info.frequency_min = 174000000;
@@ -599,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
599 } 657 }
600 break; 658 break;
601 659
602 case BTTV_TWINHAN_DST: 660 case BTTV_BOARD_TWINHAN_DST:
603 /* DST is not a frontend driver !!! */ 661 /* DST is not a frontend driver !!! */
604 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); 662 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
605 /* Setup the Card */ 663 /* Setup the Card */
@@ -620,11 +678,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
620 ret = dst_ca_attach(state, &card->dvb_adapter); 678 ret = dst_ca_attach(state, &card->dvb_adapter);
621 break; 679 break;
622 680
623 case BTTV_PINNACLESAT: 681 case BTTV_BOARD_PINNACLESAT:
624 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); 682 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
625 break; 683 break;
626 684
627 case BTTV_PC_HDTV: 685 case BTTV_BOARD_PC_HDTV:
628 card->fe = or51211_attach(&or51211_config, card->i2c_adapter); 686 card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
629 break; 687 break;
630 } 688 }
@@ -746,7 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev)
746 card->i2c_adapter = &sub->core->i2c_adap; 804 card->i2c_adapter = &sub->core->i2c_adap;
747 805
748 switch(sub->core->type) { 806 switch(sub->core->type) {
749 case BTTV_PINNACLESAT: 807 case BTTV_BOARD_PINNACLESAT:
750 card->gpio_mode = 0x0400c060; 808 card->gpio_mode = 0x0400c060;
751 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 809 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
752 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 810 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
@@ -754,8 +812,8 @@ static int dvb_bt8xx_probe(struct device *dev)
754 card->irq_err_ignore = 0; 812 card->irq_err_ignore = 0;
755 break; 813 break;
756 814
757#ifdef BTTV_DVICO_DVBT_LITE 815#ifdef BTTV_BOARD_DVICO_DVBT_LITE
758 case BTTV_DVICO_DVBT_LITE: 816 case BTTV_BOARD_DVICO_DVBT_LITE:
759#endif 817#endif
760 card->gpio_mode = 0x0400C060; 818 card->gpio_mode = 0x0400C060;
761 card->op_sync_orin = 0; 819 card->op_sync_orin = 0;
@@ -765,26 +823,34 @@ static int dvb_bt8xx_probe(struct device *dev)
765 * DA_APP(parallel) */ 823 * DA_APP(parallel) */
766 break; 824 break;
767 825
768#ifdef BTTV_TWINHAN_VP3021 826#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
769 case BTTV_TWINHAN_VP3021: 827 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
828#endif
829 card->gpio_mode = 0x0400c060;
830 card->op_sync_orin = BT878_RISC_SYNC_MASK;
831 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
832 break;
833
834#ifdef BTTV_BOARD_TWINHAN_VP3021
835 case BTTV_BOARD_TWINHAN_VP3021:
770#else 836#else
771 case BTTV_NEBULA_DIGITV: 837 case BTTV_BOARD_NEBULA_DIGITV:
772#endif 838#endif
773 case BTTV_AVDVBT_761: 839 case BTTV_BOARD_AVDVBT_761:
774 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); 840 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
775 card->op_sync_orin = 0; 841 card->op_sync_orin = 0;
776 card->irq_err_ignore = 0; 842 card->irq_err_ignore = 0;
777 /* A_PWRDN DA_SBR DA_APP (high speed serial) */ 843 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
778 break; 844 break;
779 845
780 case BTTV_AVDVBT_771: //case 0x07711461: 846 case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
781 card->gpio_mode = 0x0400402B; 847 card->gpio_mode = 0x0400402B;
782 card->op_sync_orin = BT878_RISC_SYNC_MASK; 848 card->op_sync_orin = BT878_RISC_SYNC_MASK;
783 card->irq_err_ignore = 0; 849 card->irq_err_ignore = 0;
784 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ 850 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
785 break; 851 break;
786 852
787 case BTTV_TWINHAN_DST: 853 case BTTV_BOARD_TWINHAN_DST:
788 card->gpio_mode = 0x2204f2c; 854 card->gpio_mode = 0x2204f2c;
789 card->op_sync_orin = BT878_RISC_SYNC_MASK; 855 card->op_sync_orin = BT878_RISC_SYNC_MASK;
790 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | 856 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
@@ -802,7 +868,7 @@ static int dvb_bt8xx_probe(struct device *dev)
802 * RISC+FIFO ENABLE */ 868 * RISC+FIFO ENABLE */
803 break; 869 break;
804 870
805 case BTTV_PC_HDTV: 871 case BTTV_BOARD_PC_HDTV:
806 card->gpio_mode = 0x0100EC7B; 872 card->gpio_mode = 0x0100EC7B;
807 card->op_sync_orin = 0; 873 card->op_sync_orin = 0;
808 card->irq_err_ignore = 0; 874 card->irq_err_ignore = 0;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 9ec8e5bd6c1f..cf035a80361c 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -35,6 +35,7 @@
35#include "nxt6000.h" 35#include "nxt6000.h"
36#include "cx24110.h" 36#include "cx24110.h"
37#include "or51211.h" 37#include "or51211.h"
38#include "lgdt330x.h"
38 39
39struct dvb_bt8xx_card { 40struct dvb_bt8xx_card {
40 struct semaphore lock; 41 struct semaphore lock;
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index 9719a3b30f78..7d7b0067f228 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -48,8 +48,11 @@
48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. 48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
49 */ 49 */
50 50
51#ifndef DMX_MAX_SECTION_SIZE
52#define DMX_MAX_SECTION_SIZE 4096
53#endif
51#ifndef DMX_MAX_SECFEED_SIZE 54#ifndef DMX_MAX_SECFEED_SIZE
52#define DMX_MAX_SECFEED_SIZE 4096 55#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
53#endif 56#endif
54 57
55 58
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dc476dda2b71..b4c899b15959 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -246,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
246 246
247 for (n = 0; sec->secbufp + 2 < limit; n++) { 247 for (n = 0; sec->secbufp + 2 < limit; n++) {
248 seclen = section_length(sec->secbuf); 248 seclen = section_length(sec->secbuf);
249 if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 249 if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
250 || seclen + sec->secbufp > limit) 250 || seclen + sec->secbufp > limit)
251 return 0; 251 return 0;
252 sec->seclen = seclen; 252 sec->seclen = seclen;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a8bc84240b50..6ffa6b216363 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -42,8 +42,6 @@
42#include "dvb_frontend.h" 42#include "dvb_frontend.h"
43#include "dvbdev.h" 43#include "dvbdev.h"
44 44
45// #define DEBUG_LOCKLOSS 1
46
47static int dvb_frontend_debug; 45static int dvb_frontend_debug;
48static int dvb_shutdown_timeout = 5; 46static int dvb_shutdown_timeout = 5;
49static int dvb_force_auto_inversion; 47static int dvb_force_auto_inversion;
@@ -438,25 +436,6 @@ static int dvb_frontend_thread(void *data)
438 if (s & FE_HAS_LOCK) 436 if (s & FE_HAS_LOCK)
439 continue; 437 continue;
440 else { /* if we _WERE_ tuned, but now don't have a lock */ 438 else { /* if we _WERE_ tuned, but now don't have a lock */
441#ifdef DEBUG_LOCKLOSS
442 /* first of all try setting the tone again if it was on - this
443 * sometimes works around problems with noisy power supplies */
444 if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) {
445 fe->ops->set_tone(fe, fepriv->tone);
446 mdelay(100);
447 s = 0;
448 fe->ops->read_status(fe, &s);
449 if (s & FE_HAS_LOCK) {
450 printk("DVB%i: Lock was lost, but regained by setting "
451 "the tone. This may indicate your power supply "
452 "is noisy/slightly incompatable with this DVB-S "
453 "adapter\n", fe->dvb->num);
454 fepriv->state = FESTATE_TUNED;
455 continue;
456 }
457 }
458#endif
459 /* some other reason for losing the lock - start zigzagging */
460 fepriv->state = FESTATE_ZIGZAG_FAST; 439 fepriv->state = FESTATE_ZIGZAG_FAST;
461 fepriv->started_auto_step = fepriv->auto_step; 440 fepriv->started_auto_step = fepriv->auto_step;
462 check_wrapped = 0; 441 check_wrapped = 0;
@@ -577,6 +556,49 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
577 fepriv->thread_pid); 556 fepriv->thread_pid);
578} 557}
579 558
559s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
560{
561 return ((curtime.tv_usec < lasttime.tv_usec) ?
562 1000000 - lasttime.tv_usec + curtime.tv_usec :
563 curtime.tv_usec - lasttime.tv_usec);
564}
565EXPORT_SYMBOL(timeval_usec_diff);
566
567static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
568{
569 curtime->tv_usec += add_usec;
570 if (curtime->tv_usec >= 1000000) {
571 curtime->tv_usec -= 1000000;
572 curtime->tv_sec++;
573 }
574}
575
576/*
577 * Sleep until gettimeofday() > waketime + add_usec
578 * This needs to be as precise as possible, but as the delay is
579 * usually between 2ms and 32ms, it is done using a scheduled msleep
580 * followed by usleep (normally a busy-wait loop) for the remainder
581 */
582void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
583{
584 struct timeval lasttime;
585 s32 delta, newdelta;
586
587 timeval_usec_add(waketime, add_usec);
588
589 do_gettimeofday(&lasttime);
590 delta = timeval_usec_diff(lasttime, *waketime);
591 if (delta > 2500) {
592 msleep((delta - 1500) / 1000);
593 do_gettimeofday(&lasttime);
594 newdelta = timeval_usec_diff(lasttime, *waketime);
595 delta = (newdelta > delta) ? 0 : newdelta;
596 }
597 if (delta > 0)
598 udelay(delta);
599}
600EXPORT_SYMBOL(dvb_frontend_sleep_until);
601
580static int dvb_frontend_start(struct dvb_frontend *fe) 602static int dvb_frontend_start(struct dvb_frontend *fe)
581{ 603{
582 int ret; 604 int ret;
@@ -728,6 +750,60 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
728 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); 750 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
729 fepriv->state = FESTATE_DISEQC; 751 fepriv->state = FESTATE_DISEQC;
730 fepriv->status = 0; 752 fepriv->status = 0;
753 } else if (fe->ops->set_voltage) {
754 /*
755 * NOTE: This is a fallback condition. Some frontends
756 * (stv0299 for instance) take longer than 8msec to
757 * respond to a set_voltage command. Those switches
758 * need custom routines to switch properly. For all
759 * other frontends, the following shoule work ok.
760 * Dish network legacy switches (as used by Dish500)
761 * are controlled by sending 9-bit command words
762 * spaced 8msec apart.
763 * the actual command word is switch/port dependant
764 * so it is up to the userspace application to send
765 * the right command.
766 * The command must always start with a '0' after
767 * initialization, so parg is 8 bits and does not
768 * include the initialization or start bit
769 */
770 unsigned int cmd = ((unsigned int) parg) << 1;
771 struct timeval nexttime;
772 struct timeval tv[10];
773 int i;
774 u8 last = 1;
775 if (dvb_frontend_debug)
776 printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd);
777 do_gettimeofday(&nexttime);
778 if (dvb_frontend_debug)
779 memcpy(&tv[0], &nexttime, sizeof(struct timeval));
780 /* before sending a command, initialize by sending
781 * a 32ms 18V to the switch
782 */
783 fe->ops->set_voltage(fe, SEC_VOLTAGE_18);
784 dvb_frontend_sleep_until(&nexttime, 32000);
785
786 for (i = 0; i < 9; i++) {
787 if (dvb_frontend_debug)
788 do_gettimeofday(&tv[i + 1]);
789 if ((cmd & 0x01) != last) {
790 /* set voltage to (last ? 13V : 18V) */
791 fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
792 last = (last) ? 0 : 1;
793 }
794 cmd = cmd >> 1;
795 if (i != 8)
796 dvb_frontend_sleep_until(&nexttime, 8000);
797 }
798 if (dvb_frontend_debug) {
799 printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
800 __FUNCTION__, fe->dvb->num);
801 for (i = 1; i < 10; i++)
802 printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
803 }
804 err = 0;
805 fepriv->state = FESTATE_DISEQC;
806 fepriv->status = 0;
731 } 807 }
732 break; 808 break;
733 809
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 9c2c1d1136bd..348c9b0b988a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -101,4 +101,7 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
101 101
102extern int dvb_unregister_frontend(struct dvb_frontend* fe); 102extern int dvb_unregister_frontend(struct dvb_frontend* fe);
103 103
104extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
105extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
106
104#endif 107#endif
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index e55322ef76b3..49f541d9a042 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -43,11 +43,9 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ 43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ 44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ 45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
46 { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
47 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ 46 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
48 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ 47 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
49 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ 48 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
50 { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
51 { 0x02, 0x14, KEY_MUTE }, /* MUTE */ 49 { 0x02, 0x14, KEY_MUTE }, /* MUTE */
52 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ 50 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
53 { 0x02, 0x19, KEY_RECORD }, /* RECORD */ 51 { 0x02, 0x19, KEY_RECORD }, /* RECORD */
@@ -57,8 +55,6 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
57 { 0x02, 0x1d, KEY_BACK }, /* << / RED */ 55 { 0x02, 0x1d, KEY_BACK }, /* << / RED */
58 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ 56 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
59 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ 57 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
60 { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
62 { 0x02, 0x04, KEY_EPG }, /* EPG */ 58 { 0x02, 0x04, KEY_EPG }, /* EPG */
63 { 0x02, 0x15, KEY_MENU }, /* MENU */ 59 { 0x02, 0x15, KEY_MENU }, /* MENU */
64 60
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 0058505634a0..aa271a2496d5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -82,13 +82,15 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
82static struct dvb_usb_properties dibusb1_1_properties; 82static struct dvb_usb_properties dibusb1_1_properties;
83static struct dvb_usb_properties dibusb1_1_an2235_properties; 83static struct dvb_usb_properties dibusb1_1_an2235_properties;
84static struct dvb_usb_properties dibusb2_0b_properties; 84static struct dvb_usb_properties dibusb2_0b_properties;
85static struct dvb_usb_properties artec_t1_usb2_properties;
85 86
86static int dibusb_probe(struct usb_interface *intf, 87static int dibusb_probe(struct usb_interface *intf,
87 const struct usb_device_id *id) 88 const struct usb_device_id *id)
88{ 89{
89 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || 90 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
90 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || 91 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
91 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0) 92 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 ||
93 dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0)
92 return 0; 94 return 0;
93 95
94 return -EINVAL; 96 return -EINVAL;
@@ -128,10 +130,13 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
128 130
129/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, 131/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
130 132
133/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
134/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
135
131// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 136// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
132 137
133#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 138#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
134/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, 139/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
135#endif 140#endif
136 { } /* Terminating entry */ 141 { } /* Terminating entry */
137}; 142};
@@ -264,7 +269,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
264 }, 269 },
265#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 270#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
266 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", 271 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
267 { &dibusb_dib3000mb_table[28], NULL }, 272 { &dibusb_dib3000mb_table[30], NULL },
268 { NULL }, 273 { NULL },
269 }, 274 },
270#endif 275#endif
@@ -273,7 +278,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
273 278
274static struct dvb_usb_properties dibusb2_0b_properties = { 279static struct dvb_usb_properties dibusb2_0b_properties = {
275 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, 280 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
276 .pid_filter_count = 32, 281 .pid_filter_count = 16,
277 282
278 .usb_ctrl = CYPRESS_FX2, 283 .usb_ctrl = CYPRESS_FX2,
279 284
@@ -321,6 +326,52 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
321 } 326 }
322}; 327};
323 328
329static struct dvb_usb_properties artec_t1_usb2_properties = {
330 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
331 .pid_filter_count = 16,
332
333 .usb_ctrl = CYPRESS_FX2,
334
335 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
336
337 .size_of_priv = sizeof(struct dibusb_state),
338
339 .streaming_ctrl = dibusb2_0_streaming_ctrl,
340 .pid_filter = dibusb_pid_filter,
341 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
342 .power_ctrl = dibusb2_0_power_ctrl,
343 .frontend_attach = dibusb_dib3000mb_frontend_attach,
344 .tuner_attach = dibusb_tuner_probe_and_attach,
345
346 .rc_interval = DEFAULT_RC_INTERVAL,
347 .rc_key_map = dibusb_rc_keys,
348 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
349 .rc_query = dibusb_rc_query,
350
351 .i2c_algo = &dibusb_i2c_algo,
352
353 .generic_bulk_ctrl_endpoint = 0x01,
354 /* parameter for the MPEG2-data transfer */
355 .urb = {
356 .type = DVB_USB_BULK,
357 .count = 7,
358 .endpoint = 0x06,
359 .u = {
360 .bulk = {
361 .buffersize = 4096,
362 }
363 }
364 },
365
366 .num_device_descs = 1,
367 .devices = {
368 { "Artec T1 USB2.0",
369 { &dibusb_dib3000mb_table[28], NULL },
370 { &dibusb_dib3000mb_table[29], NULL },
371 },
372 }
373};
374
324static struct usb_driver dibusb_driver = { 375static struct usb_driver dibusb_driver = {
325 .owner = THIS_MODULE, 376 .owner = THIS_MODULE,
326 .name = "dvb_usb_dibusb_mb", 377 .name = "dvb_usb_dibusb_mb",
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 6611f62977c0..2d99d05c7eab 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -11,7 +11,9 @@
11#ifndef _DVB_USB_DIBUSB_H_ 11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_ 12#define _DVB_USB_DIBUSB_H_
13 13
14#define DVB_USB_LOG_PREFIX "dibusb" 14#ifndef DVB_USB_LOG_PREFIX
15 #define DVB_USB_LOG_PREFIX "dibusb"
16#endif
15#include "dvb-usb.h" 17#include "dvb-usb.h"
16 18
17#include "dib3000.h" 19#include "dib3000.h"
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0818996bf150..6be99e537e12 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -43,10 +43,14 @@
43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c 44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d 45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
46#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
47#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
46#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 48#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
47#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 49#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
48#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 50#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
49#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 51#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
52#define USB_PID_DIBCOM_STK7700 0x1e14
53#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
50#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 54#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
51#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 55#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
52#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 56#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
@@ -68,6 +72,7 @@
68#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 72#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
69#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 73#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
70#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 74#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
75#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
71#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 76#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
72#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 77#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
73#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e 78#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index f5799a4c228e..36b7048c02d2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -196,7 +196,9 @@ static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, un
196 dvb_usb_free_stream_buffers(d); 196 dvb_usb_free_stream_buffers(d);
197 return -ENOMEM; 197 return -ENOMEM;
198 } 198 }
199 deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]); 199 deb_mem("buffer %d: %p (dma: %llu)\n",
200 d->buf_num, d->buf_list[d->buf_num],
201 (unsigned long long)d->dma_addr[d->buf_num]);
200 memset(d->buf_list[d->buf_num],0,size); 202 memset(d->buf_list[d->buf_num],0,size);
201 } 203 }
202 deb_mem("allocation successful\n"); 204 deb_mem("allocation successful\n");
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a50a41f6f79d..8e269e1c1f9d 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -164,6 +164,14 @@ config DVB_NXT2002
164 help 164 help
165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend. 165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
166 166
167config DVB_NXT200X
168 tristate "Nextwave NXT2002/NXT2004 based"
169 depends on DVB_CORE
170 select FW_LOADER
171 help
172 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
173 to support this frontend.
174
167config DVB_OR51211 175config DVB_OR51211
168 tristate "or51211 based (pcHDTV HD2000 card)" 176 tristate "or51211 based (pcHDTV HD2000 card)"
169 depends on DVB_CORE 177 depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index ad8658ffd60a..a98760fe08a1 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
26obj-$(CONFIG_DVB_TDA10021) += tda10021.o 26obj-$(CONFIG_DVB_TDA10021) += tda10021.o
27obj-$(CONFIG_DVB_STV0297) += stv0297.o 27obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o 28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o 30obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o 31obj-$(CONFIG_DVB_OR51132) += or51132.o
31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 32obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 536c35d969b7..f857b869616c 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -226,7 +226,7 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
226EXPORT_SYMBOL(dvb_pll_tua6034); 226EXPORT_SYMBOL(dvb_pll_tua6034);
227 227
228/* Infineon TUA6034 228/* Infineon TUA6034
229 * used in LG Innotek TDVS-H062F 229 * used in LG TDVS H061F and LG TDVS H062F
230 */ 230 */
231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { 231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
232 .name = "LG/Infineon TUA6034", 232 .name = "LG/Infineon TUA6034",
@@ -292,6 +292,58 @@ struct dvb_pll_desc dvb_pll_tded4 = {
292}; 292};
293EXPORT_SYMBOL(dvb_pll_tded4); 293EXPORT_SYMBOL(dvb_pll_tded4);
294 294
295/* ALPS TDHU2
296 * used in AverTVHD MCE A180
297 */
298struct dvb_pll_desc dvb_pll_tdhu2 = {
299 .name = "ALPS TDHU2",
300 .min = 54000000,
301 .max = 864000000,
302 .count = 4,
303 .entries = {
304 { 162000000, 44000000, 62500, 0x85, 0x01 },
305 { 426000000, 44000000, 62500, 0x85, 0x02 },
306 { 782000000, 44000000, 62500, 0x85, 0x08 },
307 { 999999999, 44000000, 62500, 0x85, 0x88 },
308 }
309};
310EXPORT_SYMBOL(dvb_pll_tdhu2);
311
312/* Philips TUV1236D
313 * used in ATI HDTV Wonder
314 */
315struct dvb_pll_desc dvb_pll_tuv1236d = {
316 .name = "Philips TUV1236D",
317 .min = 54000000,
318 .max = 864000000,
319 .count = 3,
320 .entries = {
321 { 157250000, 44000000, 62500, 0xc6, 0x41 },
322 { 454000000, 44000000, 62500, 0xc6, 0x42 },
323 { 999999999, 44000000, 62500, 0xc6, 0x44 },
324 },
325};
326EXPORT_SYMBOL(dvb_pll_tuv1236d);
327
328/* Samsung TBMV30111IN
329 * used in Air2PC ATSC - 2nd generation (nxt2002)
330 */
331struct dvb_pll_desc dvb_pll_tbmv30111in = {
332 .name = "Samsung TBMV30111IN",
333 .min = 54000000,
334 .max = 860000000,
335 .count = 4,
336 .entries = {
337 { 172000000, 44000000, 166666, 0xb4, 0x01 },
338 { 214000000, 44000000, 166666, 0xb4, 0x02 },
339 { 467000000, 44000000, 166666, 0xbc, 0x02 },
340 { 721000000, 44000000, 166666, 0xbc, 0x08 },
341 { 841000000, 44000000, 166666, 0xf4, 0x08 },
342 { 999999999, 44000000, 166666, 0xfc, 0x02 },
343 }
344};
345EXPORT_SYMBOL(dvb_pll_tbmv30111in);
346
295/* ----------------------------------------------------------- */ 347/* ----------------------------------------------------------- */
296/* code */ 348/* code */
297 349
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 205b2d1a8852..497d31dcf41e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -36,6 +36,10 @@ extern struct dvb_pll_desc dvb_pll_tda665x;
36extern struct dvb_pll_desc dvb_pll_fmd1216me; 36extern struct dvb_pll_desc dvb_pll_fmd1216me;
37extern struct dvb_pll_desc dvb_pll_tded4; 37extern struct dvb_pll_desc dvb_pll_tded4;
38 38
39extern struct dvb_pll_desc dvb_pll_tuv1236d;
40extern struct dvb_pll_desc dvb_pll_tdhu2;
41extern struct dvb_pll_desc dvb_pll_tbmv30111in;
42
39int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 43int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
40 u32 freq, int bandwidth); 44 u32 freq, int bandwidth);
41 45
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 7852b83b82d4..6a33f5a19a8d 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -26,6 +26,8 @@
26 * DViCO FusionHDTV 3 Gold-Q 26 * DViCO FusionHDTV 3 Gold-Q
27 * DViCO FusionHDTV 3 Gold-T 27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold 28 * DViCO FusionHDTV 5 Gold
29 * DViCO FusionHDTV 5 Lite
30 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
29 * 31 *
30 * TODO: 32 * TODO:
31 * signal strength always returns 0. 33 * signal strength always returns 0.
@@ -222,6 +224,11 @@ static int lgdt330x_init(struct dvb_frontend* fe)
222 0x4c, 0x14 224 0x4c, 0x14
223 }; 225 };
224 226
227 static u8 flip_lgdt3303_init_data[] = {
228 0x4c, 0x14,
229 0x87, 0xf3
230 };
231
225 struct lgdt330x_state* state = fe->demodulator_priv; 232 struct lgdt330x_state* state = fe->demodulator_priv;
226 char *chip_name; 233 char *chip_name;
227 int err; 234 int err;
@@ -234,8 +241,13 @@ static int lgdt330x_init(struct dvb_frontend* fe)
234 break; 241 break;
235 case LGDT3303: 242 case LGDT3303:
236 chip_name = "LGDT3303"; 243 chip_name = "LGDT3303";
237 err = i2c_write_demod_bytes(state, lgdt3303_init_data, 244 if (state->config->clock_polarity_flip) {
238 sizeof(lgdt3303_init_data)); 245 err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
246 sizeof(flip_lgdt3303_init_data));
247 } else {
248 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
249 sizeof(lgdt3303_init_data));
250 }
239 break; 251 break;
240 default: 252 default:
241 chip_name = "undefined"; 253 chip_name = "undefined";
@@ -743,9 +755,8 @@ static struct dvb_frontend_ops lgdt3302_ops = {
743 .frequency_min= 54000000, 755 .frequency_min= 54000000,
744 .frequency_max= 858000000, 756 .frequency_max= 858000000,
745 .frequency_stepsize= 62500, 757 .frequency_stepsize= 62500,
746 /* Symbol rate is for all VSB modes need to check QAM */ 758 .symbol_rate_min = 5056941, /* QAM 64 */
747 .symbol_rate_min = 10762000, 759 .symbol_rate_max = 10762000, /* VSB 8 */
748 .symbol_rate_max = 10762000,
749 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 760 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
750 }, 761 },
751 .init = lgdt330x_init, 762 .init = lgdt330x_init,
@@ -767,9 +778,8 @@ static struct dvb_frontend_ops lgdt3303_ops = {
767 .frequency_min= 54000000, 778 .frequency_min= 54000000,
768 .frequency_max= 858000000, 779 .frequency_max= 858000000,
769 .frequency_stepsize= 62500, 780 .frequency_stepsize= 62500,
770 /* Symbol rate is for all VSB modes need to check QAM */ 781 .symbol_rate_min = 5056941, /* QAM 64 */
771 .symbol_rate_min = 10762000, 782 .symbol_rate_max = 10762000, /* VSB 8 */
772 .symbol_rate_max = 10762000,
773 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 783 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
774 }, 784 },
775 .init = lgdt330x_init, 785 .init = lgdt330x_init,
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index e209ba1e47c5..2a6529cccf1a 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -47,6 +47,10 @@ struct lgdt330x_config
47 47
48 /* Need to set device param for start_dma */ 48 /* Need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50
51 /* Flip the polarity of the mpeg data transfer clock using alternate init data
52 * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
53 int clock_polarity_flip;
50}; 54};
51 55
52extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, 56extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
new file mode 100644
index 000000000000..bad0933eb714
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -0,0 +1,1205 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22*/
23
24/*
25 * NOTES ABOUT THIS DRIVER
26 *
27 * This Linux driver supports:
28 * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
29 * AverTVHD MCE A180 (NXT2004)
30 * ATI HDTV Wonder (NXT2004)
31 *
32 * This driver needs external firmware. Please use the command
33 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
34 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
35 * download/extract the appropriate firmware, and then copy it to
36 * /usr/lib/hotplug/firmware/ or /lib/firmware/
37 * (depending on configuration of firmware hotplug).
38 */
39#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
40#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
41#define CRC_CCIT_MASK 0x1021
42
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/module.h>
46#include <linux/moduleparam.h>
47
48#include "dvb_frontend.h"
49#include "dvb-pll.h"
50#include "nxt200x.h"
51
52struct nxt200x_state {
53
54 struct i2c_adapter* i2c;
55 struct dvb_frontend_ops ops;
56 const struct nxt200x_config* config;
57 struct dvb_frontend frontend;
58
59 /* demodulator private data */
60 nxt_chip_type demod_chip;
61 u8 initialised:1;
62};
63
64static int debug;
65#define dprintk(args...) \
66 do { \
67 if (debug) printk(KERN_DEBUG "nxt200x: " args); \
68 } while (0)
69
70static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
71{
72 int err;
73 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
74
75 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
76 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
77 __FUNCTION__, addr, err);
78 return -EREMOTEIO;
79 }
80 return 0;
81}
82
83static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
84{
85 int err;
86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
87
88 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
89 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
90 __FUNCTION__, addr, err);
91 return -EREMOTEIO;
92 }
93 return 0;
94}
95
96static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len)
97{
98 u8 buf2 [len+1];
99 int err;
100 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
101
102 buf2[0] = reg;
103 memcpy(&buf2[1], buf, len);
104
105 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
106 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
107 __FUNCTION__, state->config->demod_address, err);
108 return -EREMOTEIO;
109 }
110 return 0;
111}
112
113static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len)
114{
115 u8 reg2 [] = { reg };
116
117 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
118 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
119
120 int err;
121
122 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
123 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
124 __FUNCTION__, state->config->demod_address, err);
125 return -EREMOTEIO;
126 }
127 return 0;
128}
129
130static u16 nxt200x_crc(u16 crc, u8 c)
131{
132 u8 i;
133 u16 input = (u16) c & 0xFF;
134
135 input<<=8;
136 for(i=0; i<8; i++) {
137 if((crc^input) & 0x8000)
138 crc=(crc<<1)^CRC_CCIT_MASK;
139 else
140 crc<<=1;
141 input<<=1;
142 }
143 return crc;
144}
145
146static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
147{
148 u8 attr, len2, buf;
149 dprintk("%s\n", __FUNCTION__);
150
151 /* set mutli register register */
152 nxt200x_writebytes(state, 0x35, &reg, 1);
153
154 /* send the actual data */
155 nxt200x_writebytes(state, 0x36, data, len);
156
157 switch (state->demod_chip) {
158 case NXT2002:
159 len2 = len;
160 buf = 0x02;
161 break;
162 case NXT2004:
163 /* probably not right, but gives correct values */
164 attr = 0x02;
165 if (reg & 0x80) {
166 attr = attr << 1;
167 if (reg & 0x04)
168 attr = attr >> 1;
169 }
170 /* set write bit */
171 len2 = ((attr << 4) | 0x10) | len;
172 buf = 0x80;
173 break;
174 default:
175 return -EINVAL;
176 break;
177 }
178
179 /* set multi register length */
180 nxt200x_writebytes(state, 0x34, &len2, 1);
181
182 /* toggle the multireg write bit */
183 nxt200x_writebytes(state, 0x21, &buf, 1);
184
185 nxt200x_readbytes(state, 0x21, &buf, 1);
186
187 switch (state->demod_chip) {
188 case NXT2002:
189 if ((buf & 0x02) == 0)
190 return 0;
191 break;
192 case NXT2004:
193 if (buf == 0)
194 return 0;
195 break;
196 default:
197 return -EINVAL;
198 break;
199 }
200
201 printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
202
203 return 0;
204}
205
206static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
207{
208 int i;
209 u8 buf, len2, attr;
210 dprintk("%s\n", __FUNCTION__);
211
212 /* set mutli register register */
213 nxt200x_writebytes(state, 0x35, &reg, 1);
214
215 switch (state->demod_chip) {
216 case NXT2002:
217 /* set multi register length */
218 len2 = len & 0x80;
219 nxt200x_writebytes(state, 0x34, &len2, 1);
220
221 /* read the actual data */
222 nxt200x_readbytes(state, reg, data, len);
223 return 0;
224 break;
225 case NXT2004:
226 /* probably not right, but gives correct values */
227 attr = 0x02;
228 if (reg & 0x80) {
229 attr = attr << 1;
230 if (reg & 0x04)
231 attr = attr >> 1;
232 }
233
234 /* set multi register length */
235 len2 = (attr << 4) | len;
236 nxt200x_writebytes(state, 0x34, &len2, 1);
237
238 /* toggle the multireg bit*/
239 buf = 0x80;
240 nxt200x_writebytes(state, 0x21, &buf, 1);
241
242 /* read the actual data */
243 for(i = 0; i < len; i++) {
244 nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
245 }
246 return 0;
247 break;
248 default:
249 return -EINVAL;
250 break;
251 }
252}
253
254static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
255{
256 u8 buf, stopval, counter = 0;
257 dprintk("%s\n", __FUNCTION__);
258
259 /* set correct stop value */
260 switch (state->demod_chip) {
261 case NXT2002:
262 stopval = 0x40;
263 break;
264 case NXT2004:
265 stopval = 0x10;
266 break;
267 default:
268 stopval = 0;
269 break;
270 }
271
272 buf = 0x80;
273 nxt200x_writebytes(state, 0x22, &buf, 1);
274
275 while (counter < 20) {
276 nxt200x_readbytes(state, 0x31, &buf, 1);
277 if (buf & stopval)
278 return;
279 msleep(10);
280 counter++;
281 }
282
283 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
284 return;
285}
286
287static void nxt200x_microcontroller_start (struct nxt200x_state* state)
288{
289 u8 buf;
290 dprintk("%s\n", __FUNCTION__);
291
292 buf = 0x00;
293 nxt200x_writebytes(state, 0x22, &buf, 1);
294}
295
296static void nxt2004_microcontroller_init (struct nxt200x_state* state)
297{
298 u8 buf[9];
299 u8 counter = 0;
300 dprintk("%s\n", __FUNCTION__);
301
302 buf[0] = 0x00;
303 nxt200x_writebytes(state, 0x2b, buf, 1);
304 buf[0] = 0x70;
305 nxt200x_writebytes(state, 0x34, buf, 1);
306 buf[0] = 0x04;
307 nxt200x_writebytes(state, 0x35, buf, 1);
308 buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
309 buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
310 nxt200x_writebytes(state, 0x36, buf, 9);
311 buf[0] = 0x80;
312 nxt200x_writebytes(state, 0x21, buf, 1);
313
314 while (counter < 20) {
315 nxt200x_readbytes(state, 0x21, buf, 1);
316 if (buf[0] == 0)
317 return;
318 msleep(10);
319 counter++;
320 }
321
322 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
323
324 return;
325}
326
327static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
328{
329 u8 buf, count = 0;
330
331 dprintk("%s\n", __FUNCTION__);
332
333 dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]);
334
335 /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
336 * direct write is required for Philips TUV1236D and ALPS TDHU2 */
337 switch (state->demod_chip) {
338 case NXT2004:
339 if (i2c_writebytes(state, state->config->pll_address, data, 4))
340 printk(KERN_WARNING "nxt200x: error writing to tuner\n");
341 /* wait until we have a lock */
342 while (count < 20) {
343 i2c_readbytes(state, state->config->pll_address, &buf, 1);
344 if (buf & 0x40)
345 return 0;
346 msleep(100);
347 count++;
348 }
349 printk("nxt2004: timeout waiting for tuner lock\n");
350 break;
351 case NXT2002:
352 /* set the i2c transfer speed to the tuner */
353 buf = 0x03;
354 nxt200x_writebytes(state, 0x20, &buf, 1);
355
356 /* setup to transfer 4 bytes via i2c */
357 buf = 0x04;
358 nxt200x_writebytes(state, 0x34, &buf, 1);
359
360 /* write actual tuner bytes */
361 nxt200x_writebytes(state, 0x36, data, 4);
362
363 /* set tuner i2c address */
364 buf = state->config->pll_address;
365 nxt200x_writebytes(state, 0x35, &buf, 1);
366
367 /* write UC Opmode to begin transfer */
368 buf = 0x80;
369 nxt200x_writebytes(state, 0x21, &buf, 1);
370
371 while (count < 20) {
372 nxt200x_readbytes(state, 0x21, &buf, 1);
373 if ((buf & 0x80)== 0x00)
374 return 0;
375 msleep(100);
376 count++;
377 }
378 printk("nxt2002: timeout error writing tuner\n");
379 break;
380 default:
381 return -EINVAL;
382 break;
383 }
384 return 0;
385}
386
387static void nxt200x_agc_reset(struct nxt200x_state* state)
388{
389 u8 buf;
390 dprintk("%s\n", __FUNCTION__);
391
392 switch (state->demod_chip) {
393 case NXT2002:
394 buf = 0x08;
395 nxt200x_writebytes(state, 0x08, &buf, 1);
396 buf = 0x00;
397 nxt200x_writebytes(state, 0x08, &buf, 1);
398 break;
399 case NXT2004:
400 nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
401 buf = 0x08;
402 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
403 buf = 0x00;
404 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
405 break;
406 default:
407 break;
408 }
409 return;
410}
411
412static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
413{
414
415 struct nxt200x_state* state = fe->demodulator_priv;
416 u8 buf[3], written = 0, chunkpos = 0;
417 u16 rambase, position, crc = 0;
418
419 dprintk("%s\n", __FUNCTION__);
420 dprintk("Firmware is %zu bytes\n", fw->size);
421
422 /* Get the RAM base for this nxt2002 */
423 nxt200x_readbytes(state, 0x10, buf, 1);
424
425 if (buf[0] & 0x10)
426 rambase = 0x1000;
427 else
428 rambase = 0x0000;
429
430 dprintk("rambase on this nxt2002 is %04X\n", rambase);
431
432 /* Hold the micro in reset while loading firmware */
433 buf[0] = 0x80;
434 nxt200x_writebytes(state, 0x2B, buf, 1);
435
436 for (position = 0; position < fw->size; position++) {
437 if (written == 0) {
438 crc = 0;
439 chunkpos = 0x28;
440 buf[0] = ((rambase + position) >> 8);
441 buf[1] = (rambase + position) & 0xFF;
442 buf[2] = 0x81;
443 /* write starting address */
444 nxt200x_writebytes(state, 0x29, buf, 3);
445 }
446 written++;
447 chunkpos++;
448
449 if ((written % 4) == 0)
450 nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
451
452 crc = nxt200x_crc(crc, fw->data[position]);
453
454 if ((written == 255) || (position+1 == fw->size)) {
455 /* write remaining bytes of firmware */
456 nxt200x_writebytes(state, chunkpos+4-(written %4),
457 &fw->data[position-(written %4) + 1],
458 written %4);
459 buf[0] = crc << 8;
460 buf[1] = crc & 0xFF;
461
462 /* write crc */
463 nxt200x_writebytes(state, 0x2C, buf, 2);
464
465 /* do a read to stop things */
466 nxt200x_readbytes(state, 0x2A, buf, 1);
467
468 /* set transfer mode to complete */
469 buf[0] = 0x80;
470 nxt200x_writebytes(state, 0x2B, buf, 1);
471
472 written = 0;
473 }
474 }
475
476 return 0;
477};
478
479static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
480{
481
482 struct nxt200x_state* state = fe->demodulator_priv;
483 u8 buf[3];
484 u16 rambase, position, crc=0;
485
486 dprintk("%s\n", __FUNCTION__);
487 dprintk("Firmware is %zu bytes\n", fw->size);
488
489 /* set rambase */
490 rambase = 0x1000;
491
492 /* hold the micro in reset while loading firmware */
493 buf[0] = 0x80;
494 nxt200x_writebytes(state, 0x2B, buf,1);
495
496 /* calculate firmware CRC */
497 for (position = 0; position < fw->size; position++) {
498 crc = nxt200x_crc(crc, fw->data[position]);
499 }
500
501 buf[0] = rambase >> 8;
502 buf[1] = rambase & 0xFF;
503 buf[2] = 0x81;
504 /* write starting address */
505 nxt200x_writebytes(state,0x29,buf,3);
506
507 for (position = 0; position < fw->size;) {
508 nxt200x_writebytes(state, 0x2C, &fw->data[position],
509 fw->size-position > 255 ? 255 : fw->size-position);
510 position += (fw->size-position > 255 ? 255 : fw->size-position);
511 }
512 buf[0] = crc >> 8;
513 buf[1] = crc & 0xFF;
514
515 dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
516
517 /* write crc */
518 nxt200x_writebytes(state, 0x2C, buf,2);
519
520 /* do a read to stop things */
521 nxt200x_readbytes(state, 0x2C, buf, 1);
522
523 /* set transfer mode to complete */
524 buf[0] = 0x80;
525 nxt200x_writebytes(state, 0x2B, buf,1);
526
527 return 0;
528};
529
530static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
531 struct dvb_frontend_parameters *p)
532{
533 struct nxt200x_state* state = fe->demodulator_priv;
534 u8 buf[4];
535
536 /* stop the micro first */
537 nxt200x_microcontroller_stop(state);
538
539 if (state->demod_chip == NXT2004) {
540 /* make sure demod is set to digital */
541 buf[0] = 0x04;
542 nxt200x_writebytes(state, 0x14, buf, 1);
543 buf[0] = 0x00;
544 nxt200x_writebytes(state, 0x17, buf, 1);
545 }
546
547 /* get tuning information */
548 dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0);
549
550 /* set additional params */
551 switch (p->u.vsb.modulation) {
552 case QAM_64:
553 case QAM_256:
554 /* Set punctured clock for QAM */
555 /* This is just a guess since I am unable to test it */
556 if (state->config->set_ts_params)
557 state->config->set_ts_params(fe, 1);
558
559 /* set input */
560 if (state->config->set_pll_input)
561 state->config->set_pll_input(buf, 1);
562 break;
563 case VSB_8:
564 /* Set non-punctured clock for VSB */
565 if (state->config->set_ts_params)
566 state->config->set_ts_params(fe, 0);
567
568 /* set input */
569 if (state->config->set_pll_input)
570 state->config->set_pll_input(buf, 0);
571 break;
572 default:
573 return -EINVAL;
574 break;
575 }
576
577 /* write frequency information */
578 nxt200x_writetuner(state, buf);
579
580 /* reset the agc now that tuning has been completed */
581 nxt200x_agc_reset(state);
582
583 /* set target power level */
584 switch (p->u.vsb.modulation) {
585 case QAM_64:
586 case QAM_256:
587 buf[0] = 0x74;
588 break;
589 case VSB_8:
590 buf[0] = 0x70;
591 break;
592 default:
593 return -EINVAL;
594 break;
595 }
596 nxt200x_writebytes(state, 0x42, buf, 1);
597
598 /* configure sdm */
599 switch (state->demod_chip) {
600 case NXT2002:
601 buf[0] = 0x87;
602 break;
603 case NXT2004:
604 buf[0] = 0x07;
605 break;
606 default:
607 return -EINVAL;
608 break;
609 }
610 nxt200x_writebytes(state, 0x57, buf, 1);
611
612 /* write sdm1 input */
613 buf[0] = 0x10;
614 buf[1] = 0x00;
615 nxt200x_writebytes(state, 0x58, buf, 2);
616
617 /* write sdmx input */
618 switch (p->u.vsb.modulation) {
619 case QAM_64:
620 buf[0] = 0x68;
621 break;
622 case QAM_256:
623 buf[0] = 0x64;
624 break;
625 case VSB_8:
626 buf[0] = 0x60;
627 break;
628 default:
629 return -EINVAL;
630 break;
631 }
632 buf[1] = 0x00;
633 nxt200x_writebytes(state, 0x5C, buf, 2);
634
635 /* write adc power lpf fc */
636 buf[0] = 0x05;
637 nxt200x_writebytes(state, 0x43, buf, 1);
638
639 if (state->demod_chip == NXT2004) {
640 /* write ??? */
641 buf[0] = 0x00;
642 buf[1] = 0x00;
643 nxt200x_writebytes(state, 0x46, buf, 2);
644 }
645
646 /* write accumulator2 input */
647 buf[0] = 0x80;
648 buf[1] = 0x00;
649 nxt200x_writebytes(state, 0x4B, buf, 2);
650
651 /* write kg1 */
652 buf[0] = 0x00;
653 nxt200x_writebytes(state, 0x4D, buf, 1);
654
655 /* write sdm12 lpf fc */
656 buf[0] = 0x44;
657 nxt200x_writebytes(state, 0x55, buf, 1);
658
659 /* write agc control reg */
660 buf[0] = 0x04;
661 nxt200x_writebytes(state, 0x41, buf, 1);
662
663 if (state->demod_chip == NXT2004) {
664 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
665 buf[0] = 0x24;
666 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
667
668 /* soft reset? */
669 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
670 buf[0] = 0x10;
671 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
672 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
673 buf[0] = 0x00;
674 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
675
676 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
677 buf[0] = 0x04;
678 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
679 buf[0] = 0x00;
680 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
681 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
682 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
683 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
684 buf[0] = 0x11;
685 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
686 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
687 buf[0] = 0x44;
688 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
689 }
690
691 /* write agc ucgp0 */
692 switch (p->u.vsb.modulation) {
693 case QAM_64:
694 buf[0] = 0x02;
695 break;
696 case QAM_256:
697 buf[0] = 0x03;
698 break;
699 case VSB_8:
700 buf[0] = 0x00;
701 break;
702 default:
703 return -EINVAL;
704 break;
705 }
706 nxt200x_writebytes(state, 0x30, buf, 1);
707
708 /* write agc control reg */
709 buf[0] = 0x00;
710 nxt200x_writebytes(state, 0x41, buf, 1);
711
712 /* write accumulator2 input */
713 buf[0] = 0x80;
714 buf[1] = 0x00;
715 nxt200x_writebytes(state, 0x49, buf,2);
716 nxt200x_writebytes(state, 0x4B, buf,2);
717
718 /* write agc control reg */
719 buf[0] = 0x04;
720 nxt200x_writebytes(state, 0x41, buf, 1);
721
722 nxt200x_microcontroller_start(state);
723
724 if (state->demod_chip == NXT2004) {
725 nxt2004_microcontroller_init(state);
726
727 /* ???? */
728 buf[0] = 0xF0;
729 buf[1] = 0x00;
730 nxt200x_writebytes(state, 0x5C, buf, 2);
731 }
732
733 /* adjacent channel detection should be done here, but I don't
734 have any stations with this need so I cannot test it */
735
736 return 0;
737}
738
739static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
740{
741 struct nxt200x_state* state = fe->demodulator_priv;
742 u8 lock;
743 nxt200x_readbytes(state, 0x31, &lock, 1);
744
745 *status = 0;
746 if (lock & 0x20) {
747 *status |= FE_HAS_SIGNAL;
748 *status |= FE_HAS_CARRIER;
749 *status |= FE_HAS_VITERBI;
750 *status |= FE_HAS_SYNC;
751 *status |= FE_HAS_LOCK;
752 }
753 return 0;
754}
755
756static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
757{
758 struct nxt200x_state* state = fe->demodulator_priv;
759 u8 b[3];
760
761 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
762
763 *ber = ((b[0] << 8) + b[1]) * 8;
764
765 return 0;
766}
767
768static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
769{
770 struct nxt200x_state* state = fe->demodulator_priv;
771 u8 b[2];
772 u16 temp = 0;
773
774 /* setup to read cluster variance */
775 b[0] = 0x00;
776 nxt200x_writebytes(state, 0xA1, b, 1);
777
778 /* get multreg val */
779 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
780
781 temp = (b[0] << 8) | b[1];
782 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
783
784 return 0;
785}
786
787static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
788{
789
790 struct nxt200x_state* state = fe->demodulator_priv;
791 u8 b[2];
792 u16 temp = 0, temp2;
793 u32 snrdb = 0;
794
795 /* setup to read cluster variance */
796 b[0] = 0x00;
797 nxt200x_writebytes(state, 0xA1, b, 1);
798
799 /* get multreg val from 0xA6 */
800 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
801
802 temp = (b[0] << 8) | b[1];
803 temp2 = 0x7FFF - temp;
804
805 /* snr will be in db */
806 if (temp2 > 0x7F00)
807 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
808 else if (temp2 > 0x7EC0)
809 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
810 else if (temp2 > 0x7C00)
811 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
812 else
813 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
814
815 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
816 *snr = snrdb * (0xFFFF/32000);
817
818 return 0;
819}
820
821static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
822{
823 struct nxt200x_state* state = fe->demodulator_priv;
824 u8 b[3];
825
826 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
827 *ucblocks = b[2];
828
829 return 0;
830}
831
832static int nxt200x_sleep(struct dvb_frontend* fe)
833{
834 return 0;
835}
836
837static int nxt2002_init(struct dvb_frontend* fe)
838{
839 struct nxt200x_state* state = fe->demodulator_priv;
840 const struct firmware *fw;
841 int ret;
842 u8 buf[2];
843
844 /* request the firmware, this will block until someone uploads it */
845 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
846 ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev);
847 printk("nxt2002: Waiting for firmware upload(2)...\n");
848 if (ret) {
849 printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
850 return ret;
851 }
852
853 ret = nxt2002_load_firmware(fe, fw);
854 if (ret) {
855 printk("nxt2002: Writing firmware to device failed\n");
856 release_firmware(fw);
857 return ret;
858 }
859 printk("nxt2002: Firmware upload complete\n");
860
861 /* Put the micro into reset */
862 nxt200x_microcontroller_stop(state);
863
864 /* ensure transfer is complete */
865 buf[0]=0x00;
866 nxt200x_writebytes(state, 0x2B, buf, 1);
867
868 /* Put the micro into reset for real this time */
869 nxt200x_microcontroller_stop(state);
870
871 /* soft reset everything (agc,frontend,eq,fec)*/
872 buf[0] = 0x0F;
873 nxt200x_writebytes(state, 0x08, buf, 1);
874 buf[0] = 0x00;
875 nxt200x_writebytes(state, 0x08, buf, 1);
876
877 /* write agc sdm configure */
878 buf[0] = 0xF1;
879 nxt200x_writebytes(state, 0x57, buf, 1);
880
881 /* write mod output format */
882 buf[0] = 0x20;
883 nxt200x_writebytes(state, 0x09, buf, 1);
884
885 /* write fec mpeg mode */
886 buf[0] = 0x7E;
887 buf[1] = 0x00;
888 nxt200x_writebytes(state, 0xE9, buf, 2);
889
890 /* write mux selection */
891 buf[0] = 0x00;
892 nxt200x_writebytes(state, 0xCC, buf, 1);
893
894 return 0;
895}
896
897static int nxt2004_init(struct dvb_frontend* fe)
898{
899 struct nxt200x_state* state = fe->demodulator_priv;
900 const struct firmware *fw;
901 int ret;
902 u8 buf[3];
903
904 /* ??? */
905 buf[0]=0x00;
906 nxt200x_writebytes(state, 0x1E, buf, 1);
907
908 /* request the firmware, this will block until someone uploads it */
909 printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
910 ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev);
911 printk("nxt2004: Waiting for firmware upload(2)...\n");
912 if (ret) {
913 printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
914 return ret;
915 }
916
917 ret = nxt2004_load_firmware(fe, fw);
918 if (ret) {
919 printk("nxt2004: Writing firmware to device failed\n");
920 release_firmware(fw);
921 return ret;
922 }
923 printk("nxt2004: Firmware upload complete\n");
924
925 /* ensure transfer is complete */
926 buf[0] = 0x01;
927 nxt200x_writebytes(state, 0x19, buf, 1);
928
929 nxt2004_microcontroller_init(state);
930 nxt200x_microcontroller_stop(state);
931 nxt200x_microcontroller_stop(state);
932 nxt2004_microcontroller_init(state);
933 nxt200x_microcontroller_stop(state);
934
935 /* soft reset everything (agc,frontend,eq,fec)*/
936 buf[0] = 0xFF;
937 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
938 buf[0] = 0x00;
939 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
940
941 /* write agc sdm configure */
942 buf[0] = 0xD7;
943 nxt200x_writebytes(state, 0x57, buf, 1);
944
945 /* ???*/
946 buf[0] = 0x07;
947 buf[1] = 0xfe;
948 nxt200x_writebytes(state, 0x35, buf, 2);
949 buf[0] = 0x12;
950 nxt200x_writebytes(state, 0x34, buf, 1);
951 buf[0] = 0x80;
952 nxt200x_writebytes(state, 0x21, buf, 1);
953
954 /* ???*/
955 buf[0] = 0x21;
956 nxt200x_writebytes(state, 0x0A, buf, 1);
957
958 /* ???*/
959 buf[0] = 0x01;
960 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
961
962 /* write fec mpeg mode */
963 buf[0] = 0x7E;
964 buf[1] = 0x00;
965 nxt200x_writebytes(state, 0xE9, buf, 2);
966
967 /* write mux selection */
968 buf[0] = 0x00;
969 nxt200x_writebytes(state, 0xCC, buf, 1);
970
971 /* ???*/
972 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
973 buf[0] = 0x00;
974 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
975
976 /* soft reset? */
977 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
978 buf[0] = 0x10;
979 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
980 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
981 buf[0] = 0x00;
982 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
983
984 /* ???*/
985 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
986 buf[0] = 0x01;
987 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
988 buf[0] = 0x70;
989 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
990 buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
991 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
992
993 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
994 buf[0] = 0x11;
995 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
996 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
997 buf[0] = 0x40;
998 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
999
1000 nxt200x_readbytes(state, 0x10, buf, 1);
1001 buf[0] = 0x10;
1002 nxt200x_writebytes(state, 0x10, buf, 1);
1003 nxt200x_readbytes(state, 0x0A, buf, 1);
1004 buf[0] = 0x21;
1005 nxt200x_writebytes(state, 0x0A, buf, 1);
1006
1007 nxt2004_microcontroller_init(state);
1008
1009 buf[0] = 0x21;
1010 nxt200x_writebytes(state, 0x0A, buf, 1);
1011 buf[0] = 0x7E;
1012 nxt200x_writebytes(state, 0xE9, buf, 1);
1013 buf[0] = 0x00;
1014 nxt200x_writebytes(state, 0xEA, buf, 1);
1015
1016 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1017 buf[0] = 0x00;
1018 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1019 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1020 buf[0] = 0x00;
1021 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1022
1023 /* soft reset? */
1024 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1025 buf[0] = 0x10;
1026 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1027 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1028 buf[0] = 0x00;
1029 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1030
1031 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1032 buf[0] = 0x04;
1033 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1034 buf[0] = 0x00;
1035 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1036 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
1037 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1038
1039 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1040 buf[0] = 0x11;
1041 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1042
1043 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1044 buf[0] = 0x44;
1045 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1046
1047 /* initialize tuner */
1048 nxt200x_readbytes(state, 0x10, buf, 1);
1049 buf[0] = 0x12;
1050 nxt200x_writebytes(state, 0x10, buf, 1);
1051 buf[0] = 0x04;
1052 nxt200x_writebytes(state, 0x13, buf, 1);
1053 buf[0] = 0x00;
1054 nxt200x_writebytes(state, 0x16, buf, 1);
1055 buf[0] = 0x04;
1056 nxt200x_writebytes(state, 0x14, buf, 1);
1057 buf[0] = 0x00;
1058 nxt200x_writebytes(state, 0x14, buf, 1);
1059 nxt200x_writebytes(state, 0x17, buf, 1);
1060 nxt200x_writebytes(state, 0x14, buf, 1);
1061 nxt200x_writebytes(state, 0x17, buf, 1);
1062
1063 return 0;
1064}
1065
1066static int nxt200x_init(struct dvb_frontend* fe)
1067{
1068 struct nxt200x_state* state = fe->demodulator_priv;
1069 int ret = 0;
1070
1071 if (!state->initialised) {
1072 switch (state->demod_chip) {
1073 case NXT2002:
1074 ret = nxt2002_init(fe);
1075 break;
1076 case NXT2004:
1077 ret = nxt2004_init(fe);
1078 break;
1079 default:
1080 return -EINVAL;
1081 break;
1082 }
1083 state->initialised = 1;
1084 }
1085 return ret;
1086}
1087
1088static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1089{
1090 fesettings->min_delay_ms = 500;
1091 fesettings->step_size = 0;
1092 fesettings->max_drift = 0;
1093 return 0;
1094}
1095
1096static void nxt200x_release(struct dvb_frontend* fe)
1097{
1098 struct nxt200x_state* state = fe->demodulator_priv;
1099 kfree(state);
1100}
1101
1102static struct dvb_frontend_ops nxt200x_ops;
1103
1104struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1105 struct i2c_adapter* i2c)
1106{
1107 struct nxt200x_state* state = NULL;
1108 u8 buf [] = {0,0,0,0,0};
1109
1110 /* allocate memory for the internal state */
1111 state = (struct nxt200x_state*) kmalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
1112 if (state == NULL)
1113 goto error;
1114 memset(state,0,sizeof(*state));
1115
1116 /* setup the state */
1117 state->config = config;
1118 state->i2c = i2c;
1119 memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1120 state->initialised = 0;
1121
1122 /* read card id */
1123 nxt200x_readbytes(state, 0x00, buf, 5);
1124 dprintk("NXT info: %02X %02X %02X %02X %02X\n",
1125 buf[0], buf[1], buf[2], buf[3], buf[4]);
1126
1127 /* set demod chip */
1128 switch (buf[0]) {
1129 case 0x04:
1130 state->demod_chip = NXT2002;
1131 printk("nxt200x: NXT2002 Detected\n");
1132 break;
1133 case 0x05:
1134 state->demod_chip = NXT2004;
1135 printk("nxt200x: NXT2004 Detected\n");
1136 break;
1137 default:
1138 goto error;
1139 }
1140
1141 /* make sure demod chip is supported */
1142 switch (state->demod_chip) {
1143 case NXT2002:
1144 if (buf[0] != 0x04) goto error; /* device id */
1145 if (buf[1] != 0x02) goto error; /* fab id */
1146 if (buf[2] != 0x11) goto error; /* month */
1147 if (buf[3] != 0x20) goto error; /* year msb */
1148 if (buf[4] != 0x00) goto error; /* year lsb */
1149 break;
1150 case NXT2004:
1151 if (buf[0] != 0x05) goto error; /* device id */
1152 break;
1153 default:
1154 goto error;
1155 }
1156
1157 /* create dvb_frontend */
1158 state->frontend.ops = &state->ops;
1159 state->frontend.demodulator_priv = state;
1160 return &state->frontend;
1161
1162error:
1163 kfree(state);
1164 printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
1165 buf[0], buf[1], buf[2], buf[3], buf[4]);
1166 return NULL;
1167}
1168
1169static struct dvb_frontend_ops nxt200x_ops = {
1170
1171 .info = {
1172 .name = "Nextwave NXT200X VSB/QAM frontend",
1173 .type = FE_ATSC,
1174 .frequency_min = 54000000,
1175 .frequency_max = 860000000,
1176 .frequency_stepsize = 166666, /* stepsize is just a guess */
1177 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1178 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1179 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
1180 },
1181
1182 .release = nxt200x_release,
1183
1184 .init = nxt200x_init,
1185 .sleep = nxt200x_sleep,
1186
1187 .set_frontend = nxt200x_setup_frontend_parameters,
1188 .get_tune_settings = nxt200x_get_tune_settings,
1189
1190 .read_status = nxt200x_read_status,
1191 .read_ber = nxt200x_read_ber,
1192 .read_signal_strength = nxt200x_read_signal_strength,
1193 .read_snr = nxt200x_read_snr,
1194 .read_ucblocks = nxt200x_read_ucblocks,
1195};
1196
1197module_param(debug, int, 0644);
1198MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1199
1200MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1201MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
1202MODULE_LICENSE("GPL");
1203
1204EXPORT_SYMBOL(nxt200x_attach);
1205
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
new file mode 100644
index 000000000000..1d9d70bc37ef
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -0,0 +1,61 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22*/
23
24#ifndef NXT200X_H
25#define NXT200X_H
26
27#include <linux/dvb/frontend.h>
28#include <linux/firmware.h>
29
30typedef enum nxt_chip_t {
31 NXTUNDEFINED,
32 NXT2002,
33 NXT2004
34}nxt_chip_type;
35
36struct nxt200x_config
37{
38 /* the demodulator's i2c address */
39 u8 demod_address;
40
41 /* tuner information */
42 u8 pll_address;
43 struct dvb_pll_desc *pll_desc;
44
45 /* used to set pll input */
46 int (*set_pll_input)(u8* buf, int input);
47
48 /* need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50};
51
52extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
53 struct i2c_adapter* i2c);
54
55#endif /* NXT200X_H */
56
57/*
58 * Local variables:
59 * c-basic-offset: 8
60 * End:
61 */
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index fc74c40d6477..78bded861d02 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -468,6 +468,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
468 unsigned char snd_buf[2]; 468 unsigned char snd_buf[2];
469 u8 rcvr_stat; 469 u8 rcvr_stat;
470 u16 snr_equ; 470 u16 snr_equ;
471 u32 signal_strength;
471 int usK; 472 int usK;
472 473
473 snd_buf[0]=0x04; 474 snd_buf[0]=0x04;
@@ -503,7 +504,11 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
503 usK = (rcvr_stat & 0x10) ? 3 : 0; 504 usK = (rcvr_stat & 0x10) ? 3 : 0;
504 505
505 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 506 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
506 *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000; 507 signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
508 if (signal_strength > 0xffff)
509 *strength = 0xffff;
510 else
511 *strength = signal_strength;
507 dprintk("read_signal_strength %i\n",*strength); 512 dprintk("read_signal_strength %i\n",*strength);
508 513
509 return 0; 514 return 0;
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 8a9db23dd1b7..531f76246e5f 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -339,6 +339,7 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
339 u8 rec_buf[2]; 339 u8 rec_buf[2];
340 u8 snd_buf[4]; 340 u8 snd_buf[4];
341 u8 snr_equ; 341 u8 snr_equ;
342 u32 signal_strength;
342 343
343 /* SNR after Equalizer */ 344 /* SNR after Equalizer */
344 snd_buf[0] = 0x04; 345 snd_buf[0] = 0x04;
@@ -358,8 +359,11 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
358 snr_equ = rec_buf[0] & 0xff; 359 snr_equ = rec_buf[0] & 0xff;
359 360
360 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 361 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
361 *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000; 362 signal_strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
362 363 if (signal_strength > 0xffff)
364 *strength = 0xffff;
365 else
366 *strength = signal_strength;
363 dprintk("read_signal_strength %i\n",*strength); 367 dprintk("read_signal_strength %i\n",*strength);
364 368
365 return 0; 369 return 0;
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 889d9257215d..29c48665e130 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -64,8 +64,12 @@ struct stv0299_state {
64 u32 tuner_frequency; 64 u32 tuner_frequency;
65 u32 symbol_rate; 65 u32 symbol_rate;
66 fe_code_rate_t fec_inner; 66 fe_code_rate_t fec_inner;
67 int errmode;
67}; 68};
68 69
70#define STATUS_BER 0
71#define STATUS_UCBLOCKS 1
72
69static int debug; 73static int debug;
70static int debug_legacy_dish_switch; 74static int debug_legacy_dish_switch;
71#define dprintk(args...) \ 75#define dprintk(args...) \
@@ -383,36 +387,6 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
383 }; 387 };
384} 388}
385 389
386static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
387{
388 return ((curtime.tv_usec < lasttime.tv_usec) ?
389 1000000 - lasttime.tv_usec + curtime.tv_usec :
390 curtime.tv_usec - lasttime.tv_usec);
391}
392
393static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
394{
395 struct timeval lasttime;
396 s32 delta, newdelta;
397
398 waketime->tv_usec += add_usec;
399 if (waketime->tv_usec >= 1000000) {
400 waketime->tv_usec -= 1000000;
401 waketime->tv_sec++;
402 }
403
404 do_gettimeofday (&lasttime);
405 delta = stv0299_calc_usec_delay (lasttime, *waketime);
406 if (delta > 2500) {
407 msleep ((delta - 1500) / 1000);
408 do_gettimeofday (&lasttime);
409 newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
410 delta = (newdelta > delta) ? 0 : newdelta;
411 }
412 if (delta > 0)
413 udelay (delta);
414}
415
416static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) 390static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
417{ 391{
418 struct stv0299_state* state = fe->demodulator_priv; 392 struct stv0299_state* state = fe->demodulator_priv;
@@ -440,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
440 memcpy (&tv[0], &nexttime, sizeof (struct timeval)); 414 memcpy (&tv[0], &nexttime, sizeof (struct timeval));
441 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ 415 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
442 416
443 stv0299_sleep_until (&nexttime, 32000); 417 dvb_frontend_sleep_until(&nexttime, 32000);
444 418
445 for (i=0; i<9; i++) { 419 for (i=0; i<9; i++) {
446 if (debug_legacy_dish_switch) 420 if (debug_legacy_dish_switch)
@@ -454,13 +428,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
454 cmd = cmd >> 1; 428 cmd = cmd >> 1;
455 429
456 if (i != 8) 430 if (i != 8)
457 stv0299_sleep_until (&nexttime, 8000); 431 dvb_frontend_sleep_until(&nexttime, 8000);
458 } 432 }
459 if (debug_legacy_dish_switch) { 433 if (debug_legacy_dish_switch) {
460 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", 434 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
461 __FUNCTION__, fe->dvb->num); 435 __FUNCTION__, fe->dvb->num);
462 for (i=1; i < 10; i++) 436 for (i = 1; i < 10; i++)
463 printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i])); 437 printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
464 } 438 }
465 439
466 return 0; 440 return 0;
@@ -517,8 +491,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
517{ 491{
518 struct stv0299_state* state = fe->demodulator_priv; 492 struct stv0299_state* state = fe->demodulator_priv;
519 493
520 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10); 494 if (state->errmode != STATUS_BER) return 0;
521 msleep(100);
522 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); 495 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
523 496
524 return 0; 497 return 0;
@@ -557,9 +530,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
557{ 530{
558 struct stv0299_state* state = fe->demodulator_priv; 531 struct stv0299_state* state = fe->demodulator_priv;
559 532
560 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30); 533 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
561 msleep(100); 534 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
562 *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
563 535
564 return 0; 536 return 0;
565} 537}
@@ -581,49 +553,14 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
581 if (state->config->invert) invval = (~invval) & 1; 553 if (state->config->invert) invval = (~invval) & 1;
582 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); 554 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
583 555
584 if (state->config->enhanced_tuning) { 556 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
585 /* check if we should do a finetune */ 557 state->config->pll_set(fe, state->i2c, p);
586 int frequency_delta = p->frequency - state->tuner_frequency; 558 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
587 int minmax = p->u.qpsk.symbol_rate / 2000;
588 if (minmax < 5000) minmax = 5000;
589
590 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
591 (state->fec_inner == p->u.qpsk.fec_inner) &&
592 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
593 int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
594
595 // zap the derotator registers first
596 stv0299_writeregI(state, 0x22, 0x00);
597 stv0299_writeregI(state, 0x23, 0x00);
598
599 // now set them as we want
600 stv0299_writeregI(state, 0x22, Drot_freq >> 8);
601 stv0299_writeregI(state, 0x23, Drot_freq);
602 } else {
603 /* A "normal" tune is requested */
604 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
605 state->config->pll_set(fe, state->i2c, p);
606 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
607
608 stv0299_writeregI(state, 0x32, 0x80);
609 stv0299_writeregI(state, 0x22, 0x00);
610 stv0299_writeregI(state, 0x23, 0x00);
611 stv0299_writeregI(state, 0x32, 0x19);
612 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
613 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
614 }
615 } else {
616 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
617 state->config->pll_set(fe, state->i2c, p);
618 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
619 559
620 stv0299_set_FEC (state, p->u.qpsk.fec_inner); 560 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
621 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); 561 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
622 stv0299_writeregI(state, 0x22, 0x00); 562 stv0299_writeregI(state, 0x22, 0x00);
623 stv0299_writeregI(state, 0x23, 0x00); 563 stv0299_writeregI(state, 0x23, 0x00);
624 stv0299_readreg (state, 0x23);
625 stv0299_writeregI(state, 0x12, 0xb9);
626 }
627 564
628 state->tuner_frequency = p->frequency; 565 state->tuner_frequency = p->frequency;
629 state->fec_inner = p->u.qpsk.fec_inner; 566 state->fec_inner = p->u.qpsk.fec_inner;
@@ -708,6 +645,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
708 state->tuner_frequency = 0; 645 state->tuner_frequency = 0;
709 state->symbol_rate = 0; 646 state->symbol_rate = 0;
710 state->fec_inner = 0; 647 state->fec_inner = 0;
648 state->errmode = STATUS_BER;
711 649
712 /* check if the demod is there */ 650 /* check if the demod is there */
713 stv0299_writeregI(state, 0x02, 0x34); /* standby off */ 651 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index d0c4484861e1..9af3d71c89db 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -73,9 +73,6 @@ struct stv0299_config
73 /* does the inversion require inversion? */ 73 /* does the inversion require inversion? */
74 u8 invert:1; 74 u8 invert:1;
75 75
76 /* Should the enhanced tuning code be used? */
77 u8 enhanced_tuning:1;
78
79 /* Skip reinitialisation? */ 76 /* Skip reinitialisation? */
80 u8 skip_reinit:1; 77 u8 skip_reinit:1;
81 78
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 3529c618f828..7968743826fc 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -420,7 +420,7 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
420 struct tda1004x_state* state = fe->demodulator_priv; 420 struct tda1004x_state* state = fe->demodulator_priv;
421 421
422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); 422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10
424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) { 424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); 425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -597,7 +597,10 @@ static int tda10046_init(struct dvb_frontend* fe)
597 // Init the tuner PLL 597 // Init the tuner PLL
598 if (state->config->pll_init) { 598 if (state->config->pll_init) {
599 tda1004x_enable_tuner_i2c(state); 599 tda1004x_enable_tuner_i2c(state);
600 state->config->pll_init(fe); 600 if (state->config->pll_init(fe)) {
601 printk(KERN_ERR "tda1004x: pll init failed\n");
602 return -EIO;
603 }
601 tda1004x_disable_tuner_i2c(state); 604 tda1004x_disable_tuner_i2c(state);
602 } 605 }
603 606
@@ -667,7 +670,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
667 670
668 // set frequency 671 // set frequency
669 tda1004x_enable_tuner_i2c(state); 672 tda1004x_enable_tuner_i2c(state);
670 state->config->pll_set(fe, fe_params); 673 if (state->config->pll_set(fe, fe_params)) {
674 printk(KERN_ERR "tda1004x: pll set failed\n");
675 return -EIO;
676 }
671 tda1004x_disable_tuner_i2c(state); 677 tda1004x_disable_tuner_i2c(state);
672 678
673 // Hardcoded to use auto as much as possible on the TDA10045 as it 679 // Hardcoded to use auto as much as possible on the TDA10045 as it
@@ -832,6 +838,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
832 838
833 case TDA1004X_DEMOD_TDA10046: 839 case TDA1004X_DEMOD_TDA10046:
834 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); 840 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
841 msleep(1);
842 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
835 break; 843 break;
836 } 844 }
837 845
@@ -1129,7 +1137,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1129 if (state->config->pll_sleep != NULL) { 1137 if (state->config->pll_sleep != NULL) {
1130 tda1004x_enable_tuner_i2c(state); 1138 tda1004x_enable_tuner_i2c(state);
1131 state->config->pll_sleep(fe); 1139 state->config->pll_sleep(fe);
1132 tda1004x_disable_tuner_i2c(state); 1140 if (state->config->if_freq != TDA10046_FREQ_052) {
1141 /* special hack for Philips EUROPA Based boards:
1142 * keep the I2c bridge open for tuner access in analog mode
1143 */
1144 tda1004x_disable_tuner_i2c(state);
1145 }
1133 } 1146 }
1134 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1147 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1135 break; 1148 break;
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 85b437bbddcd..bbebd1c4caca 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -286,15 +286,10 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
286 * although one packet has been transfered. 286 * although one packet has been transfered.
287 */ 287 */
288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { 288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
289 unsigned int i = 0, valid; 289 unsigned int i = 0;
290 while (pluto->dma_buf[i] == 0x47) 290 while (pluto->dma_buf[i] == 0x47)
291 i += 188; 291 i += 188;
292 valid = i / 188; 292 nbpackets = i / 188;
293 if (nbpackets != valid) {
294 dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
295 nbpackets, valid);
296 nbpackets = valid;
297 }
298 } 293 }
299 294
300 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); 295 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 22b203f8ff27..87ea52757a21 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1566,7 +1566,7 @@ static u8 alps_bsru6_inittab[] = {
1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1567 0x10, 0x3f, // AGC2 0x3d 1567 0x10, 0x3f, // AGC2 0x3d
1568 0x11, 0x84, 1568 0x11, 0x84,
1569 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1569 0x12, 0xb9,
1570 0x15, 0xc9, // lock detector threshold 1570 0x15, 0xc9, // lock detector threshold
1571 0x16, 0x00, 1571 0x16, 0x00,
1572 0x17, 0x00, 1572 0x17, 0x00,
@@ -1644,7 +1644,6 @@ static struct stv0299_config alps_bsru6_config = {
1644 .inittab = alps_bsru6_inittab, 1644 .inittab = alps_bsru6_inittab,
1645 .mclk = 88000000UL, 1645 .mclk = 88000000UL,
1646 .invert = 1, 1646 .invert = 1,
1647 .enhanced_tuning = 0,
1648 .skip_reinit = 0, 1647 .skip_reinit = 0,
1649 .lock_output = STV0229_LOCKOUTPUT_1, 1648 .lock_output = STV0229_LOCKOUTPUT_1,
1650 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1649 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -1669,7 +1668,7 @@ static u8 alps_bsbe1_inittab[] = {
1669 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1668 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1670 0x10, 0x3f, // AGC2 0x3d 1669 0x10, 0x3f, // AGC2 0x3d
1671 0x11, 0x84, 1670 0x11, 0x84,
1672 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1671 0x12, 0xb9,
1673 0x15, 0xc9, // lock detector threshold 1672 0x15, 0xc9, // lock detector threshold
1674 0x16, 0x00, 1673 0x16, 0x00,
1675 0x17, 0x00, 1674 0x17, 0x00,
@@ -1721,7 +1720,6 @@ static struct stv0299_config alps_bsbe1_config = {
1721 .inittab = alps_bsbe1_inittab, 1720 .inittab = alps_bsbe1_inittab,
1722 .mclk = 88000000UL, 1721 .mclk = 88000000UL,
1723 .invert = 1, 1722 .invert = 1,
1724 .enhanced_tuning = 0,
1725 .skip_reinit = 0, 1723 .skip_reinit = 0,
1726 .min_delay_ms = 100, 1724 .min_delay_ms = 100,
1727 .set_symbol_rate = alps_bsru6_set_symbol_rate, 1725 .set_symbol_rate = alps_bsru6_set_symbol_rate,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 7692cd23f839..aa75dc03a0b3 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -499,7 +499,7 @@ static u8 typhoon_cinergy1200s_inittab[] = {
499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
500 0x10, 0x3f, // AGC2 0x3d 500 0x10, 0x3f, // AGC2 0x3d
501 0x11, 0x84, 501 0x11, 0x84,
502 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 502 0x12, 0xb9,
503 0x15, 0xc9, // lock detector threshold 503 0x15, 0xc9, // lock detector threshold
504 0x16, 0x00, 504 0x16, 0x00,
505 0x17, 0x00, 505 0x17, 0x00,
@@ -531,7 +531,6 @@ static struct stv0299_config typhoon_config = {
531 .inittab = typhoon_cinergy1200s_inittab, 531 .inittab = typhoon_cinergy1200s_inittab,
532 .mclk = 88000000UL, 532 .mclk = 88000000UL,
533 .invert = 0, 533 .invert = 0,
534 .enhanced_tuning = 0,
535 .skip_reinit = 0, 534 .skip_reinit = 0,
536 .lock_output = STV0229_LOCKOUTPUT_1, 535 .lock_output = STV0229_LOCKOUTPUT_1,
537 .volt13_op0_op1 = STV0299_VOLT13_OP0, 536 .volt13_op0_op1 = STV0299_VOLT13_OP0,
@@ -546,7 +545,6 @@ static struct stv0299_config cinergy_1200s_config = {
546 .inittab = typhoon_cinergy1200s_inittab, 545 .inittab = typhoon_cinergy1200s_inittab,
547 .mclk = 88000000UL, 546 .mclk = 88000000UL,
548 .invert = 0, 547 .invert = 0,
549 .enhanced_tuning = 0,
550 .skip_reinit = 0, 548 .skip_reinit = 0,
551 .lock_output = STV0229_LOCKOUTPUT_0, 549 .lock_output = STV0229_LOCKOUTPUT_0,
552 .volt13_op0_op1 = STV0299_VOLT13_OP0, 550 .volt13_op0_op1 = STV0299_VOLT13_OP0,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 51c30ba68140..75fb92d60998 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -490,7 +490,7 @@ static u8 alps_bsru6_inittab[] = {
490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
491 0x10, 0x3f, // AGC2 0x3d 491 0x10, 0x3f, // AGC2 0x3d
492 0x11, 0x84, 492 0x11, 0x84,
493 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 493 0x12, 0xb9,
494 0x15, 0xc9, // lock detector threshold 494 0x15, 0xc9, // lock detector threshold
495 0x16, 0x00, 495 0x16, 0x00,
496 0x17, 0x00, 496 0x17, 0x00,
@@ -580,7 +580,6 @@ static struct stv0299_config alps_bsru6_config = {
580 .inittab = alps_bsru6_inittab, 580 .inittab = alps_bsru6_inittab,
581 .mclk = 88000000UL, 581 .mclk = 88000000UL,
582 .invert = 1, 582 .invert = 1,
583 .enhanced_tuning = 0,
584 .skip_reinit = 0, 583 .skip_reinit = 0,
585 .lock_output = STV0229_LOCKOUTPUT_1, 584 .lock_output = STV0229_LOCKOUTPUT_1,
586 .volt13_op0_op1 = STV0299_VOLT13_OP1, 585 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -710,7 +709,6 @@ static struct stv0299_config philips_su1278_tt_config = {
710 .inittab = philips_su1278_tt_inittab, 709 .inittab = philips_su1278_tt_inittab,
711 .mclk = 64000000UL, 710 .mclk = 64000000UL,
712 .invert = 0, 711 .invert = 0,
713 .enhanced_tuning = 1,
714 .skip_reinit = 1, 712 .skip_reinit = 1,
715 .lock_output = STV0229_LOCKOUTPUT_1, 713 .lock_output = STV0229_LOCKOUTPUT_1,
716 .volt13_op0_op1 = STV0299_VOLT13_OP1, 714 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index b1f21ef0e3b3..755df81cbc49 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -305,7 +305,7 @@ static u8 alps_bsru6_inittab[] = {
305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
306 0x10, 0x3f, // AGC2 0x3d 306 0x10, 0x3f, // AGC2 0x3d
307 0x11, 0x84, 307 0x11, 0x84,
308 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 308 0x12, 0xb9,
309 0x15, 0xc9, // lock detector threshold 309 0x15, 0xc9, // lock detector threshold
310 0x16, 0x00, 310 0x16, 0x00,
311 0x17, 0x00, 311 0x17, 0x00,
@@ -379,7 +379,6 @@ static struct stv0299_config alps_bsru6_config = {
379 .inittab = alps_bsru6_inittab, 379 .inittab = alps_bsru6_inittab,
380 .mclk = 88000000UL, 380 .mclk = 88000000UL,
381 .invert = 1, 381 .invert = 1,
382 .enhanced_tuning = 0,
383 .skip_reinit = 0, 382 .skip_reinit = 0,
384 .lock_output = STV0229_LOCKOUTPUT_1, 383 .lock_output = STV0229_LOCKOUTPUT_1,
385 .volt13_op0_op1 = STV0299_VOLT13_OP1, 384 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 43d6c8268642..4fd8bbc47037 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -226,12 +226,14 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
226 return 0; 226 return 0;
227} 227}
228 228
229static void lnbp21_init(struct budget* budget) 229static int lnbp21_init(struct budget* budget)
230{ 230{
231 u8 buf = 0x00; 231 u8 buf = 0x00;
232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; 232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
233 233
234 i2c_transfer (&budget->i2c_adap, &msg, 1); 234 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
235 return -EIO;
236 return 0;
235} 237}
236 238
237static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 239static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -273,7 +275,7 @@ static u8 alps_bsru6_inittab[] = {
273 0x01, 0x15, 275 0x01, 0x15,
274 0x02, 0x00, 276 0x02, 0x00,
275 0x03, 0x00, 277 0x03, 0x00,
276 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ 278 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
277 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ 279 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
278 0x06, 0x40, /* DAC not used, set to high impendance mode */ 280 0x06, 0x40, /* DAC not used, set to high impendance mode */
279 0x07, 0x00, /* DAC LSB */ 281 0x07, 0x00, /* DAC LSB */
@@ -284,7 +286,7 @@ static u8 alps_bsru6_inittab[] = {
284 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 286 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
285 0x10, 0x3f, // AGC2 0x3d 287 0x10, 0x3f, // AGC2 0x3d
286 0x11, 0x84, 288 0x11, 0x84,
287 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 289 0x12, 0xb9,
288 0x15, 0xc9, // lock detector threshold 290 0x15, 0xc9, // lock detector threshold
289 0x16, 0x00, 291 0x16, 0x00,
290 0x17, 0x00, 292 0x17, 0x00,
@@ -358,7 +360,6 @@ static struct stv0299_config alps_bsru6_config = {
358 .inittab = alps_bsru6_inittab, 360 .inittab = alps_bsru6_inittab,
359 .mclk = 88000000UL, 361 .mclk = 88000000UL,
360 .invert = 1, 362 .invert = 1,
361 .enhanced_tuning = 0,
362 .skip_reinit = 0, 363 .skip_reinit = 0,
363 .lock_output = STV0229_LOCKOUTPUT_1, 364 .lock_output = STV0229_LOCKOUTPUT_1,
364 .volt13_op0_op1 = STV0299_VOLT13_OP1, 365 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -367,6 +368,79 @@ static struct stv0299_config alps_bsru6_config = {
367 .pll_set = alps_bsru6_pll_set, 368 .pll_set = alps_bsru6_pll_set,
368}; 369};
369 370
371static u8 alps_bsbe1_inittab[] = {
372 0x01, 0x15,
373 0x02, 0x30,
374 0x03, 0x00,
375 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
376 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
377 0x06, 0x40, /* DAC not used, set to high impendance mode */
378 0x07, 0x00, /* DAC LSB */
379 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
380 0x09, 0x00, /* FIFO */
381 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
382 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
383 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
384 0x10, 0x3f, // AGC2 0x3d
385 0x11, 0x84,
386 0x12, 0xb9,
387 0x15, 0xc9, // lock detector threshold
388 0x16, 0x00,
389 0x17, 0x00,
390 0x18, 0x00,
391 0x19, 0x00,
392 0x1a, 0x00,
393 0x1f, 0x50,
394 0x20, 0x00,
395 0x21, 0x00,
396 0x22, 0x00,
397 0x23, 0x00,
398 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
399 0x29, 0x1e, // 1/2 threshold
400 0x2a, 0x14, // 2/3 threshold
401 0x2b, 0x0f, // 3/4 threshold
402 0x2c, 0x09, // 5/6 threshold
403 0x2d, 0x05, // 7/8 threshold
404 0x2e, 0x01,
405 0x31, 0x1f, // test all FECs
406 0x32, 0x19, // viterbi and synchro search
407 0x33, 0xfc, // rs control
408 0x34, 0x93, // error control
409 0x0f, 0x92, // 0x80 = inverse AGC
410 0xff, 0xff
411};
412
413static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
414{
415 int ret;
416 u8 data[4];
417 u32 div;
418 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
419
420 if ((params->frequency < 950000) || (params->frequency > 2150000))
421 return -EINVAL;
422
423 div = (params->frequency + (125 - 1)) / 125; // round correctly
424 data[0] = (div >> 8) & 0x7f;
425 data[1] = div & 0xff;
426 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
427 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
428
429 ret = i2c_transfer(i2c, &msg, 1);
430 return (ret != 1) ? -EIO : 0;
431}
432
433static struct stv0299_config alps_bsbe1_config = {
434 .demod_address = 0x68,
435 .inittab = alps_bsbe1_inittab,
436 .mclk = 88000000UL,
437 .invert = 1,
438 .skip_reinit = 0,
439 .min_delay_ms = 100,
440 .set_symbol_rate = alps_bsru6_set_symbol_rate,
441 .pll_set = alps_bsbe1_pll_set,
442};
443
370static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 444static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
371{ 445{
372 struct budget* budget = (struct budget*) fe->dvb->priv; 446 struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -500,6 +574,19 @@ static u8 read_pwm(struct budget* budget)
500static void frontend_init(struct budget *budget) 574static void frontend_init(struct budget *budget)
501{ 575{
502 switch(budget->dev->pci->subsystem_device) { 576 switch(budget->dev->pci->subsystem_device) {
577 case 0x1017:
578 // try the ALPS BSBE1 now
579 budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
580 if (budget->dvb_frontend) {
581 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
582 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
583 if (lnbp21_init(budget)) {
584 printk("%s: No LNBP21 found!\n", __FUNCTION__);
585 goto error_out;
586 }
587 }
588
589 break;
503 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) 590 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
504 case 0x1013: 591 case 0x1013:
505 // try the ALPS BSRV2 first of all 592 // try the ALPS BSRV2 first of all
@@ -554,7 +641,10 @@ static void frontend_init(struct budget *budget)
554 if (budget->dvb_frontend) { 641 if (budget->dvb_frontend) {
555 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; 642 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
556 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 643 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
557 lnbp21_init(budget); 644 if (lnbp21_init(budget)) {
645 printk("%s: No LNBP21 found!\n", __FUNCTION__);
646 goto error_out;
647 }
558 break; 648 break;
559 } 649 }
560 } 650 }
@@ -566,13 +656,17 @@ static void frontend_init(struct budget *budget)
566 budget->dev->pci->subsystem_vendor, 656 budget->dev->pci->subsystem_vendor,
567 budget->dev->pci->subsystem_device); 657 budget->dev->pci->subsystem_device);
568 } else { 658 } else {
569 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { 659 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
570 printk("budget: Frontend registration failed!\n"); 660 goto error_out;
571 if (budget->dvb_frontend->ops->release)
572 budget->dvb_frontend->ops->release(budget->dvb_frontend);
573 budget->dvb_frontend = NULL;
574 }
575 } 661 }
662 return;
663
664error_out:
665 printk("budget: Frontend registration failed!\n");
666 if (budget->dvb_frontend->ops->release)
667 budget->dvb_frontend->ops->release(budget->dvb_frontend);
668 budget->dvb_frontend = NULL;
669 return;
576} 670}
577 671
578static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) 672static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
@@ -618,6 +712,7 @@ static int budget_detach (struct saa7146_dev* dev)
618 712
619static struct saa7146_extension budget_extension; 713static struct saa7146_extension budget_extension;
620 714
715MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
621MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); 716MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
622MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); 717MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
623MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 718MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
@@ -630,6 +725,7 @@ static struct pci_device_id pci_tbl[] = {
630 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), 725 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
631 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), 726 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
632 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 727 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
728 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
633 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), 729 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
634 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 730 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
635 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 731 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index d200ab0ad9e7..fd53d6010502 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -1198,7 +1198,7 @@ static u8 alps_bsbe1_inittab[] = {
1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1199 0x10, 0x3f, // AGC2 0x3d 1199 0x10, 0x3f, // AGC2 0x3d
1200 0x11, 0x84, 1200 0x11, 0x84,
1201 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1201 0x12, 0xb9,
1202 0x15, 0xc9, // lock detector threshold 1202 0x15, 0xc9, // lock detector threshold
1203 0x16, 0x00, 1203 0x16, 0x00,
1204 0x17, 0x00, 1204 0x17, 0x00,
@@ -1240,7 +1240,7 @@ static u8 alps_bsru6_inittab[] = {
1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1241 0x10, 0x3f, // AGC2 0x3d 1241 0x10, 0x3f, // AGC2 0x3d
1242 0x11, 0x84, 1242 0x11, 0x84,
1243 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1243 0x12, 0xb9,
1244 0x15, 0xc9, // lock detector threshold 1244 0x15, 0xc9, // lock detector threshold
1245 0x16, 0x00, 1245 0x16, 0x00,
1246 0x17, 0x00, 1246 0x17, 0x00,
@@ -1335,7 +1335,6 @@ static struct stv0299_config alps_stv0299_config = {
1335 .inittab = alps_bsru6_inittab, 1335 .inittab = alps_bsru6_inittab,
1336 .mclk = 88000000UL, 1336 .mclk = 88000000UL,
1337 .invert = 1, 1337 .invert = 1,
1338 .enhanced_tuning = 0,
1339 .skip_reinit = 0, 1338 .skip_reinit = 0,
1340 .lock_output = STV0229_LOCKOUTPUT_1, 1339 .lock_output = STV0229_LOCKOUTPUT_1,
1341 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1340 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bbb989df4cf0..199b01188858 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -25,6 +25,16 @@ config VIDEO_BT848
25 To compile this driver as a module, choose M here: the 25 To compile this driver as a module, choose M here: the
26 module will be called bttv. 26 module will be called bttv.
27 27
28config VIDEO_BT848_DVB
29 tristate "DVB/ATSC Support for bt878 based TV cards"
30 depends on VIDEO_BT848 && DVB_CORE
31 select DVB_BT8XX
32 ---help---
33 This adds support for DVB/ATSC cards based on the BT878 chip.
34
35 To compile this driver as a module, choose M here: the
36 module will be called dvb-bt8xx.
37
28config VIDEO_SAA6588 38config VIDEO_SAA6588
29 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" 39 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
30 depends on VIDEO_DEV && I2C && VIDEO_BT848 40 depends on VIDEO_DEV && I2C && VIDEO_BT848
@@ -243,29 +253,7 @@ config VIDEO_MEYE
243 To compile this driver as a module, choose M here: the 253 To compile this driver as a module, choose M here: the
244 module will be called meye. 254 module will be called meye.
245 255
246config VIDEO_SAA7134 256source "drivers/media/video/saa7134/Kconfig"
247 tristate "Philips SAA7134 support"
248 depends on VIDEO_DEV && PCI && I2C && SOUND
249 select VIDEO_BUF
250 select VIDEO_IR
251 select VIDEO_TUNER
252 select CRC32
253 ---help---
254 This is a video4linux driver for Philips SAA7130/7134 based
255 TV cards.
256
257 To compile this driver as a module, choose M here: the
258 module will be called saa7134.
259
260config VIDEO_SAA7134_DVB
261 tristate "DVB Support for saa7134 based TV cards"
262 depends on VIDEO_SAA7134 && DVB_CORE
263 select VIDEO_BUF_DVB
264 select DVB_MT352
265 select DVB_TDA1004X
266 ---help---
267 This adds support for DVB cards based on the
268 Philips saa7134 chip.
269 257
270config VIDEO_MXB 258config VIDEO_MXB
271 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" 259 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
@@ -316,34 +304,9 @@ config VIDEO_HEXIUM_GEMINI
316 To compile this driver as a module, choose M here: the 304 To compile this driver as a module, choose M here: the
317 module will be called hexium_gemini. 305 module will be called hexium_gemini.
318 306
319config VIDEO_CX88 307source "drivers/media/video/cx88/Kconfig"
320 tristate "Conexant 2388x (bt878 successor) support"
321 depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
322 select I2C_ALGOBIT
323 select FW_LOADER
324 select VIDEO_BTCX
325 select VIDEO_BUF
326 select VIDEO_TUNER
327 select VIDEO_TVEEPROM
328 select VIDEO_IR
329 ---help---
330 This is a video4linux driver for Conexant 2388x based
331 TV cards.
332 308
333 To compile this driver as a module, choose M here: the 309source "drivers/media/video/em28xx/Kconfig"
334 module will be called cx8800
335
336config VIDEO_CX88_DVB
337 tristate "DVB Support for cx2388x based TV cards"
338 depends on VIDEO_CX88 && DVB_CORE
339 select VIDEO_BUF_DVB
340 select DVB_MT352
341 select DVB_OR51132
342 select DVB_CX22702
343 select DVB_LGDT330X
344 ---help---
345 This adds support for DVB/ATSC cards based on the
346 Connexant 2388x chip.
347 310
348config VIDEO_OVCAMCHIP 311config VIDEO_OVCAMCHIP
349 tristate "OmniVision Camera Chip support" 312 tristate "OmniVision Camera Chip support"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 046b82de9285..3ac465992400 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,7 +5,6 @@
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ 5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o 6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o 7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
8rds-objs := saa6588.o
9zr36067-objs := zoran_procfs.o zoran_device.o \ 8zr36067-objs := zoran_procfs.o zoran_device.o \
10 zoran_driver.o zoran_card.o 9 zoran_driver.o zoran_card.o
11tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o 10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
@@ -16,7 +15,7 @@ obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
16obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o 15obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
17 16
18obj-$(CONFIG_VIDEO_ZR36120) += zoran.o 17obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
19obj-$(CONFIG_VIDEO_SAA6588) += rds.o 18obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
20obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o 19obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
21obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o 20obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
22obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o 21obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
@@ -39,6 +38,8 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
39obj-$(CONFIG_VIDEO_MEYE) += meye.o 38obj-$(CONFIG_VIDEO_MEYE) += meye.o
40obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ 39obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
41obj-$(CONFIG_VIDEO_CX88) += cx88/ 40obj-$(CONFIG_VIDEO_CX88) += cx88/
41obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
42obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
42obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ 43obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
43obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o 44obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
44obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o 45obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 0823ddaf7004..881cdcb1875d 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/devfs_fs_kernel.h> 23#include <linux/devfs_fs_kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/version.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/fs.h> 27#include <linux/fs.h>
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 76c1b63ebdf2..e4063950ae57 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -32,7 +32,6 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36#include "bttv.h" 35#include "bttv.h"
37#include "bt832.h" 36#include "bt832.h"
38 37
@@ -54,36 +53,36 @@ static struct i2c_driver driver;
54static struct i2c_client client_template; 53static struct i2c_client client_template;
55 54
56struct bt832 { 55struct bt832 {
57 struct i2c_client client; 56 struct i2c_client client;
58}; 57};
59 58
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) 59int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{ 60{
62 int i,rc; 61 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment 62 buf[0]=0x80; // start at register 0 with auto-increment
64 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) 63 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
65 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); 64 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
66 65
67 for(i=0;i<65;i++) 66 for(i=0;i<65;i++)
68 buf[i]=0; 67 buf[i]=0;
69 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) 68 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
70 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); 69 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
71 70
72 // Note: On READ the first byte is the current index 71 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote) 72 // (e.g. 0x80, what we just wrote)
74 73
75 if(1) { 74 if(1) {
76 int i; 75 int i;
77 printk("BT832 hexdump:\n"); 76 printk("BT832 hexdump:\n");
78 for(i=1;i<65;i++) { 77 for(i=1;i<65;i++) {
79 if(i!=1) { 78 if(i!=1) {
80 if(((i-1)%8)==0) printk(" "); 79 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) printk("\n"); 80 if(((i-1)%16)==0) printk("\n");
82 } 81 }
83 printk(" %02x",buf[i]); 82 printk(" %02x",buf[i]);
84 } 83 }
85 printk("\n"); 84 printk("\n");
86 } 85 }
87 return 0; 86 return 0;
88} 87}
89 88
@@ -102,13 +101,13 @@ int bt832_init(struct i2c_client *i2c_client_s)
102 return 0; 101 return 0;
103 } 102 }
104 103
105 printk("Write 0 tp VPSTATUS\n"); 104 printk("Write 0 tp VPSTATUS\n");
106 buf[0]=BT832_VP_STATUS; // Reg.52 105 buf[0]=BT832_VP_STATUS; // Reg.52
107 buf[1]= 0x00; 106 buf[1]= 0x00;
108 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 107 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
109 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 108 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
110 109
111 bt832_hexdump(i2c_client_s,buf); 110 bt832_hexdump(i2c_client_s,buf);
112 111
113 112
114 // Leave low power mode: 113 // Leave low power mode:
@@ -116,17 +115,17 @@ int bt832_init(struct i2c_client *i2c_client_s)
116 buf[0]=BT832_CAM_SETUP0; //0x39 57 115 buf[0]=BT832_CAM_SETUP0; //0x39 57
117 buf[1]=0x08; 116 buf[1]=0x08;
118 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 117 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
119 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); 118 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
120 119
121 bt832_hexdump(i2c_client_s,buf); 120 bt832_hexdump(i2c_client_s,buf);
122 121
123 printk("Write 0 tp VPSTATUS\n"); 122 printk("Write 0 tp VPSTATUS\n");
124 buf[0]=BT832_VP_STATUS; // Reg.52 123 buf[0]=BT832_VP_STATUS; // Reg.52
125 buf[1]= 0x00; 124 buf[1]= 0x00;
126 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 125 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
127 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 126 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
128 127
129 bt832_hexdump(i2c_client_s,buf); 128 bt832_hexdump(i2c_client_s,buf);
130 129
131 130
132 // Enable Output 131 // Enable Output
@@ -134,22 +133,22 @@ int bt832_init(struct i2c_client *i2c_client_s)
134 buf[0]=BT832_VP_CONTROL1; // Reg.40 133 buf[0]=BT832_VP_CONTROL1; // Reg.40
135 buf[1]= 0x27 & (~0x01); // Default | !skip 134 buf[1]= 0x27 & (~0x01); // Default | !skip
136 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 135 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
137 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); 136 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
138 137
139 bt832_hexdump(i2c_client_s,buf); 138 bt832_hexdump(i2c_client_s,buf);
140 139
141 140
142 // for testing (even works when no camera attached) 141 // for testing (even works when no camera attached)
143 printk("bt832: *** Generate NTSC M Bars *****\n"); 142 printk("bt832: *** Generate NTSC M Bars *****\n");
144 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 143 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
145 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally 144 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
146 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 145 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
147 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); 146 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
148 147
149 printk("Bt832: Camera Present: %s\n", 148 printk("Bt832: Camera Present: %s\n",
150 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); 149 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
151 150
152 bt832_hexdump(i2c_client_s,buf); 151 bt832_hexdump(i2c_client_s,buf);
153 kfree(buf); 152 kfree(buf);
154 return 1; 153 return 1;
155} 154}
@@ -162,17 +161,17 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
162 161
163 printk("bt832_attach\n"); 162 printk("bt832_attach\n");
164 163
165 client_template.adapter = adap; 164 client_template.adapter = adap;
166 client_template.addr = addr; 165 client_template.addr = addr;
167 166
168 printk("bt832: chip found @ 0x%x\n", addr<<1); 167 printk("bt832: chip found @ 0x%x\n", addr<<1);
169 168
170 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 169 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
171 return -ENOMEM; 170 return -ENOMEM;
172 memset(t,0,sizeof(*t)); 171 memset(t,0,sizeof(*t));
173 t->client = client_template; 172 t->client = client_template;
174 i2c_set_clientdata(&t->client, t); 173 i2c_set_clientdata(&t->client, t);
175 i2c_attach_client(&t->client); 174 i2c_attach_client(&t->client);
176 175
177 if(! bt832_init(&t->client)) { 176 if(! bt832_init(&t->client)) {
178 bt832_detach(&t->client); 177 bt832_detach(&t->client);
@@ -211,7 +210,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
211 210
212 printk("bt832: command %x\n",cmd); 211 printk("bt832: command %x\n",cmd);
213 212
214 switch (cmd) { 213 switch (cmd) {
215 case BT832_HEXDUMP: { 214 case BT832_HEXDUMP: {
216 unsigned char *buf; 215 unsigned char *buf;
217 buf=kmalloc(65,GFP_KERNEL); 216 buf=kmalloc(65,GFP_KERNEL);
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
index 9b6a8d2c96b5..1ce8fa71f7db 100644
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -233,8 +233,8 @@ SetInterlaceMode( spec.interlace );
233/* from web: 233/* from web:
234 Video Sampling 234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are: 235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert 236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active 237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525 238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525 239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525 240NTSC 4FSc 14.32 MHz 910 768 525
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 0881a17d5226..3413bace443a 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -6,7 +6,7 @@
6 like the big tvcards array for the most part 6 like the big tvcards array for the most part
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
@@ -145,162 +145,163 @@ static struct CARD {
145 int cardnr; 145 int cardnr;
146 char *name; 146 char *name;
147} cards[] __devinitdata = { 147} cards[] __devinitdata = {
148 { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" }, 148 { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" },
149 { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" }, 149 { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" },
150 { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" }, 150 { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
151 { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" }, 151 { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" },
152 { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" }, 152 { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" },
153 { 0xff020070, BTTV_OSPREY500, "Osprey-500" }, 153 { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" },
154 { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" }, 154 { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" },
155 { 0xff040070, BTTV_OSPREY540, "Osprey-540" }, 155 { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" },
156 156 { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" },
157 { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" }, 157
158 { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, 158 { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" },
159 159 { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
160 { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 160
161 { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" }, 161 { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
162 { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" }, 162 { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" },
163 { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 163 { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" },
164 { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 164 { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
165 { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, 165 { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
166 { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, 166 { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
167 { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 167 { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
168 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 168 { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
169 169 { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
170 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 170
171 { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
171 /* some cards ship with byteswapped IDs ... */ 172 /* some cards ship with byteswapped IDs ... */
172 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 173 { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
173 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 174 { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
174 /* this seems to happen as well ... */ 175 /* this seems to happen as well ... */
175 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 176 { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
176 177
177 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 178 { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
178 { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 179 { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
179 { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, 180 { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" },
180 181
181 { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, 182 { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
182 { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" }, 183 { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" },
183 { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, 184 { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
184 { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, 185 { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
185 { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" }, 186 { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" },
186 { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" }, 187 { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" },
187 { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, 188 { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
188 189
189 { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 190 { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
190 { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" }, 191 { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" },
191 { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 192 { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
192 { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" }, 193 { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" },
193 { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, 194 { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
194 195
195 { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, 196 { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
196 { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, 197 { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
197 { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, 198 { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
198 { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, 199 { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
199 200
200 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" }, 201 { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" },
201 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" }, 202 { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" },
202 /* clashes with FlyVideo 203 /* clashes with FlyVideo
203 *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */ 204 *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */
204 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" }, 205 { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" },
205 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */ 206 { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
206 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */ 207 { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */
207 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */ 208 { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
208 209
209 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 210 { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
210 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 211 { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
211 { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 212 { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
212 { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 213 { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
213 { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 214 { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
214 215
215 { 0x1430aa00, BTTV_PV143, "Provideo PV143A" }, 216 { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" },
216 { 0x1431aa00, BTTV_PV143, "Provideo PV143B" }, 217 { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" },
217 { 0x1432aa00, BTTV_PV143, "Provideo PV143C" }, 218 { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" },
218 { 0x1433aa00, BTTV_PV143, "Provideo PV143D" }, 219 { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" },
219 { 0x1433aa03, BTTV_PV143, "Security Eyes" }, 220 { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" },
220 221
221 { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" }, 222 { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" },
222 { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" }, 223 { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" },
223 { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" }, 224 { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" },
224 { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" }, 225 { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" },
225 226
226 { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" }, 227 { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" },
227 { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" }, 228 { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" },
228 { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" }, 229 { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" },
229 { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" }, 230 { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" },
230 231
231 { 0xa132ff00, BTTV_IVC100, "IVC-100" }, 232 { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" },
232 { 0xa1550000, BTTV_IVC200, "IVC-200" }, 233 { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" },
233 { 0xa1550001, BTTV_IVC200, "IVC-200" }, 234 { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" },
234 { 0xa1550002, BTTV_IVC200, "IVC-200" }, 235 { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" },
235 { 0xa1550003, BTTV_IVC200, "IVC-200" }, 236 { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" },
236 { 0xa1550100, BTTV_IVC200, "IVC-200G" }, 237 { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" },
237 { 0xa1550101, BTTV_IVC200, "IVC-200G" }, 238 { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
238 { 0xa1550102, BTTV_IVC200, "IVC-200G" }, 239 { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
239 { 0xa1550103, BTTV_IVC200, "IVC-200G" }, 240 { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
240 { 0xa182ff00, BTTV_IVC120, "IVC-120G" }, 241 { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
241 { 0xa182ff01, BTTV_IVC120, "IVC-120G" }, 242 { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
242 { 0xa182ff02, BTTV_IVC120, "IVC-120G" }, 243 { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
243 { 0xa182ff03, BTTV_IVC120, "IVC-120G" }, 244 { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" },
244 { 0xa182ff04, BTTV_IVC120, "IVC-120G" }, 245 { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" },
245 { 0xa182ff05, BTTV_IVC120, "IVC-120G" }, 246 { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" },
246 { 0xa182ff06, BTTV_IVC120, "IVC-120G" }, 247 { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" },
247 { 0xa182ff07, BTTV_IVC120, "IVC-120G" }, 248 { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" },
248 { 0xa182ff08, BTTV_IVC120, "IVC-120G" }, 249 { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" },
249 { 0xa182ff09, BTTV_IVC120, "IVC-120G" }, 250 { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" },
250 { 0xa182ff0a, BTTV_IVC120, "IVC-120G" }, 251 { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" },
251 { 0xa182ff0b, BTTV_IVC120, "IVC-120G" }, 252 { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" },
252 { 0xa182ff0c, BTTV_IVC120, "IVC-120G" }, 253 { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" },
253 { 0xa182ff0d, BTTV_IVC120, "IVC-120G" }, 254 { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
254 { 0xa182ff0e, BTTV_IVC120, "IVC-120G" }, 255 { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
255 { 0xa182ff0f, BTTV_IVC120, "IVC-120G" }, 256 { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
256 257
257 { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, 258 { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
258 { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, 259 { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
259 260
260 { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 261 { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
261 { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 262 { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
262 { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, 263 { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
263 { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, 264 { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
264 { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, 265 { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
265 { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" }, 266 { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
266 267
267 { 0x010115cb, BTTV_GMV1, "AG GMV1" }, 268 { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
268 { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, 269 { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
269 270
270 { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" }, 271 { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
271 { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 272 { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
272 { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 273 { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
273 { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" }, 274 { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" },
274 { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" }, 275 { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" },
275 { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" }, 276 { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" },
276 { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"}, 277 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
277 { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" }, 278 { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
278 { 0x146caa0c, BTTV_PV951, "ituner spectra8" }, 279 { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" },
279 { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" }, 280 { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" },
280 281
281 { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, 282 { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
282 { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" }, 283 { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" },
283 284
284 { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, 285 { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
285 { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, 286 { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
286 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, 287 { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
287 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, 288 { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
288 289
289 { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" }, 290 { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
290 291
291 /* likely broken, vendor id doesn't match the other magic views ... 292 /* likely broken, vendor id doesn't match the other magic views ...
292 * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ 293 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
293 294
294 /* DVB cards (using pci function .1 for mpeg data xfer) */ 295 /* DVB cards (using pci function .1 for mpeg data xfer) */
295 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, 296 { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
296 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, 297 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
297 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, 298 { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
298 { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, 299 { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
299 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" }, 300 { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
300 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, 301 { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
301 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, 302 { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
302 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, 303 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
303 { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, 304 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
304 305
305 { 0, -1, NULL } 306 { 0, -1, NULL }
306}; 307};
@@ -309,2116 +310,2494 @@ static struct CARD {
309/* array with description for bt848 / bt878 tv/grabber cards */ 310/* array with description for bt848 / bt878 tv/grabber cards */
310 311
311struct tvcard bttv_tvcards[] = { 312struct tvcard bttv_tvcards[] = {
312{ 313 /* ---- card 0x00 ---------------------------------- */
313/* ---- card 0x00 ---------------------------------- */ 314 [BTTV_BOARD_UNKNOWN] = {
314 .name = " *** UNKNOWN/GENERIC *** ", 315 .name = " *** UNKNOWN/GENERIC *** ",
315 .video_inputs = 4, 316 .video_inputs = 4,
316 .audio_inputs = 1, 317 .audio_inputs = 1,
317 .tuner = 0, 318 .tuner = 0,
318 .svhs = 2, 319 .svhs = 2,
319 .muxsel = { 2, 3, 1, 0}, 320 .muxsel = { 2, 3, 1, 0},
320 .tuner_type = -1, 321 .tuner_type = -1,
321 .tuner_addr = ADDR_UNSET, 322 .tuner_addr = ADDR_UNSET,
322},{ 323 .radio_addr = ADDR_UNSET,
323 .name = "MIRO PCTV", 324 },
324 .video_inputs = 4, 325 [BTTV_BOARD_MIRO] = {
325 .audio_inputs = 1, 326 .name = "MIRO PCTV",
326 .tuner = 0, 327 .video_inputs = 4,
327 .svhs = 2, 328 .audio_inputs = 1,
328 .gpiomask = 15, 329 .tuner = 0,
329 .muxsel = { 2, 3, 1, 1}, 330 .svhs = 2,
330 .audiomux = { 2, 0, 0, 0, 10}, 331 .gpiomask = 15,
331 .needs_tvaudio = 1, 332 .muxsel = { 2, 3, 1, 1},
332 .tuner_type = -1, 333 .audiomux = { 2, 0, 0, 0, 10},
333 .tuner_addr = ADDR_UNSET, 334 .needs_tvaudio = 1,
334},{ 335 .tuner_type = -1,
335 .name = "Hauppauge (bt848)", 336 .tuner_addr = ADDR_UNSET,
336 .video_inputs = 4, 337 .radio_addr = ADDR_UNSET,
337 .audio_inputs = 1, 338 },
338 .tuner = 0, 339 [BTTV_BOARD_HAUPPAUGE] = {
339 .svhs = 2, 340 .name = "Hauppauge (bt848)",
340 .gpiomask = 7, 341 .video_inputs = 4,
341 .muxsel = { 2, 3, 1, 1}, 342 .audio_inputs = 1,
342 .audiomux = { 0, 1, 2, 3, 4}, 343 .tuner = 0,
343 .needs_tvaudio = 1, 344 .svhs = 2,
344 .tuner_type = -1, 345 .gpiomask = 7,
345 .tuner_addr = ADDR_UNSET, 346 .muxsel = { 2, 3, 1, 1},
346},{ 347 .audiomux = { 0, 1, 2, 3, 4},
347 .name = "STB, Gateway P/N 6000699 (bt848)", 348 .needs_tvaudio = 1,
348 .video_inputs = 3, 349 .tuner_type = -1,
349 .audio_inputs = 1, 350 .tuner_addr = ADDR_UNSET,
350 .tuner = 0, 351 .radio_addr = ADDR_UNSET,
351 .svhs = 2, 352 },
352 .gpiomask = 7, 353 [BTTV_BOARD_STB] = {
353 .muxsel = { 2, 3, 1, 1}, 354 .name = "STB, Gateway P/N 6000699 (bt848)",
354 .audiomux = { 4, 0, 2, 3, 1}, 355 .video_inputs = 3,
355 .no_msp34xx = 1, 356 .audio_inputs = 1,
356 .needs_tvaudio = 1, 357 .tuner = 0,
357 .tuner_type = TUNER_PHILIPS_NTSC, 358 .svhs = 2,
358 .tuner_addr = ADDR_UNSET, 359 .gpiomask = 7,
359 .pll = PLL_28, 360 .muxsel = { 2, 3, 1, 1},
360 .has_radio = 1, 361 .audiomux = { 4, 0, 2, 3, 1},
361},{ 362 .no_msp34xx = 1,
362 363 .needs_tvaudio = 1,
363/* ---- card 0x04 ---------------------------------- */ 364 .tuner_type = TUNER_PHILIPS_NTSC,
364 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 365 .tuner_addr = ADDR_UNSET,
365 .video_inputs = 4, 366 .radio_addr = ADDR_UNSET,
366 .audio_inputs = 0, 367 .pll = PLL_28,
367 .tuner = -1, 368 .has_radio = 1,
368 .svhs = 2, 369 },
369 .gpiomask = 0, 370
370 .muxsel = { 2, 3, 1, 1}, 371 /* ---- card 0x04 ---------------------------------- */
371 .audiomux = { 0 }, 372 [BTTV_BOARD_INTEL] = {
372 .needs_tvaudio = 0, 373 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
373 .tuner_type = 4, 374 .video_inputs = 4,
374 .tuner_addr = ADDR_UNSET, 375 .audio_inputs = 0,
375},{ 376 .tuner = -1,
376 .name = "Diamond DTV2000", 377 .svhs = 2,
377 .video_inputs = 4, 378 .gpiomask = 0,
378 .audio_inputs = 1, 379 .muxsel = { 2, 3, 1, 1},
379 .tuner = 0, 380 .audiomux = { 0 },
380 .svhs = 2, 381 .needs_tvaudio = 0,
381 .gpiomask = 3, 382 .tuner_type = 4,
382 .muxsel = { 2, 3, 1, 0}, 383 .tuner_addr = ADDR_UNSET,
383 .audiomux = { 0, 1, 0, 1, 3}, 384 .radio_addr = ADDR_UNSET,
384 .needs_tvaudio = 1, 385 },
385 .tuner_type = -1, 386 [BTTV_BOARD_DIAMOND] = {
386 .tuner_addr = ADDR_UNSET, 387 .name = "Diamond DTV2000",
387},{ 388 .video_inputs = 4,
388 .name = "AVerMedia TVPhone", 389 .audio_inputs = 1,
389 .video_inputs = 3, 390 .tuner = 0,
390 .audio_inputs = 1, 391 .svhs = 2,
391 .tuner = 0, 392 .gpiomask = 3,
392 .svhs = 3, 393 .muxsel = { 2, 3, 1, 0},
393 .muxsel = { 2, 3, 1, 1}, 394 .audiomux = { 0, 1, 0, 1, 3},
394 .gpiomask = 0x0f, 395 .needs_tvaudio = 1,
395 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0}, 396 .tuner_type = -1,
396 /* 0x04 for some cards ?? */ 397 .tuner_addr = ADDR_UNSET,
397 .needs_tvaudio = 1, 398 .radio_addr = ADDR_UNSET,
398 .tuner_type = -1, 399 },
399 .tuner_addr = ADDR_UNSET, 400 [BTTV_BOARD_AVERMEDIA] = {
400 .audio_hook = avermedia_tvphone_audio, 401 .name = "AVerMedia TVPhone",
401 .has_remote = 1, 402 .video_inputs = 3,
402},{ 403 .audio_inputs = 1,
403 .name = "MATRIX-Vision MV-Delta", 404 .tuner = 0,
404 .video_inputs = 5, 405 .svhs = 3,
405 .audio_inputs = 1, 406 .muxsel = { 2, 3, 1, 1},
406 .tuner = -1, 407 .gpiomask = 0x0f,
407 .svhs = 3, 408 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
408 .gpiomask = 0, 409 /* 0x04 for some cards ?? */
409 .muxsel = { 2, 3, 1, 0, 0}, 410 .needs_tvaudio = 1,
410 .audiomux = {0 }, 411 .tuner_type = -1,
411 .needs_tvaudio = 1, 412 .tuner_addr = ADDR_UNSET,
412 .tuner_type = -1, 413 .radio_addr = ADDR_UNSET,
413 .tuner_addr = ADDR_UNSET, 414 .audio_hook = avermedia_tvphone_audio,
414},{ 415 .has_remote = 1,
415 416 },
416/* ---- card 0x08 ---------------------------------- */ 417 [BTTV_BOARD_MATRIX_VISION] = {
417 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", 418 .name = "MATRIX-Vision MV-Delta",
418 .video_inputs = 4, 419 .video_inputs = 5,
419 .audio_inputs = 1, 420 .audio_inputs = 1,
420 .tuner = 0, 421 .tuner = -1,
421 .svhs = 2, 422 .svhs = 3,
422 .gpiomask = 0xc00, 423 .gpiomask = 0,
423 .muxsel = { 2, 3, 1, 1}, 424 .muxsel = { 2, 3, 1, 0, 0},
424 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, 425 .audiomux = {0 },
425 .needs_tvaudio = 1, 426 .needs_tvaudio = 1,
426 .pll = PLL_28, 427 .tuner_type = -1,
427 .tuner_type = -1, 428 .tuner_addr = ADDR_UNSET,
428 .tuner_addr = ADDR_UNSET, 429 .radio_addr = ADDR_UNSET,
429},{ 430 },
430 .name = "IMS/IXmicro TurboTV", 431
431 .video_inputs = 3, 432 /* ---- card 0x08 ---------------------------------- */
432 .audio_inputs = 1, 433 [BTTV_BOARD_FLYVIDEO] = {
433 .tuner = 0, 434 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
434 .svhs = 2, 435 .video_inputs = 4,
435 .gpiomask = 3, 436 .audio_inputs = 1,
436 .muxsel = { 2, 3, 1, 1}, 437 .tuner = 0,
437 .audiomux = { 1, 1, 2, 3, 0}, 438 .svhs = 2,
438 .needs_tvaudio = 0, 439 .gpiomask = 0xc00,
439 .pll = PLL_28, 440 .muxsel = { 2, 3, 1, 1},
440 .tuner_type = TUNER_TEMIC_PAL, 441 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
441 .tuner_addr = ADDR_UNSET, 442 .needs_tvaudio = 1,
442},{ 443 .pll = PLL_28,
443 .name = "Hauppauge (bt878)", 444 .tuner_type = -1,
444 .video_inputs = 4, 445 .tuner_addr = ADDR_UNSET,
445 .audio_inputs = 1, 446 .radio_addr = ADDR_UNSET,
446 .tuner = 0, 447 },
447 .svhs = 2, 448 [BTTV_BOARD_TURBOTV] = {
448 .gpiomask = 0x0f, /* old: 7 */ 449 .name = "IMS/IXmicro TurboTV",
449 .muxsel = { 2, 0, 1, 1}, 450 .video_inputs = 3,
450 .audiomux = { 0, 1, 2, 3, 4}, 451 .audio_inputs = 1,
451 .needs_tvaudio = 1, 452 .tuner = 0,
452 .pll = PLL_28, 453 .svhs = 2,
453 .tuner_type = -1, 454 .gpiomask = 3,
454 .tuner_addr = ADDR_UNSET, 455 .muxsel = { 2, 3, 1, 1},
455},{ 456 .audiomux = { 1, 1, 2, 3, 0},
456 .name = "MIRO PCTV pro", 457 .needs_tvaudio = 0,
457 .video_inputs = 3, 458 .pll = PLL_28,
458 .audio_inputs = 1, 459 .tuner_type = TUNER_TEMIC_PAL,
459 .tuner = 0, 460 .tuner_addr = ADDR_UNSET,
460 .svhs = 2, 461 .radio_addr = ADDR_UNSET,
461 .gpiomask = 0x3014f, 462 },
462 .muxsel = { 2, 3, 1, 1}, 463 [BTTV_BOARD_HAUPPAUGE878] = {
463 .audiomux = { 0x20001,0x10001, 0, 0,10}, 464 .name = "Hauppauge (bt878)",
464 .needs_tvaudio = 1, 465 .video_inputs = 4,
465 .tuner_type = -1, 466 .audio_inputs = 1,
466 .tuner_addr = ADDR_UNSET, 467 .tuner = 0,
467},{ 468 .svhs = 2,
468 469 .gpiomask = 0x0f, /* old: 7 */
469/* ---- card 0x0c ---------------------------------- */ 470 .muxsel = { 2, 0, 1, 1},
470 .name = "ADS Technologies Channel Surfer TV (bt848)", 471 .audiomux = { 0, 1, 2, 3, 4},
471 .video_inputs = 3, 472 .needs_tvaudio = 1,
472 .audio_inputs = 1, 473 .pll = PLL_28,
473 .tuner = 0, 474 .tuner_type = -1,
474 .svhs = 2, 475 .tuner_addr = ADDR_UNSET,
475 .gpiomask = 15, 476 .radio_addr = ADDR_UNSET,
476 .muxsel = { 2, 3, 1, 1}, 477 },
477 .audiomux = { 13, 14, 11, 7, 0, 0}, 478 [BTTV_BOARD_MIROPRO] = {
478 .needs_tvaudio = 1, 479 .name = "MIRO PCTV pro",
479 .tuner_type = -1, 480 .video_inputs = 3,
480 .tuner_addr = ADDR_UNSET, 481 .audio_inputs = 1,
481},{ 482 .tuner = 0,
482 .name = "AVerMedia TVCapture 98", 483 .svhs = 2,
483 .video_inputs = 3, 484 .gpiomask = 0x3014f,
484 .audio_inputs = 4, 485 .muxsel = { 2, 3, 1, 1},
485 .tuner = 0, 486 .audiomux = { 0x20001,0x10001, 0, 0,10},
486 .svhs = 2, 487 .needs_tvaudio = 1,
487 .gpiomask = 15, 488 .tuner_type = -1,
488 .muxsel = { 2, 3, 1, 1}, 489 .tuner_addr = ADDR_UNSET,
489 .audiomux = { 13, 14, 11, 7, 0, 0}, 490 .radio_addr = ADDR_UNSET,
490 .needs_tvaudio = 1, 491 },
491 .msp34xx_alt = 1, 492
492 .pll = PLL_28, 493 /* ---- card 0x0c ---------------------------------- */
493 .tuner_type = TUNER_PHILIPS_PAL, 494 [BTTV_BOARD_ADSTECH_TV] = {
494 .tuner_addr = ADDR_UNSET, 495 .name = "ADS Technologies Channel Surfer TV (bt848)",
495 .audio_hook = avermedia_tv_stereo_audio, 496 .video_inputs = 3,
496},{ 497 .audio_inputs = 1,
497 .name = "Aimslab Video Highway Xtreme (VHX)", 498 .tuner = 0,
498 .video_inputs = 3, 499 .svhs = 2,
499 .audio_inputs = 1, 500 .gpiomask = 15,
500 .tuner = 0, 501 .muxsel = { 2, 3, 1, 1},
501 .svhs = 2, 502 .audiomux = { 13, 14, 11, 7, 0, 0},
502 .gpiomask = 7, 503 .needs_tvaudio = 1,
503 .muxsel = { 2, 3, 1, 1}, 504 .tuner_type = -1,
504 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ 505 .tuner_addr = ADDR_UNSET,
505 .needs_tvaudio = 1, 506 .radio_addr = ADDR_UNSET,
506 .pll = PLL_28, 507 },
507 .tuner_type = -1, 508 [BTTV_BOARD_AVERMEDIA98] = {
508 .tuner_addr = ADDR_UNSET, 509 .name = "AVerMedia TVCapture 98",
509},{ 510 .video_inputs = 3,
510 .name = "Zoltrix TV-Max", 511 .audio_inputs = 4,
511 .video_inputs = 3, 512 .tuner = 0,
512 .audio_inputs = 1, 513 .svhs = 2,
513 .tuner = 0, 514 .gpiomask = 15,
514 .svhs = 2, 515 .muxsel = { 2, 3, 1, 1},
515 .gpiomask = 15, 516 .audiomux = { 13, 14, 11, 7, 0, 0},
516 .muxsel = { 2, 3, 1, 1}, 517 .needs_tvaudio = 1,
517 .audiomux = {0 , 0, 1 , 0, 10}, 518 .msp34xx_alt = 1,
518 .needs_tvaudio = 1, 519 .pll = PLL_28,
519 .tuner_type = -1, 520 .tuner_type = TUNER_PHILIPS_PAL,
520 .tuner_addr = ADDR_UNSET, 521 .tuner_addr = ADDR_UNSET,
521},{ 522 .radio_addr = ADDR_UNSET,
522 523 .audio_hook = avermedia_tv_stereo_audio,
523/* ---- card 0x10 ---------------------------------- */ 524 .no_gpioirq = 1,
524 .name = "Prolink Pixelview PlayTV (bt878)", 525 },
525 .video_inputs = 3, 526 [BTTV_BOARD_VHX] = {
526 .audio_inputs = 1, 527 .name = "Aimslab Video Highway Xtreme (VHX)",
527 .tuner = 0, 528 .video_inputs = 3,
528 .svhs = 2, 529 .audio_inputs = 1,
529 .gpiomask = 0x01fe00, 530 .tuner = 0,
530 .muxsel = { 2, 3, 1, 1}, 531 .svhs = 2,
531 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ 532 .gpiomask = 7,
532 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 533 .muxsel = { 2, 3, 1, 1},
533 .needs_tvaudio = 1, 534 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
534 .pll = PLL_28, 535 .needs_tvaudio = 1,
535 .tuner_type = -1, 536 .pll = PLL_28,
536},{ 537 .tuner_type = -1,
537 .name = "Leadtek WinView 601", 538 .tuner_addr = ADDR_UNSET,
538 .video_inputs = 3, 539 .radio_addr = ADDR_UNSET,
539 .audio_inputs = 1, 540 },
540 .tuner = 0, 541 [BTTV_BOARD_ZOLTRIX] = {
541 .svhs = 2, 542 .name = "Zoltrix TV-Max",
542 .gpiomask = 0x8300f8, 543 .video_inputs = 3,
543 .muxsel = { 2, 3, 1, 1,0}, 544 .audio_inputs = 1,
544 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, 545 .tuner = 0,
545 .needs_tvaudio = 1, 546 .svhs = 2,
546 .tuner_type = -1, 547 .gpiomask = 15,
547 .tuner_addr = ADDR_UNSET, 548 .muxsel = { 2, 3, 1, 1},
548 .audio_hook = winview_audio, 549 .audiomux = {0 , 0, 1 , 0, 10},
549 .has_radio = 1, 550 .needs_tvaudio = 1,
550},{ 551 .tuner_type = -1,
551 .name = "AVEC Intercapture", 552 .tuner_addr = ADDR_UNSET,
552 .video_inputs = 3, 553 .radio_addr = ADDR_UNSET,
553 .audio_inputs = 2, 554 },
554 .tuner = 0, 555
555 .svhs = 2, 556 /* ---- card 0x10 ---------------------------------- */
556 .gpiomask = 0, 557 [BTTV_BOARD_PIXVIEWPLAYTV] = {
557 .muxsel = {2, 3, 1, 1}, 558 .name = "Prolink Pixelview PlayTV (bt878)",
558 .audiomux = {1, 0, 0, 0, 0}, 559 .video_inputs = 3,
559 .needs_tvaudio = 1, 560 .audio_inputs = 1,
560 .tuner_type = -1, 561 .tuner = 0,
561 .tuner_addr = ADDR_UNSET, 562 .svhs = 2,
562},{ 563 .gpiomask = 0x01fe00,
563 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", 564 .muxsel = { 2, 3, 1, 1},
564 .video_inputs = 4, 565 #if 0
565 .audio_inputs = 1, 566 /* old */
566 .tuner = -1, 567 .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
567 .svhs = -1, 568 #else
568 .gpiomask = 0x8dff00, 569 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
569 .muxsel = { 2, 3, 1, 1}, 570 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
570 .audiomux = { 0 }, 571 #endif
571 .no_msp34xx = 1, 572 .needs_tvaudio = 1,
572 .tuner_type = -1, 573 .pll = PLL_28,
573 .tuner_addr = ADDR_UNSET, 574 .tuner_type = -1,
574},{ 575 },
575 576 [BTTV_BOARD_WINVIEW_601] = {
576/* ---- card 0x14 ---------------------------------- */ 577 .name = "Leadtek WinView 601",
577 .name = "CEI Raffles Card", 578 .video_inputs = 3,
578 .video_inputs = 3, 579 .audio_inputs = 1,
579 .audio_inputs = 3, 580 .tuner = 0,
580 .tuner = 0, 581 .svhs = 2,
581 .svhs = 2, 582 .gpiomask = 0x8300f8,
582 .muxsel = {2, 3, 1, 1}, 583 .muxsel = { 2, 3, 1, 1,0},
583 .tuner_type = -1, 584 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
584 .tuner_addr = ADDR_UNSET, 585 .needs_tvaudio = 1,
585},{ 586 .tuner_type = -1,
586 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", 587 .tuner_addr = ADDR_UNSET,
587 .video_inputs = 4, 588 .radio_addr = ADDR_UNSET,
588 .audio_inputs = 2, /* tuner, line in */ 589 .audio_hook = winview_audio,
589 .tuner = 0, 590 .has_radio = 1,
590 .svhs = 2, 591 },
591 .gpiomask = 0x1800, 592 [BTTV_BOARD_AVEC_INTERCAP] = {
592 .muxsel = { 2, 3, 1, 1}, 593 .name = "AVEC Intercapture",
593 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 594 .video_inputs = 3,
594 .pll = PLL_28, 595 .audio_inputs = 2,
595 .tuner_type = TUNER_PHILIPS_PAL_I, 596 .tuner = 0,
596 .tuner_addr = ADDR_UNSET, 597 .svhs = 2,
597},{ 598 .gpiomask = 0,
598 .name = "Askey CPH050/ Phoebe Tv Master + FM", 599 .muxsel = {2, 3, 1, 1},
599 .video_inputs = 3, 600 .audiomux = {1, 0, 0, 0, 0},
600 .audio_inputs = 1, 601 .needs_tvaudio = 1,
601 .tuner = 0, 602 .tuner_type = -1,
602 .svhs = 2, 603 .tuner_addr = ADDR_UNSET,
603 .gpiomask = 0xc00, 604 .radio_addr = ADDR_UNSET,
604 .muxsel = { 2, 3, 1, 1}, 605 },
605 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0}, 606 [BTTV_BOARD_LIFE_FLYKIT] = {
606 .needs_tvaudio = 1, 607 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
607 .pll = PLL_28, 608 .video_inputs = 4,
608 .tuner_type = -1, 609 .audio_inputs = 1,
609 .tuner_addr = ADDR_UNSET, 610 .tuner = -1,
610},{ 611 .svhs = -1,
611 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", 612 .gpiomask = 0x8dff00,
612 .video_inputs = 3, 613 .muxsel = { 2, 3, 1, 1},
613 .audio_inputs = 1, 614 .audiomux = { 0 },
614 .tuner = 0, 615 .no_msp34xx = 1,
615 .svhs = -1, 616 .tuner_type = -1,
616 .gpiomask = 7, 617 .tuner_addr = ADDR_UNSET,
617 .muxsel = { 2, 3, -1 }, 618 .radio_addr = ADDR_UNSET,
618 .digital_mode = DIGITAL_MODE_CAMERA, 619 },
619 .audiomux = { 0, 0, 0, 0, 0 }, 620
620 .no_msp34xx = 1, 621 /* ---- card 0x14 ---------------------------------- */
621 .pll = PLL_28, 622 [BTTV_BOARD_CEI_RAFFLES] = {
622 .tuner_type = TUNER_ALPS_TSBB5_PAL_I, 623 .name = "CEI Raffles Card",
623 .tuner_addr = ADDR_UNSET, 624 .video_inputs = 3,
624},{ 625 .audio_inputs = 3,
625 626 .tuner = 0,
626/* ---- card 0x18 ---------------------------------- */ 627 .svhs = 2,
627 .name = "Askey CPH05X/06X (bt878) [many vendors]", 628 .muxsel = {2, 3, 1, 1},
628 .video_inputs = 3, 629 .tuner_type = -1,
629 .audio_inputs = 1, 630 .tuner_addr = ADDR_UNSET,
630 .tuner = 0, 631 .radio_addr = ADDR_UNSET,
631 .svhs = 2, 632 },
632 .gpiomask = 0xe00, 633 [BTTV_BOARD_CONFERENCETV] = {
633 .muxsel = { 2, 3, 1, 1}, 634 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
634 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00}, 635 .video_inputs = 4,
635 .needs_tvaudio = 1, 636 .audio_inputs = 2, /* tuner, line in */
636 .pll = PLL_28, 637 .tuner = 0,
637 .tuner_type = -1, 638 .svhs = 2,
638 .tuner_addr = ADDR_UNSET, 639 .gpiomask = 0x1800,
639 .has_remote = 1, 640 .muxsel = { 2, 3, 1, 1},
640},{ 641 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
641 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", 642 .pll = PLL_28,
642 .video_inputs = 3, 643 .tuner_type = TUNER_PHILIPS_PAL_I,
643 .audio_inputs = 1, 644 .tuner_addr = ADDR_UNSET,
644 .tuner = 0, 645 .radio_addr = ADDR_UNSET,
645 .svhs = 2, 646 },
646 .gpiomask = 0x1f0fff, 647 [BTTV_BOARD_PHOEBE_TVMAS] = {
647 .muxsel = { 2, 3, 1, 1}, 648 .name = "Askey CPH050/ Phoebe Tv Master + FM",
648 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, 649 .video_inputs = 3,
649 .needs_tvaudio = 0, 650 .audio_inputs = 1,
650 .tuner_type = TUNER_PHILIPS_PAL, 651 .tuner = 0,
651 .tuner_addr = ADDR_UNSET, 652 .svhs = 2,
652 .audio_hook = terratv_audio, 653 .gpiomask = 0xc00,
653},{ 654 .muxsel = { 2, 3, 1, 1},
654 .name = "Hauppauge WinCam newer (bt878)", 655 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
655 .video_inputs = 4, 656 .needs_tvaudio = 1,
656 .audio_inputs = 1, 657 .pll = PLL_28,
657 .tuner = 0, 658 .tuner_type = -1,
658 .svhs = 3, 659 .tuner_addr = ADDR_UNSET,
659 .gpiomask = 7, 660 .radio_addr = ADDR_UNSET,
660 .muxsel = { 2, 0, 1, 1}, 661 },
661 .audiomux = { 0, 1, 2, 3, 4}, 662 [BTTV_BOARD_MODTEC_205] = {
662 .needs_tvaudio = 1, 663 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
663 .tuner_type = -1, 664 .video_inputs = 3,
664 .tuner_addr = ADDR_UNSET, 665 .audio_inputs = 1,
665},{ 666 .tuner = 0,
666 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", 667 .svhs = -1,
667 .video_inputs = 4, 668 .gpiomask = 7,
668 .audio_inputs = 2, 669 .muxsel = { 2, 3, -1 },
669 .tuner = 0, 670 .digital_mode = DIGITAL_MODE_CAMERA,
670 .svhs = 2, 671 .audiomux = { 0, 0, 0, 0, 0 },
671 .gpiomask = 0x1800, 672 .no_msp34xx = 1,
672 .muxsel = { 2, 3, 1, 1}, 673 .pll = PLL_28,
673 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 674 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
674 .pll = PLL_28, 675 .tuner_addr = ADDR_UNSET,
675 .tuner_type = TUNER_PHILIPS_SECAM, 676 .radio_addr = ADDR_UNSET,
676 .tuner_addr = ADDR_UNSET, 677 },
677},{ 678
678 679 /* ---- card 0x18 ---------------------------------- */
679/* ---- card 0x1c ---------------------------------- */ 680 [BTTV_BOARD_MAGICTVIEW061] = {
680 .name = "Terratec TerraTV+ Version 1.1 (bt878)", 681 .name = "Askey CPH05X/06X (bt878) [many vendors]",
681 .video_inputs = 3, 682 .video_inputs = 3,
682 .audio_inputs = 1, 683 .audio_inputs = 1,
683 .tuner = 0, 684 .tuner = 0,
684 .svhs = 2, 685 .svhs = 2,
685 .gpiomask = 0x1f0fff, 686 .gpiomask = 0xe00,
686 .muxsel = { 2, 3, 1, 1}, 687 .muxsel = { 2, 3, 1, 1},
687 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, 688 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
688 .needs_tvaudio = 0, 689 .needs_tvaudio = 1,
689 .tuner_type = TUNER_PHILIPS_PAL, 690 .pll = PLL_28,
690 .tuner_addr = ADDR_UNSET, 691 .tuner_type = -1,
691 .audio_hook = terratv_audio, 692 .tuner_addr = ADDR_UNSET,
692 /* GPIO wiring: 693 .radio_addr = ADDR_UNSET,
693 External 20 pin connector (for Active Radio Upgrade board) 694 .has_remote = 1,
694 gpio00: i2c-sda 695 },
695 gpio01: i2c-scl 696 [BTTV_BOARD_VOBIS_BOOSTAR] = {
696 gpio02: om5610-data 697 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
697 gpio03: om5610-clk 698 .video_inputs = 3,
698 gpio04: om5610-wre 699 .audio_inputs = 1,
699 gpio05: om5610-stereo 700 .tuner = 0,
700 gpio06: rds6588-davn 701 .svhs = 2,
701 gpio07: Pin 7 n.c. 702 .gpiomask = 0x1f0fff,
702 gpio08: nIOW 703 .muxsel = { 2, 3, 1, 1},
703 gpio09+10: nIOR, nSEL ?? (bt878) 704 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
704 gpio09: nIOR (bt848) 705 .needs_tvaudio = 0,
705 gpio10: nSEL (bt848) 706 .tuner_type = TUNER_PHILIPS_PAL,
706 Sound Routing: 707 .tuner_addr = ADDR_UNSET,
707 gpio16: u2-A0 (1st 4052bt) 708 .radio_addr = ADDR_UNSET,
708 gpio17: u2-A1 709 .audio_hook = terratv_audio,
709 gpio18: u2-nEN 710 },
710 gpio19: u4-A0 (2nd 4052) 711 [BTTV_BOARD_HAUPPAUG_WCAM] = {
711 gpio20: u4-A1 712 .name = "Hauppauge WinCam newer (bt878)",
712 u4-nEN - GND 713 .video_inputs = 4,
713 Btspy: 714 .audio_inputs = 1,
714 00000 : Cdrom (internal audio input) 715 .tuner = 0,
715 10000 : ext. Video audio input 716 .svhs = 3,
716 20000 : TV Mono 717 .gpiomask = 7,
717 a0000 : TV Mono/2 718 .muxsel = { 2, 0, 1, 1},
718 1a0000 : TV Stereo 719 .audiomux = { 0, 1, 2, 3, 4},
719 30000 : Radio 720 .needs_tvaudio = 1,
720 40000 : Mute 721 .tuner_type = -1,
721*/ 722 .tuner_addr = ADDR_UNSET,
722 723 .radio_addr = ADDR_UNSET,
723},{ 724 },
724 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ 725 [BTTV_BOARD_MAXI] = {
725 .name = "Imagenation PXC200", 726 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
726 .video_inputs = 5, 727 .video_inputs = 4,
727 .audio_inputs = 1, 728 .audio_inputs = 2,
728 .tuner = -1, 729 .tuner = 0,
729 .svhs = 1, /* was: 4 */ 730 .svhs = 2,
730 .gpiomask = 0, 731 .gpiomask = 0x1800,
731 .muxsel = { 2, 3, 1, 0, 0}, 732 .muxsel = { 2, 3, 1, 1},
732 .audiomux = { 0 }, 733 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
733 .needs_tvaudio = 1, 734 .pll = PLL_28,
734 .tuner_type = -1, 735 .tuner_type = TUNER_PHILIPS_SECAM,
735 .tuner_addr = ADDR_UNSET, 736 .tuner_addr = ADDR_UNSET,
736 .muxsel_hook = PXC200_muxsel, 737 .radio_addr = ADDR_UNSET,
737 738 },
738},{ 739
739 .name = "Lifeview FlyVideo 98 LR50", 740 /* ---- card 0x1c ---------------------------------- */
740 .video_inputs = 4, 741 [BTTV_BOARD_TERRATV] = {
741 .audio_inputs = 1, 742 .name = "Terratec TerraTV+ Version 1.1 (bt878)",
742 .tuner = 0, 743 .video_inputs = 3,
743 .svhs = 2, 744 .audio_inputs = 1,
744 .gpiomask = 0x1800, /* 0x8dfe00 */ 745 .tuner = 0,
745 .muxsel = { 2, 3, 1, 1}, 746 .svhs = 2,
746 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, 747 .gpiomask = 0x1f0fff,
747 .pll = PLL_28, 748 .muxsel = { 2, 3, 1, 1},
748 .tuner_type = -1, 749 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
749 .tuner_addr = ADDR_UNSET, 750 .needs_tvaudio = 0,
750},{ 751 .tuner_type = TUNER_PHILIPS_PAL,
751 .name = "Formac iProTV, Formac ProTV I (bt848)", 752 .tuner_addr = ADDR_UNSET,
752 .video_inputs = 4, 753 .radio_addr = ADDR_UNSET,
753 .audio_inputs = 1, 754 .audio_hook = terratv_audio,
754 .tuner = 0, 755 /* GPIO wiring:
755 .svhs = 3, 756 External 20 pin connector (for Active Radio Upgrade board)
756 .gpiomask = 1, 757 gpio00: i2c-sda
757 .muxsel = { 2, 3, 1, 1}, 758 gpio01: i2c-scl
758 .audiomux = { 1, 0, 0, 0, 0 }, 759 gpio02: om5610-data
759 .pll = PLL_28, 760 gpio03: om5610-clk
760 .tuner_type = TUNER_PHILIPS_PAL, 761 gpio04: om5610-wre
761 .tuner_addr = ADDR_UNSET, 762 gpio05: om5610-stereo
762},{ 763 gpio06: rds6588-davn
763 764 gpio07: Pin 7 n.c.
764/* ---- card 0x20 ---------------------------------- */ 765 gpio08: nIOW
765 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 766 gpio09+10: nIOR, nSEL ?? (bt878)
766 .video_inputs = 4, 767 gpio09: nIOR (bt848)
767 .audio_inputs = 0, 768 gpio10: nSEL (bt848)
768 .tuner = -1, 769 Sound Routing:
769 .svhs = 2, 770 gpio16: u2-A0 (1st 4052bt)
770 .gpiomask = 0, 771 gpio17: u2-A1
771 .muxsel = { 2, 3, 1, 1}, 772 gpio18: u2-nEN
772 .audiomux = { 0 }, 773 gpio19: u4-A0 (2nd 4052)
773 .needs_tvaudio = 0, 774 gpio20: u4-A1
774 .tuner_type = 4, 775 u4-nEN - GND
775 .tuner_addr = ADDR_UNSET, 776 Btspy:
776},{ 777 00000 : Cdrom (internal audio input)
777 .name = "Terratec TerraTValue Version Bt878", 778 10000 : ext. Video audio input
778 .video_inputs = 3, 779 20000 : TV Mono
779 .audio_inputs = 1, 780 a0000 : TV Mono/2
780 .tuner = 0, 781 1a0000 : TV Stereo
781 .svhs = 2, 782 30000 : Radio
782 .gpiomask = 0xffff00, 783 40000 : Mute
783 .muxsel = { 2, 3, 1, 1},
784 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
785 .needs_tvaudio = 1,
786 .pll = PLL_28,
787 .tuner_type = TUNER_PHILIPS_PAL,
788 .tuner_addr = ADDR_UNSET,
789},{
790 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
791 .video_inputs = 4,
792 .audio_inputs = 1,
793 .tuner = 0,
794 .svhs = 2,
795 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
796 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
797 .gpiomask = 0xb33000,
798 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
799 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
800 gpio23 -- hef4052:nEnable (0x800000)
801 gpio12 -- hef4052:A1
802 gpio13 -- hef4052:A0
803 0x0000: external audio
804 0x1000: FM
805 0x2000: TV
806 0x3000: n.c.
807 Note: There exists another variant "Winfast 2000" with tv stereo !?
808 Note: eeprom only contains FF and pci subsystem id 107d:6606
809 */
810 .needs_tvaudio = 0,
811 .pll = PLL_28,
812 .has_radio = 1,
813 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
814 .tuner_addr = ADDR_UNSET,
815 .audio_hook = winfast2000_audio,
816 .has_remote = 1,
817},{
818 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
819 .video_inputs = 4,
820 .audio_inputs = 3,
821 .tuner = 0,
822 .svhs = 2,
823 .gpiomask = 0x1800,
824 .muxsel = { 2, 3, 1, 1},
825 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
826 .pll = PLL_28,
827 .tuner_type = -1,
828 .tuner_addr = ADDR_UNSET,
829},{
830
831/* ---- card 0x24 ---------------------------------- */
832 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
833 .video_inputs = 4,
834 .audio_inputs = 3,
835 .tuner = 0,
836 .svhs = 2,
837 .gpiomask = 0x1800,
838 .muxsel = { 2, 3, 1, 1},
839 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
840 .pll = PLL_28,
841 .tuner_type = -1,
842 .tuner_addr = ADDR_UNSET,
843 .has_radio = 1,
844},{
845 .name = "Prolink PixelView PlayTV pro",
846 .video_inputs = 3,
847 .audio_inputs = 1,
848 .tuner = 0,
849 .svhs = 2,
850 .gpiomask = 0xff,
851 .muxsel = { 2, 3, 1, 1 },
852 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
853 .no_msp34xx = 1,
854 .pll = PLL_28,
855 .tuner_type = -1,
856 .tuner_addr = ADDR_UNSET,
857},{
858 .name = "Askey CPH06X TView99",
859 .video_inputs = 4,
860 .audio_inputs = 1,
861 .tuner = 0,
862 .svhs = 2,
863 .gpiomask = 0x551e00,
864 .muxsel = { 2, 3, 1, 0},
865 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
866 .needs_tvaudio = 1,
867 .pll = PLL_28,
868 .tuner_type = 1,
869 .tuner_addr = ADDR_UNSET,
870 .has_remote = 1,
871},{
872 .name = "Pinnacle PCTV Studio/Rave",
873 .video_inputs = 3,
874 .audio_inputs = 1,
875 .tuner = 0,
876 .svhs = 2,
877 .gpiomask = 0x03000F,
878 .muxsel = { 2, 3, 1, 1},
879 .audiomux = { 2, 0xd0001, 0, 0, 1},
880 .needs_tvaudio = 0,
881 .pll = PLL_28,
882 .tuner_type = -1,
883 .tuner_addr = ADDR_UNSET,
884},{
885
886/* ---- card 0x28 ---------------------------------- */
887 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
888 .video_inputs = 3,
889 .audio_inputs = 1,
890 .tuner = 0,
891 .svhs = 2,
892 .gpiomask = 7,
893 .muxsel = { 2, 3, 1, 1},
894 .audiomux = { 4, 0, 2, 3, 1},
895 .no_msp34xx = 1,
896 .needs_tvaudio = 1,
897 .tuner_type = TUNER_PHILIPS_NTSC,
898 .tuner_addr = ADDR_UNSET,
899 .pll = PLL_28,
900 .has_radio = 1,
901},{
902 .name = "AVerMedia TVPhone 98",
903 .video_inputs = 3,
904 .audio_inputs = 4,
905 .tuner = 0,
906 .svhs = 2,
907 .gpiomask = 15,
908 .muxsel = { 2, 3, 1, 1},
909 .audiomux = { 13, 4, 11, 7, 0, 0},
910 .needs_tvaudio = 1,
911 .pll = PLL_28,
912 .tuner_type = -1,
913 .tuner_addr = ADDR_UNSET,
914 .has_radio = 1,
915 .audio_hook = avermedia_tvphone_audio,
916},{
917 .name = "ProVideo PV951", /* pic16c54 */
918 .video_inputs = 3,
919 .audio_inputs = 1,
920 .tuner = 0,
921 .svhs = 2,
922 .gpiomask = 0,
923 .muxsel = { 2, 3, 1, 1},
924 .audiomux = { 0, 0, 0, 0, 0},
925 .needs_tvaudio = 1,
926 .no_msp34xx = 1,
927 .pll = PLL_28,
928 .tuner_type = 1,
929 .tuner_addr = ADDR_UNSET,
930},{
931 .name = "Little OnAir TV",
932 .video_inputs = 3,
933 .audio_inputs = 1,
934 .tuner = 0,
935 .svhs = 2,
936 .gpiomask = 0xe00b,
937 .muxsel = {2, 3, 1, 1},
938 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
939 .no_msp34xx = 1,
940 .tuner_type = -1,
941 .tuner_addr = ADDR_UNSET,
942},{
943
944/* ---- card 0x2c ---------------------------------- */
945 .name = "Sigma TVII-FM",
946 .video_inputs = 2,
947 .audio_inputs = 1,
948 .tuner = 0,
949 .svhs = -1,
950 .gpiomask = 3,
951 .muxsel = {2, 3, 1, 1},
952 .audiomux = {1, 1, 0, 2, 3},
953 .no_msp34xx = 1,
954 .pll = PLL_NONE,
955 .tuner_type = -1,
956 .tuner_addr = ADDR_UNSET,
957},{
958 .name = "MATRIX-Vision MV-Delta 2",
959 .video_inputs = 5,
960 .audio_inputs = 1,
961 .tuner = -1,
962 .svhs = 3,
963 .gpiomask = 0,
964 .muxsel = { 2, 3, 1, 0, 0},
965 .audiomux = {0 },
966 .no_msp34xx = 1,
967 .pll = PLL_28,
968 .tuner_type = -1,
969 .tuner_addr = ADDR_UNSET,
970},{
971 .name = "Zoltrix Genie TV/FM",
972 .video_inputs = 3,
973 .audio_inputs = 1,
974 .tuner = 0,
975 .svhs = 2,
976 .gpiomask = 0xbcf03f,
977 .muxsel = { 2, 3, 1, 1},
978 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
979 .no_msp34xx = 1,
980 .pll = PLL_28,
981 .tuner_type = 21,
982 .tuner_addr = ADDR_UNSET,
983},{
984 .name = "Terratec TV/Radio+",
985 .video_inputs = 3,
986 .audio_inputs = 1,
987 .tuner = 0,
988 .svhs = 2,
989 .gpiomask = 0x70000,
990 .muxsel = { 2, 3, 1, 1},
991 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
992 .needs_tvaudio = 1,
993 .no_msp34xx = 1,
994 .pll = PLL_35,
995 .tuner_type = 1,
996 .tuner_addr = ADDR_UNSET,
997 .has_radio = 1,
998},{
999
1000/* ---- card 0x30 ---------------------------------- */
1001 .name = "Askey CPH03x/ Dynalink Magic TView",
1002 .video_inputs = 3,
1003 .audio_inputs = 1,
1004 .tuner = 0,
1005 .svhs = 2,
1006 .gpiomask = 15,
1007 .muxsel = { 2, 3, 1, 1},
1008 .audiomux = {2,0,0,0,1},
1009 .needs_tvaudio = 1,
1010 .pll = PLL_28,
1011 .tuner_type = -1,
1012 .tuner_addr = ADDR_UNSET,
1013},{
1014 .name = "IODATA GV-BCTV3/PCI",
1015 .video_inputs = 3,
1016 .audio_inputs = 1,
1017 .tuner = 0,
1018 .svhs = 2,
1019 .gpiomask = 0x010f00,
1020 .muxsel = {2, 3, 0, 0},
1021 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1022 .no_msp34xx = 1,
1023 .pll = PLL_28,
1024 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1025 .tuner_addr = ADDR_UNSET,
1026 .audio_hook = gvbctv3pci_audio,
1027},{
1028 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1029 .video_inputs = 5,
1030 .audio_inputs = 1,
1031 .tuner = 0,
1032 .svhs = 3,
1033 .gpiomask = 0xAA0000,
1034 .muxsel = { 2,3,1,1,-1 },
1035 .digital_mode = DIGITAL_MODE_CAMERA,
1036 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1037 .no_msp34xx = 1,
1038 .pll = PLL_28,
1039 .tuner_type = TUNER_PHILIPS_PAL_I,
1040 .tuner_addr = ADDR_UNSET,
1041 .has_remote = 1,
1042 /* GPIO wiring: (different from Rev.4C !)
1043 GPIO17: U4.A0 (first hef4052bt)
1044 GPIO19: U4.A1
1045 GPIO20: U5.A1 (second hef4052bt)
1046 GPIO21: U4.nEN
1047 GPIO22: BT832 Reset Line
1048 GPIO23: A5,A0, U5,nEN
1049 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1050 */
1051},{
1052 .name = "Eagle Wireless Capricorn2 (bt878A)",
1053 .video_inputs = 4,
1054 .audio_inputs = 1,
1055 .tuner = 0,
1056 .svhs = 2,
1057 .gpiomask = 7,
1058 .muxsel = { 2, 0, 1, 1},
1059 .audiomux = { 0, 1, 2, 3, 4},
1060 .pll = PLL_28,
1061 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1062 .tuner_addr = ADDR_UNSET,
1063},{
1064
1065/* ---- card 0x34 ---------------------------------- */
1066 /* David Härdeman <david@2gen.com> */
1067 .name = "Pinnacle PCTV Studio Pro",
1068 .video_inputs = 4,
1069 .audio_inputs = 1,
1070 .tuner = 0,
1071 .svhs = 3,
1072 .gpiomask = 0x03000F,
1073 .muxsel = { 2, 3, 1, 1},
1074 .audiomux = { 1, 0xd0001, 0, 0, 10},
1075 /* sound path (5 sources):
1076 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1077 0= ext. Audio IN
1078 1= from MUX2
1079 2= Mono TV sound from Tuner
1080 3= not connected
1081 MUX2 (mask 0x30000):
1082 0,2,3= from MSP34xx
1083 1= FM stereo Radio from Tuner */
1084 .needs_tvaudio = 0,
1085 .pll = PLL_28,
1086 .tuner_type = -1,
1087 .tuner_addr = ADDR_UNSET,
1088},{
1089 /* Claas Langbehn <claas@bigfoot.com>,
1090 Sven Grothklags <sven@upb.de> */
1091 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1092 .video_inputs = 4,
1093 .audio_inputs = 3,
1094 .tuner = 0,
1095 .svhs = 2,
1096 .gpiomask = 0x1c,
1097 .muxsel = { 2, 3, 1, 1},
1098 .audiomux = { 0, 0, 0x10, 8, 4 },
1099 .needs_tvaudio = 1,
1100 .pll = PLL_28,
1101 .tuner_type = TUNER_PHILIPS_PAL,
1102 .tuner_addr = ADDR_UNSET,
1103 .has_radio = 1,
1104},{
1105 /* Tim Röstermundt <rosterm@uni-muenster.de>
1106 in de.comp.os.unix.linux.hardware:
1107 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1108 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1109 options tuner type=5 */
1110 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1111 .video_inputs = 4,
1112 .audio_inputs = 1,
1113 .tuner = 0,
1114 .svhs = 2,
1115 .gpiomask = 0x18e0,
1116 .muxsel = { 2, 3, 1, 1},
1117 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1118 /* For cards with tda9820/tda9821:
1119 0x0000: Tuner normal stereo
1120 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1121 0x0880: Tuner A2 stereo */
1122 .pll = PLL_28,
1123 .tuner_type = -1,
1124 .tuner_addr = ADDR_UNSET,
1125},{
1126 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1127 old Easy TV BT848 version (model CPH031) */
1128 .name = "Askey CPH031/ BESTBUY Easy TV",
1129 .video_inputs = 4,
1130 .audio_inputs = 1,
1131 .tuner = 0,
1132 .svhs = 2,
1133 .gpiomask = 0xF,
1134 .muxsel = { 2, 3, 1, 0},
1135 .audiomux = { 2, 0, 0, 0, 10},
1136 .needs_tvaudio = 0,
1137 .pll = PLL_28,
1138 .tuner_type = TUNER_TEMIC_PAL,
1139 .tuner_addr = ADDR_UNSET,
1140},{
1141
1142/* ---- card 0x38 ---------------------------------- */
1143 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1144 .name = "Lifeview FlyVideo 98FM LR50",
1145 .video_inputs = 4,
1146 .audio_inputs = 3,
1147 .tuner = 0,
1148 .svhs = 2,
1149 .gpiomask = 0x1800,
1150 .muxsel = { 2, 3, 1, 1},
1151 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1152 .pll = PLL_28,
1153 .tuner_type = 5,
1154 .tuner_addr = ADDR_UNSET,
1155},{
1156 /* This is the ultimate cheapo capture card
1157 * just a BT848A on a small PCB!
1158 * Steve Hosgood <steve@equiinet.com> */
1159 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1160 .video_inputs = 2,
1161 .audio_inputs = 0,
1162 .tuner = -1,
1163 .svhs = 1,
1164 .gpiomask = 0,
1165 .muxsel = { 3, 1 },
1166 .audiomux = { 0 },
1167 .needs_tvaudio = 0,
1168 .no_msp34xx = 1,
1169 .pll = PLL_35,
1170 .tuner_type = -1,
1171 .tuner_addr = ADDR_UNSET,
1172},{
1173 /* Daniel Herrington <daniel.herrington@home.com> */
1174 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1175 .video_inputs = 3,
1176 .audio_inputs = 1,
1177 .tuner = 0,
1178 .svhs = 2,
1179 .gpiomask = 0xe00,
1180 .muxsel = { 2, 3, 1, 1},
1181 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1182 .needs_tvaudio = 1,
1183 .pll = PLL_28,
1184 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1185 .tuner_addr = ADDR_UNSET,
1186},{
1187 /* Matti Mottus <mottus@physic.ut.ee> */
1188 .name = "Askey CPH03x TV Capturer",
1189 .video_inputs = 4,
1190 .audio_inputs = 1,
1191 .tuner = 0,
1192 .svhs = 2,
1193 .gpiomask = 0x03000F,
1194 .muxsel = { 2, 3, 1, 0},
1195 .audiomux = { 2,0,0,0,1 },
1196 .pll = PLL_28,
1197 .tuner_type = 0,
1198 .tuner_addr = ADDR_UNSET,
1199},{
1200
1201/* ---- card 0x3c ---------------------------------- */
1202 /* Philip Blundell <philb@gnu.org> */
1203 .name = "Modular Technology MM100PCTV",
1204 .video_inputs = 2,
1205 .audio_inputs = 2,
1206 .tuner = 0,
1207 .svhs = -1,
1208 .gpiomask = 11,
1209 .muxsel = { 2, 3, 1, 1},
1210 .audiomux = { 2, 0, 0, 1, 8},
1211 .pll = PLL_35,
1212 .tuner_type = TUNER_TEMIC_PAL,
1213 .tuner_addr = ADDR_UNSET,
1214},{
1215 /* Adrian Cox <adrian@humboldt.co.uk */
1216 .name = "AG Electronics GMV1",
1217 .video_inputs = 2,
1218 .audio_inputs = 0,
1219 .tuner = -1,
1220 .svhs = 1,
1221 .gpiomask = 0xF,
1222 .muxsel = { 2, 2},
1223 .audiomux = { },
1224 .no_msp34xx = 1,
1225 .needs_tvaudio = 0,
1226 .pll = PLL_28,
1227 .tuner_type = -1,
1228 .tuner_addr = ADDR_UNSET,
1229},{
1230 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1231 new Easy TV BT878 version (model CPH061)
1232 special thanks to Informatica Mieres for providing the card */
1233 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1234 .video_inputs = 3,
1235 .audio_inputs = 2,
1236 .tuner = 0,
1237 .svhs = 2,
1238 .gpiomask = 0xFF,
1239 .muxsel = { 2, 3, 1, 0},
1240 .audiomux = { 1, 0, 4, 4, 9},
1241 .needs_tvaudio = 0,
1242 .pll = PLL_28,
1243 .tuner_type = TUNER_PHILIPS_PAL,
1244 .tuner_addr = ADDR_UNSET,
1245},{
1246 /* Lukas Gebauer <geby@volny.cz> */
1247 .name = "ATI TV-Wonder",
1248 .video_inputs = 3,
1249 .audio_inputs = 1,
1250 .tuner = 0,
1251 .svhs = 2,
1252 .gpiomask = 0xf03f,
1253 .muxsel = { 2, 3, 1, 0 },
1254 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1255 .pll = PLL_28,
1256 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1257 .tuner_addr = ADDR_UNSET,
1258},{
1259
1260/* ---- card 0x40 ---------------------------------- */
1261 /* Lukas Gebauer <geby@volny.cz> */
1262 .name = "ATI TV-Wonder VE",
1263 .video_inputs = 2,
1264 .audio_inputs = 1,
1265 .tuner = 0,
1266 .svhs = -1,
1267 .gpiomask = 1,
1268 .muxsel = { 2, 3, 0, 1},
1269 .audiomux = { 0, 0, 1, 0, 0},
1270 .no_msp34xx = 1,
1271 .pll = PLL_28,
1272 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1273 .tuner_addr = ADDR_UNSET,
1274},{
1275 /* DeeJay <deejay@westel900.net (2000S) */
1276 .name = "Lifeview FlyVideo 2000S LR90",
1277 .video_inputs = 3,
1278 .audio_inputs = 3,
1279 .tuner = 0,
1280 .svhs = 2,
1281 .gpiomask = 0x18e0,
1282 .muxsel = { 2, 3, 0, 1},
1283 /* Radio changed from 1e80 to 0x800 to make
1284 FlyVideo2000S in .hu happy (gm)*/
1285 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1286 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
1287 .audio_hook = fv2000s_audio,
1288 .no_msp34xx = 1,
1289 .no_tda9875 = 1,
1290 .needs_tvaudio = 1,
1291 .pll = PLL_28,
1292 .tuner_type = 5,
1293 .tuner_addr = ADDR_UNSET,
1294},{
1295 .name = "Terratec TValueRadio",
1296 .video_inputs = 3,
1297 .audio_inputs = 1,
1298 .tuner = 0,
1299 .svhs = 2,
1300 .gpiomask = 0xffff00,
1301 .muxsel = { 2, 3, 1, 1},
1302 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
1303 .needs_tvaudio = 1,
1304 .pll = PLL_28,
1305 .tuner_type = TUNER_PHILIPS_PAL,
1306 .tuner_addr = ADDR_UNSET,
1307 .has_radio = 1,
1308},{
1309 /* TANAKA Kei <peg00625@nifty.com> */
1310 .name = "IODATA GV-BCTV4/PCI",
1311 .video_inputs = 3,
1312 .audio_inputs = 1,
1313 .tuner = 0,
1314 .svhs = 2,
1315 .gpiomask = 0x010f00,
1316 .muxsel = {2, 3, 0, 0},
1317 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1318 .no_msp34xx = 1,
1319 .pll = PLL_28,
1320 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1321 .tuner_addr = ADDR_UNSET,
1322 .audio_hook = gvbctv3pci_audio,
1323},{
1324
1325/* ---- card 0x44 ---------------------------------- */
1326 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1327 /* try "insmod msp3400 simple=0" if you have
1328 * sound problems with this card. */
1329 .video_inputs = 4,
1330 .audio_inputs = 1,
1331 .tuner = 0,
1332 .svhs = -1,
1333 .gpiomask = 0x4f8a00,
1334 /* 0x100000: 1=MSP enabled (0=disable again)
1335 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
1336 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
1337 /* tvtuner, radio, external,internal, mute, stereo
1338 * tuner, Composit, SVid, Composit-on-Svid-adapter */
1339 .muxsel = { 2, 3 ,0 ,1},
1340 .tuner_type = TUNER_MT2032,
1341 .tuner_addr = ADDR_UNSET,
1342 .pll = PLL_28,
1343 .has_radio = 1,
1344},{
1345 /* Philip Blundell <pb@nexus.co.uk> */
1346 .name = "Active Imaging AIMMS",
1347 .video_inputs = 1,
1348 .audio_inputs = 0,
1349 .tuner = -1,
1350 .tuner_type = -1,
1351 .tuner_addr = ADDR_UNSET,
1352 .pll = PLL_28,
1353 .muxsel = { 2 },
1354 .gpiomask = 0
1355},{
1356 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1357 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1358 .video_inputs = 3,
1359 .audio_inputs = 4,
1360 .tuner = 0,
1361 .svhs = 2,
1362 .gpiomask = 15,
1363 .muxsel = { 2, 3, 1, 1},
1364 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
1365 .needs_tvaudio = 1,
1366 .pll = PLL_28,
1367 .tuner_type = 25,
1368 .tuner_addr = ADDR_UNSET,
1369 .has_remote = 1,
1370 /* GPIO wiring:
1371 GPIO0: U4.A0 (hef4052bt)
1372 GPIO1: U4.A1
1373 GPIO2: U4.A1 (second hef4052bt)
1374 GPIO3: U4.nEN, U5.A0, A5.nEN
1375 GPIO8-15: vrd866b ?
1376 */ 784 */
1377},{ 785
1378 .name = "Lifeview FlyVideo 98EZ (capture only) LR51", 786 },
1379 .video_inputs = 4, 787 [BTTV_BOARD_PXC200] = {
1380 .audio_inputs = 0, 788 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
1381 .tuner = -1, 789 .name = "Imagenation PXC200",
1382 .svhs = 2, 790 .video_inputs = 5,
1383 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */ 791 .audio_inputs = 1,
1384 .pll = PLL_28, 792 .tuner = -1,
1385 .no_msp34xx = 1, 793 .svhs = 1, /* was: 4 */
1386 .tuner_type = UNSET, 794 .gpiomask = 0,
1387 .tuner_addr = ADDR_UNSET, 795 .muxsel = { 2, 3, 1, 0, 0},
1388},{ 796 .audiomux = { 0 },
1389 797 .needs_tvaudio = 1,
1390/* ---- card 0x48 ---------------------------------- */ 798 .tuner_type = -1,
1391 /* Dariusz Kowalewski <darekk@automex.pl> */ 799 .tuner_addr = ADDR_UNSET,
1392 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", 800 .radio_addr = ADDR_UNSET,
1393 .video_inputs = 4, 801 .muxsel_hook = PXC200_muxsel,
1394 .audio_inputs = 1, 802
1395 .tuner = 0, 803 },
1396 .svhs = 2, 804 [BTTV_BOARD_FLYVIDEO_98] = {
1397 .gpiomask = 0x3f, 805 .name = "Lifeview FlyVideo 98 LR50",
1398 .muxsel = { 2, 3, 1, 1 }, 806 .video_inputs = 4,
1399 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, 807 .audio_inputs = 1,
1400 .needs_tvaudio = 1, 808 .tuner = 0,
1401 .no_msp34xx = 1, 809 .svhs = 2,
1402 .no_tda9875 = 1, 810 .gpiomask = 0x1800, /* 0x8dfe00 */
1403 .pll = PLL_28, 811 .muxsel = { 2, 3, 1, 1},
1404 .tuner_type = 5, 812 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
1405 .tuner_addr = ADDR_UNSET, 813 .pll = PLL_28,
1406 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ 814 .tuner_type = -1,
1407 .has_radio = 1, /* Note: not all cards have radio */ 815 .tuner_addr = ADDR_UNSET,
1408 .has_remote = 1, 816 .radio_addr = ADDR_UNSET,
1409 /* GPIO wiring: 817 },
1410 GPIO0: A0 hef4052 818 [BTTV_BOARD_IPROTV] = {
1411 GPIO1: A1 hef4052 819 .name = "Formac iProTV, Formac ProTV I (bt848)",
1412 GPIO3: nEN hef4052 820 .video_inputs = 4,
1413 GPIO8-15: vrd866b 821 .audio_inputs = 1,
1414 GPIO20,22,23: R30,R29,R28 822 .tuner = 0,
1415 */ 823 .svhs = 3,
1416},{ 824 .gpiomask = 1,
1417 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ 825 .muxsel = { 2, 3, 1, 1},
1418 /* you must jumper JP5 for the card to work */ 826 .audiomux = { 1, 0, 0, 0, 0 },
1419 .name = "Sensoray 311", 827 .pll = PLL_28,
1420 .video_inputs = 5, 828 .tuner_type = TUNER_PHILIPS_PAL,
1421 .audio_inputs = 0, 829 .tuner_addr = ADDR_UNSET,
1422 .tuner = -1, 830 .radio_addr = ADDR_UNSET,
1423 .svhs = 4, 831 },
1424 .gpiomask = 0, 832
1425 .muxsel = { 2, 3, 1, 0, 0}, 833 /* ---- card 0x20 ---------------------------------- */
1426 .audiomux = { 0 }, 834 [BTTV_BOARD_INTEL_C_S_PCI] = {
1427 .needs_tvaudio = 0, 835 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
1428 .tuner_type = -1, 836 .video_inputs = 4,
1429 .tuner_addr = ADDR_UNSET, 837 .audio_inputs = 0,
1430},{ 838 .tuner = -1,
1431 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ 839 .svhs = 2,
1432 .name = "RemoteVision MX (RV605)", 840 .gpiomask = 0,
1433 .video_inputs = 16, 841 .muxsel = { 2, 3, 1, 1},
1434 .audio_inputs = 0, 842 .audiomux = { 0 },
1435 .tuner = -1, 843 .needs_tvaudio = 0,
1436 .svhs = -1, 844 .tuner_type = 4,
1437 .gpiomask = 0x00, 845 .tuner_addr = ADDR_UNSET,
1438 .gpiomask2 = 0x07ff, 846 .radio_addr = ADDR_UNSET,
1439 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, 847 },
1440 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, 848 [BTTV_BOARD_TERRATVALUE] = {
1441 .no_msp34xx = 1, 849 .name = "Terratec TerraTValue Version Bt878",
1442 .no_tda9875 = 1, 850 .video_inputs = 3,
1443 .tuner_type = -1, 851 .audio_inputs = 1,
1444 .tuner_addr = ADDR_UNSET, 852 .tuner = 0,
1445 .muxsel_hook = rv605_muxsel, 853 .svhs = 2,
1446},{ 854 .gpiomask = 0xffff00,
1447 .name = "Powercolor MTV878/ MTV878R/ MTV878F", 855 .muxsel = { 2, 3, 1, 1},
1448 .video_inputs = 3, 856 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
1449 .audio_inputs = 2, 857 .needs_tvaudio = 1,
1450 .tuner = 0, 858 .pll = PLL_28,
1451 .svhs = 2, 859 .tuner_type = TUNER_PHILIPS_PAL,
1452 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ 860 .tuner_addr = ADDR_UNSET,
1453 .muxsel = { 2, 1, 1, }, 861 .radio_addr = ADDR_UNSET,
1454 .audiomux = { 0, 1, 2, 2, 4 }, 862 },
1455 .needs_tvaudio = 0, 863 [BTTV_BOARD_WINFAST2000] = {
1456 .tuner_type = TUNER_PHILIPS_PAL, 864 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
1457 .tuner_addr = ADDR_UNSET, 865 .video_inputs = 4,
1458 .pll = PLL_28, 866 .audio_inputs = 1,
1459 .has_radio = 1, 867 .tuner = 0,
1460},{ 868 .svhs = 2,
1461 869 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
1462/* ---- card 0x4c ---------------------------------- */ 870 #if 0
1463 /* Masaki Suzuki <masaki@btree.org> */ 871 .gpiomask = 0xc33000,
1464 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", 872 .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
1465 .video_inputs = 3, 873 #else
1466 .audio_inputs = 1, 874 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
1467 .tuner = 0, 875 .gpiomask = 0xb33000,
1468 .svhs = 2, 876 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
1469 .gpiomask = 0x140007, 877 #endif
1470 .muxsel = { 2, 3, 1, 1 }, 878 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
1471 .audiomux = { 0, 1, 2, 3, 4, 0 }, 879 gpio23 -- hef4052:nEnable (0x800000)
1472 .tuner_type = TUNER_PHILIPS_NTSC, 880 gpio12 -- hef4052:A1
1473 .tuner_addr = ADDR_UNSET, 881 gpio13 -- hef4052:A0
1474 .audio_hook = windvr_audio, 882 0x0000: external audio
1475},{ 883 0x1000: FM
1476 .name = "GrandTec Multi Capture Card (Bt878)", 884 0x2000: TV
1477 .video_inputs = 4, 885 0x3000: n.c.
1478 .audio_inputs = 0, 886 Note: There exists another variant "Winfast 2000" with tv stereo !?
1479 .tuner = -1, 887 Note: eeprom only contains FF and pci subsystem id 107d:6606
1480 .svhs = -1, 888 */
1481 .gpiomask = 0, 889 .needs_tvaudio = 0,
1482 .muxsel = { 2, 3, 1, 0 }, 890 .pll = PLL_28,
1483 .audiomux = { 0 }, 891 .has_radio = 1,
1484 .needs_tvaudio = 0, 892 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
1485 .no_msp34xx = 1, 893 .tuner_addr = ADDR_UNSET,
1486 .pll = PLL_28, 894 .radio_addr = ADDR_UNSET,
1487 .tuner_type = -1, 895 .audio_hook = winfast2000_audio,
1488 .tuner_addr = ADDR_UNSET, 896 .has_remote = 1,
1489},{ 897 },
1490 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", 898 [BTTV_BOARD_CHRONOS_VS2] = {
1491 .video_inputs = 4, 899 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
1492 .audio_inputs = 3, 900 .video_inputs = 4,
1493 .tuner = 0, 901 .audio_inputs = 3,
1494 .svhs = 2, 902 .tuner = 0,
1495 .gpiomask = 7, 903 .svhs = 2,
1496 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ 904 .gpiomask = 0x1800,
1497 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio! 905 .muxsel = { 2, 3, 1, 1},
1498 * This card lacks external Audio In, so we mute it on Ext. & Int. 906 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
1499 * The PCB can take a sbx1637/sbx1673, wiring unknown. 907 .pll = PLL_28,
1500 * This card lacks PCI subsystem ID, sigh. 908 .tuner_type = -1,
1501 * audiomux=1: lower volume, 2+3: mute 909 .tuner_addr = ADDR_UNSET,
1502 * btwincap uses 0x80000/0x80003 910 .radio_addr = ADDR_UNSET,
1503 */ 911 },
1504 .needs_tvaudio = 0, 912
1505 .no_msp34xx = 1, 913 /* ---- card 0x24 ---------------------------------- */
1506 .pll = PLL_28, 914 [BTTV_BOARD_TYPHOON_TVIEW] = {
1507 .tuner_type = 5, 915 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
1508 .tuner_addr = ADDR_UNSET, 916 .video_inputs = 4,
1509 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and 917 .audio_inputs = 3,
1510 radio signal strength indicators work fine. */ 918 .tuner = 0,
1511 .has_radio = 1, 919 .svhs = 2,
1512 /* GPIO Info: 920 .gpiomask = 0x1800,
1513 GPIO0,1: HEF4052 A0,A1 921 .muxsel = { 2, 3, 1, 1},
1514 GPIO2: HEF4052 nENABLE 922 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1515 GPIO3-7: n.c. 923 .pll = PLL_28,
1516 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card] 924 .tuner_type = -1,
1517 GPIO14,15: ?? 925 .tuner_addr = ADDR_UNSET,
1518 GPIO16-21: n.c. 926 .radio_addr = ADDR_UNSET,
1519 GPIO22,23: ?? 927 .has_radio = 1,
1520 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ 928 },
1521},{ 929 [BTTV_BOARD_PXELVWPLTVPRO] = {
1522 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ 930 .name = "Prolink PixelView PlayTV pro",
1523 .name = "DSP Design TCVIDEO", 931 .video_inputs = 3,
1524 .video_inputs = 4, 932 .audio_inputs = 1,
1525 .svhs = -1, 933 .tuner = 0,
1526 .muxsel = { 2, 3, 1, 0}, 934 .svhs = 2,
1527 .pll = PLL_28, 935 .gpiomask = 0xff,
1528 .tuner_type = -1, 936 .muxsel = { 2, 3, 1, 1 },
1529 .tuner_addr = ADDR_UNSET, 937 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
1530},{ 938 .no_msp34xx = 1,
1531 939 .pll = PLL_28,
1532 /* ---- card 0x50 ---------------------------------- */ 940 .tuner_type = -1,
1533 .name = "Hauppauge WinTV PVR", 941 .tuner_addr = ADDR_UNSET,
1534 .video_inputs = 4, 942 .radio_addr = ADDR_UNSET,
1535 .audio_inputs = 1, 943 },
1536 .tuner = 0, 944 [BTTV_BOARD_MAGICTVIEW063] = {
1537 .svhs = 2, 945 .name = "Askey CPH06X TView99",
1538 .muxsel = { 2, 0, 1, 1}, 946 .video_inputs = 4,
1539 .needs_tvaudio = 1, 947 .audio_inputs = 1,
1540 .pll = PLL_28, 948 .tuner = 0,
1541 .tuner_type = -1, 949 .svhs = 2,
1542 .tuner_addr = ADDR_UNSET, 950 .gpiomask = 0x551e00,
1543 951 .muxsel = { 2, 3, 1, 0},
1544 .gpiomask = 7, 952 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
1545 .audiomux = {7}, 953 .needs_tvaudio = 1,
1546},{ 954 .pll = PLL_28,
1547 .name = "IODATA GV-BCTV5/PCI", 955 .tuner_type = 1,
1548 .video_inputs = 3, 956 .tuner_addr = ADDR_UNSET,
1549 .audio_inputs = 1, 957 .radio_addr = ADDR_UNSET,
1550 .tuner = 0, 958 .has_remote = 1,
1551 .svhs = 2, 959 },
1552 .gpiomask = 0x0f0f80, 960 [BTTV_BOARD_PINNACLE] = {
1553 .muxsel = {2, 3, 1, 0}, 961 .name = "Pinnacle PCTV Studio/Rave",
1554 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0}, 962 .video_inputs = 3,
1555 .no_msp34xx = 1, 963 .audio_inputs = 1,
1556 .pll = PLL_28, 964 .tuner = 0,
1557 .tuner_type = TUNER_PHILIPS_NTSC_M, 965 .svhs = 2,
1558 .tuner_addr = ADDR_UNSET, 966 .gpiomask = 0x03000F,
1559 .audio_hook = gvbctv5pci_audio, 967 .muxsel = { 2, 3, 1, 1},
1560 .has_radio = 1, 968 .audiomux = { 2, 0xd0001, 0, 0, 1},
1561},{ 969 .needs_tvaudio = 0,
1562 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ 970 .pll = PLL_28,
1563 .video_inputs = 4, /* id-inputs-clock */ 971 .tuner_type = -1,
1564 .audio_inputs = 0, 972 .tuner_addr = ADDR_UNSET,
1565 .tuner = -1, 973 .radio_addr = ADDR_UNSET,
1566 .svhs = 3, 974 },
1567 .muxsel = { 3, 2, 0, 1 }, 975
1568 .pll = PLL_28, 976 /* ---- card 0x28 ---------------------------------- */
1569 .tuner_type = -1, 977 [BTTV_BOARD_STB2] = {
1570 .tuner_addr = ADDR_UNSET, 978 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
1571 .no_msp34xx = 1, 979 .video_inputs = 3,
1572 .no_tda9875 = 1, 980 .audio_inputs = 1,
1573 .no_tda7432 = 1, 981 .tuner = 0,
1574},{ 982 .svhs = 2,
1575 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ 983 .gpiomask = 7,
1576 .video_inputs = 3, 984 .muxsel = { 2, 3, 1, 1},
1577 .audio_inputs = 0, 985 .audiomux = { 4, 0, 2, 3, 1},
1578 .tuner = -1, 986 .no_msp34xx = 1,
1579 .svhs = 2, 987 .needs_tvaudio = 1,
1580 .muxsel = { 2, 3, 1 }, 988 .tuner_type = TUNER_PHILIPS_NTSC,
1581 .pll = PLL_28, 989 .tuner_addr = ADDR_UNSET,
1582 .tuner_type = -1, 990 .radio_addr = ADDR_UNSET,
1583 .tuner_addr = ADDR_UNSET, 991 .pll = PLL_28,
1584 .no_msp34xx = 1, 992 .has_radio = 1,
1585 .no_tda9875 = 1, 993 },
1586 .no_tda7432 = 1, 994 [BTTV_BOARD_AVPHONE98] = {
1587},{ 995 .name = "AVerMedia TVPhone 98",
1588 996 .video_inputs = 3,
1589 /* ---- card 0x54 ---------------------------------- */ 997 .audio_inputs = 4,
1590 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ 998 .tuner = 0,
1591 .video_inputs = 2, 999 .svhs = 2,
1592 .audio_inputs = 0, 1000 .gpiomask = 15,
1593 .tuner = -1, 1001 .muxsel = { 2, 3, 1, 1},
1594 .svhs = 1, 1002 .audiomux = { 13, 4, 11, 7, 0, 0},
1595 .muxsel = { 3, 1 }, 1003 .needs_tvaudio = 1,
1596 .pll = PLL_28, 1004 .pll = PLL_28,
1597 .tuner_type = -1, 1005 .tuner_type = -1,
1598 .tuner_addr = ADDR_UNSET, 1006 .tuner_addr = ADDR_UNSET,
1599 .no_msp34xx = 1, 1007 .radio_addr = ADDR_UNSET,
1600 .no_tda9875 = 1, 1008 .has_radio = 1,
1601 .no_tda7432 = 1, 1009 .audio_hook = avermedia_tvphone_audio,
1602},{ 1010 },
1603 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ 1011 [BTTV_BOARD_PV951] = {
1604 .video_inputs = 1, 1012 .name = "ProVideo PV951", /* pic16c54 */
1605 .audio_inputs = 0, 1013 .video_inputs = 3,
1606 .tuner = -1, 1014 .audio_inputs = 1,
1607 .svhs = -1, 1015 .tuner = 0,
1608 .muxsel = { 0 }, 1016 .svhs = 2,
1609 .pll = PLL_28, 1017 .gpiomask = 0,
1610 .tuner_type = -1, 1018 .muxsel = { 2, 3, 1, 1},
1611 .tuner_addr = ADDR_UNSET, 1019 .audiomux = { 0, 0, 0, 0, 0},
1612 .no_msp34xx = 1, 1020 .needs_tvaudio = 1,
1613 .no_tda9875 = 1, 1021 .no_msp34xx = 1,
1614 .no_tda7432 = 1, 1022 .pll = PLL_28,
1615},{ 1023 .tuner_type = 1,
1616 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ 1024 .tuner_addr = ADDR_UNSET,
1617 .video_inputs = 2, 1025 .radio_addr = ADDR_UNSET,
1618 .audio_inputs = 0, 1026 },
1619 .tuner = -1, 1027 [BTTV_BOARD_ONAIR_TV] = {
1620 .svhs = 1, 1028 .name = "Little OnAir TV",
1621 .muxsel = { 0, 1 }, 1029 .video_inputs = 3,
1622 .pll = PLL_28, 1030 .audio_inputs = 1,
1623 .tuner_type = -1, 1031 .tuner = 0,
1624 .tuner_addr = ADDR_UNSET, 1032 .svhs = 2,
1625 .no_msp34xx = 1, 1033 .gpiomask = 0xe00b,
1626 .no_tda9875 = 1, 1034 .muxsel = {2, 3, 1, 1},
1627 .no_tda7432 = 1, 1035 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
1628},{ 1036 .no_msp34xx = 1,
1629 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ 1037 .tuner_type = -1,
1630 .video_inputs = 1, 1038 .tuner_addr = ADDR_UNSET,
1631 .audio_inputs = 1, 1039 .radio_addr = ADDR_UNSET,
1632 .tuner = -1, 1040 },
1633 .svhs = -1, 1041
1634 .muxsel = { 0 }, 1042 /* ---- card 0x2c ---------------------------------- */
1635 .pll = PLL_28, 1043 [BTTV_BOARD_SIGMA_TVII_FM] = {
1636 .tuner_type = UNSET, 1044 .name = "Sigma TVII-FM",
1637 .tuner_addr = ADDR_UNSET, 1045 .video_inputs = 2,
1638 .no_msp34xx = 1, 1046 .audio_inputs = 1,
1639 .no_tda9875 = 1, 1047 .tuner = 0,
1640 .no_tda7432 = 1, 1048 .svhs = -1,
1641},{ 1049 .gpiomask = 3,
1642 1050 .muxsel = {2, 3, 1, 1},
1643 /* ---- card 0x58 ---------------------------------- */ 1051 .audiomux = {1, 1, 0, 2, 3},
1644 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ 1052 .no_msp34xx = 1,
1645 .video_inputs = 2, 1053 .pll = PLL_NONE,
1646 .audio_inputs = 1, 1054 .tuner_type = -1,
1647 .tuner = -1, 1055 .tuner_addr = ADDR_UNSET,
1648 .svhs = 1, 1056 .radio_addr = ADDR_UNSET,
1649 .muxsel = { 0, 1 }, 1057 },
1650 .pll = PLL_28, 1058 [BTTV_BOARD_MATRIX_VISION2] = {
1651 .tuner_type = UNSET, 1059 .name = "MATRIX-Vision MV-Delta 2",
1652 .tuner_addr = ADDR_UNSET, 1060 .video_inputs = 5,
1653 .no_msp34xx = 1, 1061 .audio_inputs = 1,
1654 .no_tda9875 = 1, 1062 .tuner = -1,
1655 .no_tda7432 = 1, 1063 .svhs = 3,
1656},{ 1064 .gpiomask = 0,
1657 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ 1065 .muxsel = { 2, 3, 1, 0, 0},
1658 .video_inputs = 2, 1066 .audiomux = {0 },
1659 .audio_inputs = 1, 1067 .no_msp34xx = 1,
1660 .tuner = -1, 1068 .pll = PLL_28,
1661 .svhs = 1, 1069 .tuner_type = -1,
1662 .muxsel = { 2, 3 }, 1070 .tuner_addr = ADDR_UNSET,
1663 .pll = PLL_28, 1071 .radio_addr = ADDR_UNSET,
1664 .tuner_type = UNSET, 1072 },
1665 .tuner_addr = ADDR_UNSET, 1073 [BTTV_BOARD_ZOLTRIX_GENIE] = {
1666 .no_msp34xx = 1, 1074 .name = "Zoltrix Genie TV/FM",
1667 .no_tda9875 = 1, 1075 .video_inputs = 3,
1668 .no_tda7432 = 1, 1076 .audio_inputs = 1,
1669},{ 1077 .tuner = 0,
1670 .name = "Osprey 500", /* 500 */ 1078 .svhs = 2,
1671 .video_inputs = 2, 1079 .gpiomask = 0xbcf03f,
1672 .audio_inputs = 1, 1080 .muxsel = { 2, 3, 1, 1},
1673 .tuner = -1, 1081 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
1674 .svhs = 1, 1082 .no_msp34xx = 1,
1675 .muxsel = { 2, 3 }, 1083 .pll = PLL_28,
1676 .pll = PLL_28, 1084 .tuner_type = 21,
1677 .tuner_type = -1, 1085 .tuner_addr = ADDR_UNSET,
1678 .tuner_addr = ADDR_UNSET, 1086 .radio_addr = ADDR_UNSET,
1679 .no_msp34xx = 1, 1087 },
1680 .no_tda9875 = 1, 1088 [BTTV_BOARD_TERRATVRADIO] = {
1681 .no_tda7432 = 1, 1089 .name = "Terratec TV/Radio+",
1682},{ 1090 .video_inputs = 3,
1683 .name = "Osprey 540", /* 540 */ 1091 .audio_inputs = 1,
1684 .video_inputs = 4, 1092 .tuner = 0,
1685 .audio_inputs = 1, 1093 .svhs = 2,
1686 .tuner = -1, 1094 .gpiomask = 0x70000,
1687 .pll = PLL_28, 1095 .muxsel = { 2, 3, 1, 1},
1688 .tuner_type = -1, 1096 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
1689 .tuner_addr = ADDR_UNSET, 1097 .needs_tvaudio = 1,
1690 .no_msp34xx = 1, 1098 .no_msp34xx = 1,
1691 .no_tda9875 = 1, 1099 .pll = PLL_35,
1692 .no_tda7432 = 1, 1100 .tuner_type = 1,
1693},{ 1101 .tuner_addr = ADDR_UNSET,
1694 1102 .radio_addr = ADDR_UNSET,
1695 /* ---- card 0x5C ---------------------------------- */ 1103 .has_radio = 1,
1696 .name = "Osprey 2000", /* 2000 */ 1104 },
1697 .video_inputs = 2, 1105
1698 .audio_inputs = 1, 1106 /* ---- card 0x30 ---------------------------------- */
1699 .tuner = -1, 1107 [BTTV_BOARD_DYNALINK] = {
1700 .svhs = 1, 1108 .name = "Askey CPH03x/ Dynalink Magic TView",
1701 .muxsel = { 2, 3 }, 1109 .video_inputs = 3,
1702 .pll = PLL_28, 1110 .audio_inputs = 1,
1703 .tuner_type = UNSET, 1111 .tuner = 0,
1704 .tuner_addr = ADDR_UNSET, 1112 .svhs = 2,
1705 .no_msp34xx = 1, 1113 .gpiomask = 15,
1706 .no_tda9875 = 1, 1114 .muxsel = { 2, 3, 1, 1},
1707 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ 1115 .audiomux = {2,0,0,0,1},
1708},{ 1116 .needs_tvaudio = 1,
1709 /* M G Berberich <berberic@forwiss.uni-passau.de> */ 1117 .pll = PLL_28,
1710 .name = "IDS Eagle", 1118 .tuner_type = -1,
1711 .video_inputs = 4, 1119 .tuner_addr = ADDR_UNSET,
1712 .audio_inputs = 0, 1120 .radio_addr = ADDR_UNSET,
1713 .tuner = -1, 1121 },
1714 .tuner_type = -1, 1122 [BTTV_BOARD_GVBCTV3PCI] = {
1715 .tuner_addr = ADDR_UNSET, 1123 .name = "IODATA GV-BCTV3/PCI",
1716 .svhs = -1, 1124 .video_inputs = 3,
1717 .gpiomask = 0, 1125 .audio_inputs = 1,
1718 .muxsel = { 0, 1, 2, 3 }, 1126 .tuner = 0,
1719 .muxsel_hook = eagle_muxsel, 1127 .svhs = 2,
1720 .no_msp34xx = 1, 1128 .gpiomask = 0x010f00,
1721 .no_tda9875 = 1, 1129 .muxsel = {2, 3, 0, 0},
1722 .pll = PLL_28, 1130 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1723},{ 1131 .no_msp34xx = 1,
1724 .name = "Pinnacle PCTV Sat", 1132 .pll = PLL_28,
1725 .video_inputs = 2, 1133 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1726 .audio_inputs = 0, 1134 .tuner_addr = ADDR_UNSET,
1727 .svhs = 1, 1135 .radio_addr = ADDR_UNSET,
1728 .tuner = -1, 1136 .audio_hook = gvbctv3pci_audio,
1729 .tuner_type = -1, 1137 },
1730 .tuner_addr = ADDR_UNSET, 1138 [BTTV_BOARD_PXELVWPLTVPAK] = {
1731 .no_msp34xx = 1, 1139 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1732 .no_tda9875 = 1, 1140 .video_inputs = 5,
1733 .no_tda7432 = 1, 1141 .audio_inputs = 1,
1734 .gpiomask = 0x01, 1142 .tuner = 0,
1735 .audiomux = { 0, 0, 0, 0, 1 }, 1143 .svhs = 3,
1736 .muxsel = { 3, 0, 1, 2}, 1144 .gpiomask = 0xAA0000,
1737 .needs_tvaudio = 0, 1145 .muxsel = { 2,3,1,1,-1 },
1738 .pll = PLL_28, 1146 .digital_mode = DIGITAL_MODE_CAMERA,
1739 .no_gpioirq = 1, 1147 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1740 .has_dvb = 1, 1148 .no_msp34xx = 1,
1741},{ 1149 .pll = PLL_28,
1742 .name = "Formac ProTV II (bt878)", 1150 .tuner_type = TUNER_PHILIPS_PAL_I,
1743 .video_inputs = 4, 1151 .tuner_addr = ADDR_UNSET,
1744 .audio_inputs = 1, 1152 .radio_addr = ADDR_UNSET,
1745 .tuner = 0, 1153 .has_remote = 1,
1746 .svhs = 3, 1154 /* GPIO wiring: (different from Rev.4C !)
1747 .gpiomask = 2, 1155 GPIO17: U4.A0 (first hef4052bt)
1748 /* TV, Comp1, Composite over SVID con, SVID */ 1156 GPIO19: U4.A1
1749 .muxsel = { 2, 3, 1, 1}, 1157 GPIO20: U5.A1 (second hef4052bt)
1750 .audiomux = { 2, 2, 0, 0, 0 }, 1158 GPIO21: U4.nEN
1751 .pll = PLL_28, 1159 GPIO22: BT832 Reset Line
1752 .has_radio = 1, 1160 GPIO23: A5,A0, U5,nEN
1753 .tuner_type = TUNER_PHILIPS_PAL, 1161 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1754 .tuner_addr = ADDR_UNSET, 1162 */
1755/* sound routing: 1163 },
1756 GPIO=0x00,0x01,0x03: mute (?) 1164 [BTTV_BOARD_EAGLE] = {
1757 0x02: both TV and radio (tuner: FM1216/I) 1165 .name = "Eagle Wireless Capricorn2 (bt878A)",
1758 The card has onboard audio connectors labeled "cdrom" and "board", 1166 .video_inputs = 4,
1759 not soldered here, though unknown wiring. 1167 .audio_inputs = 1,
1760 Card lacks: external audio in, pci subsystem id. 1168 .tuner = 0,
1761*/ 1169 .svhs = 2,
1762},{ 1170 .gpiomask = 7,
1763 1171 .muxsel = { 2, 0, 1, 1},
1764 /* ---- card 0x60 ---------------------------------- */ 1172 .audiomux = { 0, 1, 2, 3, 4},
1765 .name = "MachTV", 1173 .pll = PLL_28,
1766 .video_inputs = 3, 1174 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1767 .audio_inputs = 1, 1175 .tuner_addr = ADDR_UNSET,
1768 .tuner = 0, 1176 .radio_addr = ADDR_UNSET,
1769 .svhs = -1, 1177 },
1770 .gpiomask = 7, 1178
1771 .muxsel = { 2, 3, 1, 1}, 1179 /* ---- card 0x34 ---------------------------------- */
1772 .audiomux = { 0, 1, 2, 3, 4}, 1180 [BTTV_BOARD_PINNACLEPRO] = {
1773 .needs_tvaudio = 1, 1181 /* David Härdeman <david@2gen.com> */
1774 .tuner_type = 5, 1182 .name = "Pinnacle PCTV Studio Pro",
1775 .tuner_addr = ADDR_UNSET, 1183 .video_inputs = 4,
1776 .pll = 1, 1184 .audio_inputs = 1,
1777},{ 1185 .tuner = 0,
1778 .name = "Euresys Picolo", 1186 .svhs = 3,
1779 .video_inputs = 3, 1187 .gpiomask = 0x03000F,
1780 .audio_inputs = 0, 1188 .muxsel = { 2, 3, 1, 1},
1781 .tuner = -1, 1189 .audiomux = { 1, 0xd0001, 0, 0, 10},
1782 .svhs = 2, 1190 /* sound path (5 sources):
1783 .gpiomask = 0, 1191 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1784 .no_msp34xx = 1, 1192 0= ext. Audio IN
1785 .no_tda9875 = 1, 1193 1= from MUX2
1786 .no_tda7432 = 1, 1194 2= Mono TV sound from Tuner
1787 .muxsel = { 2, 0, 1}, 1195 3= not connected
1788 .pll = PLL_28, 1196 MUX2 (mask 0x30000):
1789 .tuner_type = UNSET, 1197 0,2,3= from MSP34xx
1790 .tuner_addr = ADDR_UNSET, 1198 1= FM stereo Radio from Tuner */
1791},{ 1199 .needs_tvaudio = 0,
1792 /* Luc Van Hoeylandt <luc@e-magic.be> */ 1200 .pll = PLL_28,
1793 .name = "ProVideo PV150", /* 0x4f */ 1201 .tuner_type = -1,
1794 .video_inputs = 2, 1202 .tuner_addr = ADDR_UNSET,
1795 .audio_inputs = 0, 1203 .radio_addr = ADDR_UNSET,
1796 .tuner = -1, 1204 },
1797 .svhs = -1, 1205 [BTTV_BOARD_TVIEW_RDS_FM] = {
1798 .gpiomask = 0, 1206 /* Claas Langbehn <claas@bigfoot.com>,
1799 .muxsel = { 2, 3 }, 1207 Sven Grothklags <sven@upb.de> */
1800 .audiomux = { 0 }, 1208 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1801 .needs_tvaudio = 0, 1209 .video_inputs = 4,
1802 .no_msp34xx = 1, 1210 .audio_inputs = 3,
1803 .pll = PLL_28, 1211 .tuner = 0,
1804 .tuner_type = UNSET, 1212 .svhs = 2,
1805 .tuner_addr = ADDR_UNSET, 1213 .gpiomask = 0x1c,
1806},{ 1214 .muxsel = { 2, 3, 1, 1},
1807 /* Hiroshi Takekawa <sian@big.or.jp> */ 1215 .audiomux = { 0, 0, 0x10, 8, 4 },
1808 /* This card lacks subsystem ID */ 1216 .needs_tvaudio = 1,
1809 .name = "AD-TVK503", /* 0x63 */ 1217 .pll = PLL_28,
1810 .video_inputs = 4, 1218 .tuner_type = TUNER_PHILIPS_PAL,
1811 .audio_inputs = 1, 1219 .tuner_addr = ADDR_UNSET,
1812 .tuner = 0, 1220 .radio_addr = ADDR_UNSET,
1813 .svhs = 2, 1221 .has_radio = 1,
1814 .gpiomask = 0x001e8007, 1222 },
1815 .muxsel = { 2, 3, 1, 0 }, 1223 [BTTV_BOARD_LIFETEC_9415] = {
1816 /* Tuner, Radio, external, internal, off, on */ 1224 /* Tim Röstermundt <rosterm@uni-muenster.de>
1817 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, 1225 in de.comp.os.unix.linux.hardware:
1818 .needs_tvaudio = 0, 1226 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1819 .no_msp34xx = 1, 1227 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1820 .pll = PLL_28, 1228 options tuner type=5 */
1821 .tuner_type = 2, 1229 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1822 .tuner_addr = ADDR_UNSET, 1230 .video_inputs = 4,
1823 .audio_hook = adtvk503_audio, 1231 .audio_inputs = 1,
1824},{ 1232 .tuner = 0,
1825 1233 .svhs = 2,
1826 /* ---- card 0x64 ---------------------------------- */ 1234 .gpiomask = 0x18e0,
1827 .name = "Hercules Smart TV Stereo", 1235 .muxsel = { 2, 3, 1, 1},
1828 .video_inputs = 4, 1236 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1829 .audio_inputs = 1, 1237 /* For cards with tda9820/tda9821:
1830 .tuner = 0, 1238 0x0000: Tuner normal stereo
1831 .svhs = 2, 1239 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1832 .gpiomask = 0x00, 1240 0x0880: Tuner A2 stereo */
1833 .muxsel = { 2, 3, 1, 1 }, 1241 .pll = PLL_28,
1834 .needs_tvaudio = 1, 1242 .tuner_type = -1,
1835 .no_msp34xx = 1, 1243 .tuner_addr = ADDR_UNSET,
1836 .pll = PLL_28, 1244 .radio_addr = ADDR_UNSET,
1837 .tuner_type = 5, 1245 },
1838 .tuner_addr = ADDR_UNSET, 1246 [BTTV_BOARD_BESTBUY_EASYTV] = {
1839 /* Notes: 1247 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1840 - card lacks subsystem ID 1248 old Easy TV BT848 version (model CPH031) */
1841 - stereo variant w/ daughter board with tda9874a @0xb0 1249 .name = "Askey CPH031/ BESTBUY Easy TV",
1842 - Audio Routing: 1250 .video_inputs = 4,
1843 always from tda9874 independent of GPIO (?) 1251 .audio_inputs = 1,
1844 external line in: unknown 1252 .tuner = 0,
1845 - Other chips: em78p156elp @ 0x96 (probably IR remote control) 1253 .svhs = 2,
1846 hef4053 (instead 4052) for unknown function 1254 .gpiomask = 0xF,
1847 */ 1255 .muxsel = { 2, 3, 1, 0},
1848},{ 1256 .audiomux = { 2, 0, 0, 0, 10},
1849 .name = "Pace TV & Radio Card", 1257 .needs_tvaudio = 0,
1850 .video_inputs = 4, 1258 .pll = PLL_28,
1851 .audio_inputs = 1, 1259 .tuner_type = TUNER_TEMIC_PAL,
1852 .tuner = 0, 1260 .tuner_addr = ADDR_UNSET,
1853 .svhs = 2, 1261 .radio_addr = ADDR_UNSET,
1854 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */ 1262 },
1855 .gpiomask = 0, 1263
1856 .no_tda9875 = 1, 1264 /* ---- card 0x38 ---------------------------------- */
1857 .no_tda7432 = 1, 1265 [BTTV_BOARD_FLYVIDEO_98FM] = {
1858 .tuner_type = 1, 1266 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1859 .tuner_addr = ADDR_UNSET, 1267 .name = "Lifeview FlyVideo 98FM LR50",
1860 .has_radio = 1, 1268 .video_inputs = 4,
1861 .pll = PLL_28, 1269 .audio_inputs = 3,
1862 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id 1270 .tuner = 0,
1863 only internal line out: (4pin header) RGGL 1271 .svhs = 2,
1864 Radio must be decoded by msp3410d (not routed through)*/ 1272 .gpiomask = 0x1800,
1865 /* 1273 .muxsel = { 2, 3, 1, 1},
1866 .digital_mode = DIGITAL_MODE_CAMERA, todo! 1274 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1867 */ 1275 .pll = PLL_28,
1868},{ 1276 .tuner_type = 5,
1869 /* Chris Willing <chris@vislab.usyd.edu.au> */ 1277 .tuner_addr = ADDR_UNSET,
1870 .name = "IVC-200", 1278 .radio_addr = ADDR_UNSET,
1871 .video_inputs = 1, 1279 },
1872 .audio_inputs = 0, 1280 /* This is the ultimate cheapo capture card
1873 .tuner = -1, 1281 * just a BT848A on a small PCB!
1874 .tuner_type = -1, 1282 * Steve Hosgood <steve@equiinet.com> */
1875 .tuner_addr = ADDR_UNSET, 1283 [BTTV_BOARD_GRANDTEC] = {
1876 .svhs = -1, 1284 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1877 .gpiomask = 0xdf, 1285 .video_inputs = 2,
1878 .muxsel = { 2 }, 1286 .audio_inputs = 0,
1879 .pll = PLL_28, 1287 .tuner = -1,
1880},{ 1288 .svhs = 1,
1881 .name = "Grand X-Guard / Trust 814PCI", 1289 .gpiomask = 0,
1882 .video_inputs = 16, 1290 .muxsel = { 3, 1 },
1883 .audio_inputs = 0, 1291 .audiomux = { 0 },
1884 .tuner = -1, 1292 .needs_tvaudio = 0,
1885 .svhs = -1, 1293 .no_msp34xx = 1,
1886 .tuner_type = 4, 1294 .pll = PLL_35,
1887 .tuner_addr = ADDR_UNSET, 1295 .tuner_type = -1,
1888 .gpiomask2 = 0xff, 1296 .tuner_addr = ADDR_UNSET,
1889 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, 1297 .radio_addr = ADDR_UNSET,
1890 .muxsel_hook = xguard_muxsel, 1298 },
1891 .no_msp34xx = 1, 1299 [BTTV_BOARD_ASKEY_CPH060] = {
1892 .no_tda9875 = 1, 1300 /* Daniel Herrington <daniel.herrington@home.com> */
1893 .no_tda7432 = 1, 1301 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1894 .pll = PLL_28, 1302 .video_inputs = 3,
1895},{ 1303 .audio_inputs = 1,
1896 1304 .tuner = 0,
1897 /* ---- card 0x68 ---------------------------------- */ 1305 .svhs = 2,
1898 .name = "Nebula Electronics DigiTV", 1306 .gpiomask = 0xe00,
1899 .video_inputs = 1, 1307 .muxsel = { 2, 3, 1, 1},
1900 .tuner = -1, 1308 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1901 .svhs = -1, 1309 .needs_tvaudio = 1,
1902 .muxsel = { 2, 3, 1, 0}, 1310 .pll = PLL_28,
1903 .no_msp34xx = 1, 1311 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1904 .no_tda9875 = 1, 1312 .tuner_addr = ADDR_UNSET,
1905 .no_tda7432 = 1, 1313 .radio_addr = ADDR_UNSET,
1906 .pll = PLL_28, 1314 },
1907 .tuner_type = -1, 1315 [BTTV_BOARD_ASKEY_CPH03X] = {
1908 .tuner_addr = ADDR_UNSET, 1316 /* Matti Mottus <mottus@physic.ut.ee> */
1909 .has_dvb = 1, 1317 .name = "Askey CPH03x TV Capturer",
1910 .no_gpioirq = 1, 1318 .video_inputs = 4,
1911},{ 1319 .audio_inputs = 1,
1912 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ 1320 .tuner = 0,
1913 .name = "ProVideo PV143", 1321 .svhs = 2,
1914 .video_inputs = 4, 1322 .gpiomask = 0x03000F,
1915 .audio_inputs = 0, 1323 .muxsel = { 2, 3, 1, 0},
1916 .tuner = -1, 1324 .audiomux = { 2,0,0,0,1 },
1917 .svhs = -1, 1325 .pll = PLL_28,
1918 .gpiomask = 0, 1326 .tuner_type = 0,
1919 .muxsel = { 2, 3, 1, 0 }, 1327 .tuner_addr = ADDR_UNSET,
1920 .audiomux = { 0 }, 1328 .radio_addr = ADDR_UNSET,
1921 .needs_tvaudio = 0, 1329 },
1922 .no_msp34xx = 1, 1330
1923 .pll = PLL_28, 1331 /* ---- card 0x3c ---------------------------------- */
1924 .tuner_type = -1, 1332 [BTTV_BOARD_MM100PCTV] = {
1925 .tuner_addr = ADDR_UNSET, 1333 /* Philip Blundell <philb@gnu.org> */
1926},{ 1334 .name = "Modular Technology MM100PCTV",
1927 /* M.Klahr@phytec.de */ 1335 .video_inputs = 2,
1928 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", 1336 .audio_inputs = 2,
1929 .video_inputs = 4, 1337 .tuner = 0,
1930 .audio_inputs = 0, 1338 .svhs = -1,
1931 .tuner = -1, /* card has no tuner */ 1339 .gpiomask = 11,
1932 .svhs = 3, 1340 .muxsel = { 2, 3, 1, 1},
1933 .gpiomask = 0x00, 1341 .audiomux = { 2, 0, 0, 1, 8},
1934 .muxsel = { 2, 3, 1, 0}, 1342 .pll = PLL_35,
1935 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1343 .tuner_type = TUNER_TEMIC_PAL,
1936 .needs_tvaudio = 1, 1344 .tuner_addr = ADDR_UNSET,
1937 .pll = PLL_28, 1345 .radio_addr = ADDR_UNSET,
1938 .tuner_type = -1, 1346 },
1939 .tuner_addr = ADDR_UNSET, 1347 [BTTV_BOARD_GMV1] = {
1940},{ 1348 /* Adrian Cox <adrian@humboldt.co.uk */
1941 .name = "PHYTEC VD-009-X1 Combi (bt878)", 1349 .name = "AG Electronics GMV1",
1942 .video_inputs = 4, 1350 .video_inputs = 2,
1943 .audio_inputs = 0, 1351 .audio_inputs = 0,
1944 .tuner = -1, /* card has no tuner */ 1352 .tuner = -1,
1945 .svhs = 3, 1353 .svhs = 1,
1946 .gpiomask = 0x00, 1354 .gpiomask = 0xF,
1947 .muxsel = { 2, 3, 1, 1}, 1355 .muxsel = { 2, 2},
1948 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1356 .audiomux = { },
1949 .needs_tvaudio = 1, 1357 .no_msp34xx = 1,
1950 .pll = PLL_28, 1358 .needs_tvaudio = 0,
1951 .tuner_type = -1, 1359 .pll = PLL_28,
1952 .tuner_addr = ADDR_UNSET, 1360 .tuner_type = -1,
1953},{ 1361 .tuner_addr = ADDR_UNSET,
1954 1362 .radio_addr = ADDR_UNSET,
1955 /* ---- card 0x6c ---------------------------------- */ 1363 },
1956 .name = "PHYTEC VD-009 MiniDIN (bt878)", 1364 [BTTV_BOARD_BESTBUY_EASYTV2] = {
1957 .video_inputs = 10, 1365 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1958 .audio_inputs = 0, 1366 new Easy TV BT878 version (model CPH061)
1959 .tuner = -1, /* card has no tuner */ 1367 special thanks to Informatica Mieres for providing the card */
1960 .svhs = 9, 1368 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1961 .gpiomask = 0x00, 1369 .video_inputs = 3,
1962 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1370 .audio_inputs = 2,
1963 via the upper nibble of muxsel. here: used for 1371 .tuner = 0,
1964 xternal video-mux */ 1372 .svhs = 2,
1965 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, 1373 .gpiomask = 0xFF,
1966 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1374 .muxsel = { 2, 3, 1, 0},
1967 .needs_tvaudio = 1, 1375 .audiomux = { 1, 0, 4, 4, 9},
1968 .pll = PLL_28, 1376 .needs_tvaudio = 0,
1969 .tuner_type = -1, 1377 .pll = PLL_28,
1970 .tuner_addr = ADDR_UNSET, 1378 .tuner_type = TUNER_PHILIPS_PAL,
1971},{ 1379 .tuner_addr = ADDR_UNSET,
1972 .name = "PHYTEC VD-009 Combi (bt878)", 1380 .radio_addr = ADDR_UNSET,
1973 .video_inputs = 10, 1381 },
1974 .audio_inputs = 0, 1382 [BTTV_BOARD_ATI_TVWONDER] = {
1975 .tuner = -1, /* card has no tuner */ 1383 /* Lukas Gebauer <geby@volny.cz> */
1976 .svhs = 9, 1384 .name = "ATI TV-Wonder",
1977 .gpiomask = 0x00, 1385 .video_inputs = 3,
1978 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1386 .audio_inputs = 1,
1979 via the upper nibble of muxsel. here: used for 1387 .tuner = 0,
1980 xternal video-mux */ 1388 .svhs = 2,
1981 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, 1389 .gpiomask = 0xf03f,
1982 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1390 .muxsel = { 2, 3, 1, 0 },
1983 .needs_tvaudio = 1, 1391 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1984 .pll = PLL_28, 1392 .pll = PLL_28,
1985 .tuner_type = -1, 1393 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1986 .tuner_addr = ADDR_UNSET, 1394 .tuner_addr = ADDR_UNSET,
1987},{ 1395 .radio_addr = ADDR_UNSET,
1988 .name = "IVC-100", 1396 },
1989 .video_inputs = 4, 1397
1990 .audio_inputs = 0, 1398 /* ---- card 0x40 ---------------------------------- */
1991 .tuner = -1, 1399 [BTTV_BOARD_ATI_TVWONDERVE] = {
1992 .tuner_type = -1, 1400 /* Lukas Gebauer <geby@volny.cz> */
1993 .tuner_addr = ADDR_UNSET, 1401 .name = "ATI TV-Wonder VE",
1994 .svhs = -1, 1402 .video_inputs = 2,
1995 .gpiomask = 0xdf, 1403 .audio_inputs = 1,
1996 .muxsel = { 2, 3, 1, 0 }, 1404 .tuner = 0,
1997 .pll = PLL_28, 1405 .svhs = -1,
1998},{ 1406 .gpiomask = 1,
1999 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ 1407 .muxsel = { 2, 3, 0, 1},
2000 .name = "IVC-120G", 1408 .audiomux = { 0, 0, 1, 0, 0},
2001 .video_inputs = 16, 1409 .no_msp34xx = 1,
2002 .audio_inputs = 0, /* card has no audio */ 1410 .pll = PLL_28,
2003 .tuner = -1, /* card has no tuner */ 1411 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
2004 .tuner_type = -1, 1412 .tuner_addr = ADDR_UNSET,
2005 .tuner_addr = ADDR_UNSET, 1413 .radio_addr = ADDR_UNSET,
2006 .svhs = -1, /* card has no svhs */ 1414 },
2007 .needs_tvaudio = 0, 1415 [BTTV_BOARD_FLYVIDEO2000] = {
2008 .no_msp34xx = 1, 1416 /* DeeJay <deejay@westel900.net (2000S) */
2009 .no_tda9875 = 1, 1417 .name = "Lifeview FlyVideo 2000S LR90",
2010 .no_tda7432 = 1, 1418 .video_inputs = 3,
2011 .gpiomask = 0x00, 1419 .audio_inputs = 3,
2012 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 1420 .tuner = 0,
2013 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, 1421 .svhs = 2,
2014 .muxsel_hook = ivc120_muxsel, 1422 .gpiomask = 0x18e0,
2015 .pll = PLL_28, 1423 .muxsel = { 2, 3, 0, 1},
2016},{ 1424 /* Radio changed from 1e80 to 0x800 to make
2017 1425 FlyVideo2000S in .hu happy (gm)*/
2018 /* ---- card 0x70 ---------------------------------- */ 1426 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
2019 .name = "pcHDTV HD-2000 TV", 1427 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
2020 .video_inputs = 4, 1428 .audio_hook = fv2000s_audio,
2021 .audio_inputs = 1, 1429 .no_msp34xx = 1,
2022 .tuner = 0, 1430 .no_tda9875 = 1,
2023 .svhs = 2, 1431 .needs_tvaudio = 1,
2024 .muxsel = { 2, 3, 1, 0}, 1432 .pll = PLL_28,
2025 .tuner_type = TUNER_PHILIPS_ATSC, 1433 .tuner_type = 5,
2026 .tuner_addr = ADDR_UNSET, 1434 .tuner_addr = ADDR_UNSET,
2027 .has_dvb = 1, 1435 .radio_addr = ADDR_UNSET,
2028},{ 1436 },
2029 .name = "Twinhan DST + clones", 1437 [BTTV_BOARD_TERRATVALUER] = {
2030 .no_msp34xx = 1, 1438 .name = "Terratec TValueRadio",
2031 .no_tda9875 = 1, 1439 .video_inputs = 3,
2032 .no_tda7432 = 1, 1440 .audio_inputs = 1,
2033 .tuner_type = TUNER_ABSENT, 1441 .tuner = 0,
2034 .tuner_addr = ADDR_UNSET, 1442 .svhs = 2,
2035 .no_video = 1, 1443 .gpiomask = 0xffff00,
2036 .has_dvb = 1, 1444 .muxsel = { 2, 3, 1, 1},
2037},{ 1445 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
2038 .name = "Winfast VC100", 1446 .needs_tvaudio = 1,
2039 .video_inputs = 3, 1447 .pll = PLL_28,
2040 .audio_inputs = 0, 1448 .tuner_type = TUNER_PHILIPS_PAL,
2041 .svhs = 1, 1449 .tuner_addr = ADDR_UNSET,
2042 .tuner = -1, 1450 .radio_addr = ADDR_UNSET,
2043 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */ 1451 .has_radio = 1,
2044 .no_msp34xx = 1, 1452 },
2045 .no_tda9875 = 1, 1453 [BTTV_BOARD_GVBCTV4PCI] = {
2046 .no_tda7432 = 1, 1454 /* TANAKA Kei <peg00625@nifty.com> */
2047 .tuner_type = TUNER_ABSENT, 1455 .name = "IODATA GV-BCTV4/PCI",
2048 .tuner_addr = ADDR_UNSET, 1456 .video_inputs = 3,
2049 .pll = PLL_28, 1457 .audio_inputs = 1,
2050},{ 1458 .tuner = 0,
2051 .name = "Teppro TEV-560/InterVision IV-560", 1459 .svhs = 2,
2052 .video_inputs = 3, 1460 .gpiomask = 0x010f00,
2053 .audio_inputs = 1, 1461 .muxsel = {2, 3, 0, 0},
2054 .tuner = 0, 1462 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
2055 .svhs = 2, 1463 .no_msp34xx = 1,
2056 .gpiomask = 3, 1464 .pll = PLL_28,
2057 .muxsel = { 2, 3, 1, 1}, 1465 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
2058 .audiomux = { 1, 1, 1, 1, 0}, 1466 .tuner_addr = ADDR_UNSET,
2059 .needs_tvaudio = 1, 1467 .radio_addr = ADDR_UNSET,
2060 .tuner_type = TUNER_PHILIPS_PAL, 1468 .audio_hook = gvbctv3pci_audio,
2061 .tuner_addr = ADDR_UNSET, 1469 },
2062 .pll = PLL_35, 1470
2063},{ 1471 /* ---- card 0x44 ---------------------------------- */
2064 1472 [BTTV_BOARD_VOODOOTV_FM] = {
2065 /* ---- card 0x74 ---------------------------------- */ 1473 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
2066 .name = "SIMUS GVC1100", 1474 /* try "insmod msp3400 simple=0" if you have
2067 .video_inputs = 4, 1475 * sound problems with this card. */
2068 .audio_inputs = 0, 1476 .video_inputs = 4,
2069 .tuner = -1, 1477 .audio_inputs = 1,
2070 .svhs = -1, 1478 .tuner = 0,
2071 .tuner_type = -1, 1479 .svhs = -1,
2072 .tuner_addr = ADDR_UNSET, 1480 .gpiomask = 0x4f8a00,
2073 .pll = PLL_28, 1481 /* 0x100000: 1=MSP enabled (0=disable again)
2074 .muxsel = { 2, 2, 2, 2}, 1482 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
2075 .gpiomask = 0x3F, 1483 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
2076 .muxsel_hook = gvc1100_muxsel, 1484 /* tvtuner, radio, external,internal, mute, stereo
2077},{ 1485 * tuner, Composit, SVid, Composit-on-Svid-adapter */
2078 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ 1486 .muxsel = { 2, 3 ,0 ,1},
2079 .name = "NGS NGSTV+", 1487 .tuner_type = TUNER_MT2032,
2080 .video_inputs = 3, 1488 .tuner_addr = ADDR_UNSET,
2081 .tuner = 0, 1489 .radio_addr = ADDR_UNSET,
2082 .svhs = 2, 1490 .pll = PLL_28,
2083 .gpiomask = 0x008007, 1491 .has_radio = 1,
2084 .muxsel = {2, 3, 0, 0}, 1492 },
2085 .audiomux = {0, 0, 0, 0, 0x000003, 0}, 1493 [BTTV_BOARD_AIMMS] = {
2086 .pll = PLL_28, 1494 /* Philip Blundell <pb@nexus.co.uk> */
2087 .tuner_type = TUNER_PHILIPS_PAL, 1495 .name = "Active Imaging AIMMS",
2088 .tuner_addr = ADDR_UNSET, 1496 .video_inputs = 1,
2089 .has_remote = 1, 1497 .audio_inputs = 0,
2090},{ 1498 .tuner = -1,
2091 /* http://linuxmedialabs.com */ 1499 .tuner_type = -1,
2092 .name = "LMLBT4", 1500 .tuner_addr = ADDR_UNSET,
2093 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ 1501 .radio_addr = ADDR_UNSET,
2094 .audio_inputs = 0, 1502 .pll = PLL_28,
2095 .tuner = -1, 1503 .muxsel = { 2 },
2096 .svhs = -1, 1504 .gpiomask = 0
2097 .muxsel = { 2, 3, 1, 0 }, 1505 },
2098 .no_msp34xx = 1, 1506 [BTTV_BOARD_PV_BT878P_PLUS] = {
2099 .no_tda9875 = 1, 1507 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
2100 .no_tda7432 = 1, 1508 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
2101 .needs_tvaudio = 0, 1509 .video_inputs = 3,
2102 .tuner_type = -1, 1510 .audio_inputs = 4,
2103 .tuner_addr = ADDR_UNSET, 1511 .tuner = 0,
2104},{ 1512 .svhs = 2,
2105 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ 1513 .gpiomask = 15,
2106 .name = "Tekram M205 PRO", 1514 .muxsel = { 2, 3, 1, 1},
2107 .video_inputs = 3, 1515 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
2108 .audio_inputs = 1, 1516 .needs_tvaudio = 1,
2109 .tuner = 0, 1517 .pll = PLL_28,
2110 .tuner_type = TUNER_PHILIPS_PAL, 1518 .tuner_type = 25,
2111 .tuner_addr = ADDR_UNSET, 1519 .tuner_addr = ADDR_UNSET,
2112 .svhs = 2, 1520 .radio_addr = ADDR_UNSET,
2113 .needs_tvaudio = 0, 1521 .has_remote = 1,
2114 .gpiomask = 0x68, 1522 /* GPIO wiring:
2115 .muxsel = { 2, 3, 1}, 1523 GPIO0: U4.A0 (hef4052bt)
2116 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 }, 1524 GPIO1: U4.A1
2117 .pll = PLL_28, 1525 GPIO2: U4.A1 (second hef4052bt)
2118},{ 1526 GPIO3: U4.nEN, U5.A0, A5.nEN
2119 1527 GPIO8-15: vrd866b ?
2120 /* ---- card 0x78 ---------------------------------- */ 1528 */
2121 /* Javier Cendan Ares <jcendan@lycos.es> */ 1529 },
2122 /* bt878 TV + FM without subsystem ID */ 1530 [BTTV_BOARD_FLYVIDEO98EZ] = {
2123 .name = "Conceptronic CONTVFMi", 1531 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
2124 .video_inputs = 3, 1532 .video_inputs = 4,
2125 .audio_inputs = 1, 1533 .audio_inputs = 0,
2126 .tuner = 0, 1534 .tuner = -1,
2127 .svhs = 2, 1535 .svhs = 2,
2128 .gpiomask = 0x008007, 1536 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
2129 .muxsel = { 2, 3, 1, 1 }, 1537 .pll = PLL_28,
2130 .audiomux = { 0, 1, 2, 2, 3 }, 1538 .no_msp34xx = 1,
2131 .needs_tvaudio = 0, 1539 .tuner_type = UNSET,
2132 .pll = PLL_28, 1540 .tuner_addr = ADDR_UNSET,
2133 .tuner_type = TUNER_PHILIPS_PAL, 1541 .radio_addr = ADDR_UNSET,
2134 .tuner_addr = ADDR_UNSET, 1542 },
2135 .has_remote = 1, 1543
2136 .has_radio = 1, 1544 /* ---- card 0x48 ---------------------------------- */
2137},{ 1545 [BTTV_BOARD_PV_BT878P_9B] = {
2138 /*Eric DEBIEF <debief@telemsa.com>*/ 1546 /* Dariusz Kowalewski <darekk@automex.pl> */
2139 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ 1547 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
2140 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/ 1548 .video_inputs = 4,
2141 /*0x79 in bttv.h*/ 1549 .audio_inputs = 1,
2142 .name = "Euresys Picolo Tetra", 1550 .tuner = 0,
2143 .video_inputs = 4, 1551 .svhs = 2,
2144 .audio_inputs = 0, 1552 .gpiomask = 0x3f,
2145 .tuner = -1, 1553 .muxsel = { 2, 3, 1, 1 },
2146 .svhs = -1, 1554 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
2147 .gpiomask = 0, 1555 .needs_tvaudio = 1,
2148 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ 1556 .no_msp34xx = 1,
2149 .no_msp34xx = 1, 1557 .no_tda9875 = 1,
2150 .no_tda9875 = 1, 1558 .pll = PLL_28,
2151 .no_tda7432 = 1, 1559 .tuner_type = 5,
2152 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ 1560 .tuner_addr = ADDR_UNSET,
2153 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1561 .radio_addr = ADDR_UNSET,
2154 .pll = PLL_28, 1562 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
2155 .needs_tvaudio = 0, 1563 .has_radio = 1, /* Note: not all cards have radio */
2156 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ 1564 .has_remote = 1,
2157 .tuner_type = -1, 1565 /* GPIO wiring:
2158 .tuner_addr = ADDR_UNSET, 1566 GPIO0: A0 hef4052
2159},{ 1567 GPIO1: A1 hef4052
2160 /* Spirit TV Tuner from http://spiritmodems.com.au */ 1568 GPIO3: nEN hef4052
2161 /* Stafford Goodsell <surge@goliath.homeunix.org> */ 1569 GPIO8-15: vrd866b
2162 .name = "Spirit TV Tuner", 1570 GPIO20,22,23: R30,R29,R28
2163 .video_inputs = 3, 1571 */
2164 .audio_inputs = 1, 1572 },
2165 .tuner = 0, 1573 [BTTV_BOARD_SENSORAY311] = {
2166 .svhs = 2, 1574 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
2167 .gpiomask = 0x0000000f, 1575 /* you must jumper JP5 for the card to work */
2168 .muxsel = { 2, 1, 1 }, 1576 .name = "Sensoray 311",
2169 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, 1577 .video_inputs = 5,
2170 .tuner_type = TUNER_TEMIC_PAL, 1578 .audio_inputs = 0,
2171 .tuner_addr = ADDR_UNSET, 1579 .tuner = -1,
2172 .no_msp34xx = 1, 1580 .svhs = 4,
2173 .no_tda9875 = 1, 1581 .gpiomask = 0,
2174},{ 1582 .muxsel = { 2, 3, 1, 0, 0},
2175 /* Wolfram Joost <wojo@frokaschwei.de> */ 1583 .audiomux = { 0 },
2176 .name = "AVerMedia AVerTV DVB-T 771", 1584 .needs_tvaudio = 0,
2177 .video_inputs = 2, 1585 .tuner_type = -1,
2178 .svhs = 1, 1586 .tuner_addr = ADDR_UNSET,
2179 .tuner = -1, 1587 .radio_addr = ADDR_UNSET,
2180 .tuner_type = TUNER_ABSENT, 1588 },
2181 .tuner_addr = ADDR_UNSET, 1589 [BTTV_BOARD_RV605] = {
2182 .muxsel = { 3 , 3 }, 1590 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
2183 .no_msp34xx = 1, 1591 .name = "RemoteVision MX (RV605)",
2184 .no_tda9875 = 1, 1592 .video_inputs = 16,
2185 .no_tda7432 = 1, 1593 .audio_inputs = 0,
2186 .pll = PLL_28, 1594 .tuner = -1,
2187 .has_dvb = 1, 1595 .svhs = -1,
2188 .no_gpioirq = 1, 1596 .gpiomask = 0x00,
2189 .has_remote = 1, 1597 .gpiomask2 = 0x07ff,
2190},{ 1598 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
2191 /* ---- card 0x7c ---------------------------------- */ 1599 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
2192 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ 1600 .no_msp34xx = 1,
2193 /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */ 1601 .no_tda9875 = 1,
2194 .name = "AverMedia AverTV DVB-T 761", 1602 .tuner_type = -1,
2195 .video_inputs = 2, 1603 .tuner_addr = ADDR_UNSET,
2196 .tuner = -1, 1604 .radio_addr = ADDR_UNSET,
2197 .svhs = 1, 1605 .muxsel_hook = rv605_muxsel,
2198 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ 1606 },
2199 .no_msp34xx = 1, 1607 [BTTV_BOARD_POWERCLR_MTV878] = {
2200 .no_tda9875 = 1, 1608 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
2201 .no_tda7432 = 1, 1609 .video_inputs = 3,
2202 .pll = PLL_28, 1610 .audio_inputs = 2,
2203 .tuner_type = -1, 1611 .tuner = 0,
2204 .tuner_addr = ADDR_UNSET, 1612 .svhs = 2,
2205 .has_dvb = 1, 1613 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
2206 .no_gpioirq = 1, 1614 .muxsel = { 2, 1, 1, },
2207 .has_remote = 1, 1615 .audiomux = { 0, 1, 2, 2, 4 },
2208},{ 1616 .needs_tvaudio = 0,
2209 /* andre.schwarz@matrix-vision.de */ 1617 .tuner_type = TUNER_PHILIPS_PAL,
2210 .name = "MATRIX Vision Sigma-SQ", 1618 .tuner_addr = ADDR_UNSET,
2211 .video_inputs = 16, 1619 .radio_addr = ADDR_UNSET,
2212 .audio_inputs = 0, 1620 .pll = PLL_28,
2213 .tuner = -1, 1621 .has_radio = 1,
2214 .svhs = -1, 1622 },
2215 .gpiomask = 0x0, 1623
2216 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 1624 /* ---- card 0x4c ---------------------------------- */
2217 3, 3, 3, 3, 3, 3, 3, 3 }, 1625 [BTTV_BOARD_WINDVR] = {
2218 .muxsel_hook = sigmaSQ_muxsel, 1626 /* Masaki Suzuki <masaki@btree.org> */
2219 .audiomux = { 0 }, 1627 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
2220 .no_msp34xx = 1, 1628 .video_inputs = 3,
2221 .pll = PLL_28, 1629 .audio_inputs = 1,
2222 .tuner_type = -1, 1630 .tuner = 0,
2223 .tuner_addr = ADDR_UNSET, 1631 .svhs = 2,
2224},{ 1632 .gpiomask = 0x140007,
2225 /* andre.schwarz@matrix-vision.de */ 1633 .muxsel = { 2, 3, 1, 1 },
2226 .name = "MATRIX Vision Sigma-SLC", 1634 .audiomux = { 0, 1, 2, 3, 4, 0 },
2227 .video_inputs = 4, 1635 .tuner_type = TUNER_PHILIPS_NTSC,
2228 .audio_inputs = 0, 1636 .tuner_addr = ADDR_UNSET,
2229 .tuner = -1, 1637 .radio_addr = ADDR_UNSET,
2230 .svhs = -1, 1638 .audio_hook = windvr_audio,
2231 .gpiomask = 0x0, 1639 },
2232 .muxsel = { 2, 2, 2, 2 }, 1640 [BTTV_BOARD_GRANDTEC_MULTI] = {
2233 .muxsel_hook = sigmaSLC_muxsel, 1641 .name = "GrandTec Multi Capture Card (Bt878)",
2234 .audiomux = { 0 }, 1642 .video_inputs = 4,
2235 .no_msp34xx = 1, 1643 .audio_inputs = 0,
2236 .pll = PLL_28, 1644 .tuner = -1,
2237 .tuner_type = -1, 1645 .svhs = -1,
2238 .tuner_addr = ADDR_UNSET, 1646 .gpiomask = 0,
2239},{ 1647 .muxsel = { 2, 3, 1, 0 },
2240 /* BTTV_APAC_VIEWCOMP */ 1648 .audiomux = { 0 },
2241 /* Attila Kondoros <attila.kondoros@chello.hu> */ 1649 .needs_tvaudio = 0,
2242 /* bt878 TV + FM 0x00000000 subsystem ID */ 1650 .no_msp34xx = 1,
2243 .name = "APAC Viewcomp 878(AMAX)", 1651 .pll = PLL_28,
2244 .video_inputs = 2, 1652 .tuner_type = -1,
2245 .audio_inputs = 1, 1653 .tuner_addr = ADDR_UNSET,
2246 .tuner = 0, 1654 .radio_addr = ADDR_UNSET,
2247 .svhs = -1, 1655 },
2248 .gpiomask = 0xFF, 1656 [BTTV_BOARD_KWORLD] = {
2249 .muxsel = { 2, 3, 1, 1}, 1657 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
2250 .audiomux = { 2, 0, 0, 0, 10}, 1658 .video_inputs = 4,
2251 .needs_tvaudio = 0, 1659 .audio_inputs = 3,
2252 .pll = PLL_28, 1660 .tuner = 0,
2253 .tuner_type = TUNER_PHILIPS_PAL, 1661 .svhs = 2,
2254 .tuner_addr = ADDR_UNSET, 1662 .gpiomask = 7,
2255 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ 1663 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
2256 .has_radio = 1, /* not every card has radio */ 1664 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
2257},{ 1665 * This card lacks external Audio In, so we mute it on Ext. & Int.
2258 1666 * The PCB can take a sbx1637/sbx1673, wiring unknown.
2259 /* ---- card 0x80 ---------------------------------- */ 1667 * This card lacks PCI subsystem ID, sigh.
2260 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ 1668 * audiomux=1: lower volume, 2+3: mute
2261 .name = "DViCO FusionHDTV DVB-T Lite", 1669 * btwincap uses 0x80000/0x80003
2262 .tuner = -1, 1670 */
2263 .no_msp34xx = 1, 1671 .needs_tvaudio = 0,
2264 .no_tda9875 = 1, 1672 .no_msp34xx = 1,
2265 .no_tda7432 = 1, 1673 .pll = PLL_28,
2266 .pll = PLL_28, 1674 .tuner_type = 5,
2267 .no_video = 1, 1675 .tuner_addr = ADDR_UNSET,
2268 .has_dvb = 1, 1676 .radio_addr = ADDR_UNSET,
2269 .tuner_type = -1, 1677 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
2270 .tuner_addr = ADDR_UNSET, 1678 radio signal strength indicators work fine. */
2271},{ 1679 .has_radio = 1,
2272 /* Steven <photon38@pchome.com.tw> */ 1680 /* GPIO Info:
2273 .name = "V-Gear MyVCD", 1681 GPIO0,1: HEF4052 A0,A1
2274 .video_inputs = 3, 1682 GPIO2: HEF4052 nENABLE
2275 .audio_inputs = 1, 1683 GPIO3-7: n.c.
2276 .tuner = 0, 1684 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
2277 .svhs = 2, 1685 GPIO14,15: ??
2278 .gpiomask = 0x3f, 1686 GPIO16-21: n.c.
2279 .muxsel = {2, 3, 1, 0}, 1687 GPIO22,23: ??
2280 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, 1688 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
2281 .no_msp34xx = 1, 1689 },
2282 .pll = PLL_28, 1690 [BTTV_BOARD_DSP_TCVIDEO] = {
2283 .tuner_type = TUNER_PHILIPS_NTSC_M, 1691 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
2284 .tuner_addr = ADDR_UNSET, 1692 .name = "DSP Design TCVIDEO",
2285 .has_radio = 0, 1693 .video_inputs = 4,
2286},{ 1694 .svhs = -1,
2287 /* Rick C <cryptdragoon@gmail.com> */ 1695 .muxsel = { 2, 3, 1, 0},
2288 .name = "Super TV Tuner", 1696 .pll = PLL_28,
2289 .video_inputs = 4, 1697 .tuner_type = -1,
2290 .audio_inputs = 1, 1698 .tuner_addr = ADDR_UNSET,
2291 .tuner = 0, 1699 .radio_addr = ADDR_UNSET,
2292 .svhs = 2, 1700 },
2293 .muxsel = { 2, 3, 1, 0}, 1701
2294 .tuner_type = TUNER_PHILIPS_NTSC, 1702 /* ---- card 0x50 ---------------------------------- */
2295 .tuner_addr = ADDR_UNSET, 1703 [BTTV_BOARD_HAUPPAUGEPVR] = {
2296 .gpiomask = 0x008007, 1704 .name = "Hauppauge WinTV PVR",
2297 .audiomux = { 0, 0x000001,0,0, 0}, 1705 .video_inputs = 4,
2298 .needs_tvaudio = 1, 1706 .audio_inputs = 1,
2299 .has_radio = 1, 1707 .tuner = 0,
2300},{ 1708 .svhs = 2,
2301 /* Chris Fanning <video4linux@haydon.net> */ 1709 .muxsel = { 2, 0, 1, 1},
2302 .name = "Tibet Systems 'Progress DVR' CS16", 1710 .needs_tvaudio = 1,
2303 .video_inputs = 16, 1711 .pll = PLL_28,
2304 .audio_inputs = 0, 1712 .tuner_type = -1,
2305 .tuner = -1, 1713 .tuner_addr = ADDR_UNSET,
2306 .svhs = -1, 1714 .radio_addr = ADDR_UNSET,
2307 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, 1715
2308 .pll = PLL_28, 1716 .gpiomask = 7,
2309 .no_msp34xx = 1, 1717 .audiomux = {7},
2310 .no_tda9875 = 1, 1718 },
2311 .no_tda7432 = 1, 1719 [BTTV_BOARD_GVBCTV5PCI] = {
2312 .tuner_type = -1, 1720 .name = "IODATA GV-BCTV5/PCI",
2313 .tuner_addr = ADDR_UNSET, 1721 .video_inputs = 3,
2314 .muxsel_hook = tibetCS16_muxsel, 1722 .audio_inputs = 1,
2315}, 1723 .tuner = 0,
2316{ 1724 .svhs = 2,
2317 /* Bill Brack <wbrack@mmm.com.hk> */ 1725 .gpiomask = 0x0f0f80,
2318 /* 1726 .muxsel = {2, 3, 1, 0},
2319 * Note that, because of the card's wiring, the "master" 1727 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
2320 * BT878A chip (i.e. the one which controls the analog switch 1728 .no_msp34xx = 1,
2321 * and must use this card type) is the 2nd one detected. The 1729 .pll = PLL_28,
2322 * other 3 chips should use card type 0x85, whose description 1730 .tuner_type = TUNER_PHILIPS_NTSC_M,
2323 * follows this one. There is a EEPROM on the card (which is 1731 .tuner_addr = ADDR_UNSET,
2324 * connected to the I2C of one of those other chips), but is 1732 .radio_addr = ADDR_UNSET,
2325 * not currently handled. There is also a facility for a 1733 .audio_hook = gvbctv5pci_audio,
2326 * "monitor", which is also not currently implemented. 1734 .has_radio = 1,
2327 */ 1735 },
2328 .name = "Kodicom 4400R (master)", 1736 [BTTV_BOARD_OSPREY1x0] = {
2329 .video_inputs = 16, 1737 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
2330 .audio_inputs = 0, 1738 .video_inputs = 4, /* id-inputs-clock */
2331 .tuner = -1, 1739 .audio_inputs = 0,
2332 .tuner_type = -1, 1740 .tuner = -1,
2333 .tuner_addr = ADDR_UNSET, 1741 .svhs = 3,
2334 .svhs = -1, 1742 .muxsel = { 3, 2, 0, 1 },
2335 /* GPIO bits 0-9 used for analog switch: 1743 .pll = PLL_28,
2336 * 00 - 03: camera selector 1744 .tuner_type = -1,
2337 * 04 - 06: channel (controller) selector 1745 .tuner_addr = ADDR_UNSET,
2338 * 07: data (1->on, 0->off) 1746 .radio_addr = ADDR_UNSET,
2339 * 08: strobe 1747 .no_msp34xx = 1,
2340 * 09: reset 1748 .no_tda9875 = 1,
2341 * bit 16 is input from sync separator for the channel 1749 .no_tda7432 = 1,
2342 */ 1750 },
2343 .gpiomask = 0x0003ff, 1751 [BTTV_BOARD_OSPREY1x0_848] = {
2344 .no_gpioirq = 1, 1752 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
2345 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1753 .video_inputs = 3,
2346 .pll = PLL_28, 1754 .audio_inputs = 0,
2347 .no_msp34xx = 1, 1755 .tuner = -1,
2348 .no_tda7432 = 1, 1756 .svhs = 2,
2349 .no_tda9875 = 1, 1757 .muxsel = { 2, 3, 1 },
2350 .muxsel_hook = kodicom4400r_muxsel, 1758 .pll = PLL_28,
2351}, 1759 .tuner_type = -1,
2352{ 1760 .tuner_addr = ADDR_UNSET,
2353 /* Bill Brack <wbrack@mmm.com.hk> */ 1761 .radio_addr = ADDR_UNSET,
2354 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the 1762 .no_msp34xx = 1,
2355 * one which controls the analog switch, and must use the card type) 1763 .no_tda9875 = 1,
2356 * is the 2nd one detected. The other 3 chips should use this card 1764 .no_tda7432 = 1,
2357 * type 1765 },
1766
1767 /* ---- card 0x54 ---------------------------------- */
1768 [BTTV_BOARD_OSPREY101_848] = {
1769 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
1770 .video_inputs = 2,
1771 .audio_inputs = 0,
1772 .tuner = -1,
1773 .svhs = 1,
1774 .muxsel = { 3, 1 },
1775 .pll = PLL_28,
1776 .tuner_type = -1,
1777 .tuner_addr = ADDR_UNSET,
1778 .radio_addr = ADDR_UNSET,
1779 .no_msp34xx = 1,
1780 .no_tda9875 = 1,
1781 .no_tda7432 = 1,
1782 },
1783 [BTTV_BOARD_OSPREY1x1] = {
1784 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1785 .video_inputs = 1,
1786 .audio_inputs = 0,
1787 .tuner = -1,
1788 .svhs = -1,
1789 .muxsel = { 0 },
1790 .pll = PLL_28,
1791 .tuner_type = -1,
1792 .tuner_addr = ADDR_UNSET,
1793 .radio_addr = ADDR_UNSET,
1794 .no_msp34xx = 1,
1795 .no_tda9875 = 1,
1796 .no_tda7432 = 1,
1797 },
1798 [BTTV_BOARD_OSPREY1x1_SVID] = {
1799 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1800 .video_inputs = 2,
1801 .audio_inputs = 0,
1802 .tuner = -1,
1803 .svhs = 1,
1804 .muxsel = { 0, 1 },
1805 .pll = PLL_28,
1806 .tuner_type = -1,
1807 .tuner_addr = ADDR_UNSET,
1808 .radio_addr = ADDR_UNSET,
1809 .no_msp34xx = 1,
1810 .no_tda9875 = 1,
1811 .no_tda7432 = 1,
1812 },
1813 [BTTV_BOARD_OSPREY2xx] = {
1814 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1815 .video_inputs = 1,
1816 .audio_inputs = 1,
1817 .tuner = -1,
1818 .svhs = -1,
1819 .muxsel = { 0 },
1820 .pll = PLL_28,
1821 .tuner_type = UNSET,
1822 .tuner_addr = ADDR_UNSET,
1823 .radio_addr = ADDR_UNSET,
1824 .no_msp34xx = 1,
1825 .no_tda9875 = 1,
1826 .no_tda7432 = 1,
1827 },
1828
1829 /* ---- card 0x58 ---------------------------------- */
1830 [BTTV_BOARD_OSPREY2x0_SVID] = {
1831 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
1832 .video_inputs = 2,
1833 .audio_inputs = 1,
1834 .tuner = -1,
1835 .svhs = 1,
1836 .muxsel = { 0, 1 },
1837 .pll = PLL_28,
1838 .tuner_type = UNSET,
1839 .tuner_addr = ADDR_UNSET,
1840 .radio_addr = ADDR_UNSET,
1841 .no_msp34xx = 1,
1842 .no_tda9875 = 1,
1843 .no_tda7432 = 1,
1844 },
1845 [BTTV_BOARD_OSPREY2x0] = {
1846 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1847 .video_inputs = 2,
1848 .audio_inputs = 1,
1849 .tuner = -1,
1850 .svhs = 1,
1851 .muxsel = { 2, 3 },
1852 .pll = PLL_28,
1853 .tuner_type = UNSET,
1854 .tuner_addr = ADDR_UNSET,
1855 .radio_addr = ADDR_UNSET,
1856 .no_msp34xx = 1,
1857 .no_tda9875 = 1,
1858 .no_tda7432 = 1,
1859 },
1860 [BTTV_BOARD_OSPREY500] = {
1861 .name = "Osprey 500", /* 500 */
1862 .video_inputs = 2,
1863 .audio_inputs = 1,
1864 .tuner = -1,
1865 .svhs = 1,
1866 .muxsel = { 2, 3 },
1867 .pll = PLL_28,
1868 .tuner_type = -1,
1869 .tuner_addr = ADDR_UNSET,
1870 .radio_addr = ADDR_UNSET,
1871 .no_msp34xx = 1,
1872 .no_tda9875 = 1,
1873 .no_tda7432 = 1,
1874 },
1875 [BTTV_BOARD_OSPREY540] = {
1876 .name = "Osprey 540", /* 540 */
1877 .video_inputs = 4,
1878 .audio_inputs = 1,
1879 .tuner = -1,
1880 #if 0 /* TODO ... */
1881 .svhs = OSPREY540_SVID_ANALOG,
1882 .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
1883 [OSPREY540_SVID_ANALOG] = 3, },
1884 #endif
1885 .pll = PLL_28,
1886 .tuner_type = -1,
1887 .tuner_addr = ADDR_UNSET,
1888 .radio_addr = ADDR_UNSET,
1889 .no_msp34xx = 1,
1890 .no_tda9875 = 1,
1891 .no_tda7432 = 1,
1892 #if 0 /* TODO ... */
1893 .muxsel_hook = osprey_540_muxsel,
1894 .picture_hook = osprey_540_set_picture,
1895 #endif
1896 },
1897
1898 /* ---- card 0x5C ---------------------------------- */
1899 [BTTV_BOARD_OSPREY2000] = {
1900 .name = "Osprey 2000", /* 2000 */
1901 .video_inputs = 2,
1902 .audio_inputs = 1,
1903 .tuner = -1,
1904 .svhs = 1,
1905 .muxsel = { 2, 3 },
1906 .pll = PLL_28,
1907 .tuner_type = UNSET,
1908 .tuner_addr = ADDR_UNSET,
1909 .radio_addr = ADDR_UNSET,
1910 .no_msp34xx = 1,
1911 .no_tda9875 = 1,
1912 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1913 },
1914 [BTTV_BOARD_IDS_EAGLE] = {
1915 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1916 .name = "IDS Eagle",
1917 .video_inputs = 4,
1918 .audio_inputs = 0,
1919 .tuner = -1,
1920 .tuner_type = -1,
1921 .tuner_addr = ADDR_UNSET,
1922 .radio_addr = ADDR_UNSET,
1923 .svhs = -1,
1924 .gpiomask = 0,
1925 .muxsel = { 0, 1, 2, 3 },
1926 .muxsel_hook = eagle_muxsel,
1927 .no_msp34xx = 1,
1928 .no_tda9875 = 1,
1929 .pll = PLL_28,
1930 },
1931 [BTTV_BOARD_PINNACLESAT] = {
1932 .name = "Pinnacle PCTV Sat",
1933 .video_inputs = 2,
1934 .audio_inputs = 0,
1935 .svhs = 1,
1936 .tuner = -1,
1937 .tuner_type = -1,
1938 .tuner_addr = ADDR_UNSET,
1939 .radio_addr = ADDR_UNSET,
1940 .no_msp34xx = 1,
1941 .no_tda9875 = 1,
1942 .no_tda7432 = 1,
1943 .muxsel = { 3, 0, 1, 2},
1944 .pll = PLL_28,
1945 .no_gpioirq = 1,
1946 .has_dvb = 1,
1947 },
1948 [BTTV_BOARD_FORMAC_PROTV] = {
1949 .name = "Formac ProTV II (bt878)",
1950 .video_inputs = 4,
1951 .audio_inputs = 1,
1952 .tuner = 0,
1953 .svhs = 3,
1954 .gpiomask = 2,
1955 /* TV, Comp1, Composite over SVID con, SVID */
1956 .muxsel = { 2, 3, 1, 1},
1957 .audiomux = { 2, 2, 0, 0, 0 },
1958 .pll = PLL_28,
1959 .has_radio = 1,
1960 .tuner_type = TUNER_PHILIPS_PAL,
1961 .tuner_addr = ADDR_UNSET,
1962 .radio_addr = ADDR_UNSET,
1963 /* sound routing:
1964 GPIO=0x00,0x01,0x03: mute (?)
1965 0x02: both TV and radio (tuner: FM1216/I)
1966 The card has onboard audio connectors labeled "cdrom" and "board",
1967 not soldered here, though unknown wiring.
1968 Card lacks: external audio in, pci subsystem id.
2358 */ 1969 */
2359 .name = "Kodicom 4400R (slave)", 1970 },
2360 .video_inputs = 16, 1971
2361 .audio_inputs = 0, 1972 /* ---- card 0x60 ---------------------------------- */
2362 .tuner = -1, 1973 [BTTV_BOARD_MACHTV] = {
2363 .tuner_type = -1, 1974 .name = "MachTV",
2364 .tuner_addr = ADDR_UNSET, 1975 .video_inputs = 3,
2365 .svhs = -1, 1976 .audio_inputs = 1,
2366 .gpiomask = 0x010000, 1977 .tuner = 0,
2367 .no_gpioirq = 1, 1978 .svhs = -1,
2368 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1979 .gpiomask = 7,
2369 .pll = PLL_28, 1980 .muxsel = { 2, 3, 1, 1},
2370 .no_msp34xx = 1, 1981 .audiomux = { 0, 1, 2, 3, 4},
2371 .no_tda7432 = 1, 1982 .needs_tvaudio = 1,
2372 .no_tda9875 = 1, 1983 .tuner_type = 5,
2373 .muxsel_hook = kodicom4400r_muxsel, 1984 .tuner_addr = ADDR_UNSET,
2374}, 1985 .radio_addr = ADDR_UNSET,
2375{ 1986 .pll = PLL_28,
2376 /* ---- card 0x86---------------------------------- */ 1987 },
2377 /* Michael Henson <mhenson@clarityvi.com> */ 1988 [BTTV_BOARD_EURESYS_PICOLO] = {
2378 /* Adlink RTV24 with special unlock codes */ 1989 .name = "Euresys Picolo",
2379 .name = "Adlink RTV24", 1990 .video_inputs = 3,
2380 .video_inputs = 4, 1991 .audio_inputs = 0,
2381 .audio_inputs = 1, 1992 .tuner = -1,
2382 .tuner = 0, 1993 .svhs = 2,
2383 .svhs = 2, 1994 .gpiomask = 0,
2384 .muxsel = { 2, 3, 1, 0}, 1995 .no_msp34xx = 1,
2385 .tuner_type = -1, 1996 .no_tda9875 = 1,
2386 .tuner_addr = ADDR_UNSET, 1997 .no_tda7432 = 1,
2387 .pll = PLL_28, 1998 .muxsel = { 2, 0, 1},
2388}, 1999 .pll = PLL_28,
2389{ 2000 .tuner_type = UNSET,
2390 /* ---- card 0x87---------------------------------- */ 2001 .tuner_addr = ADDR_UNSET,
2391 /* Michael Krufky <mkrufky@m1k.net> */ 2002 .radio_addr = ADDR_UNSET,
2392 .name = "DViCO FusionHDTV 5 Lite", 2003 },
2393 .tuner = 0, 2004 [BTTV_BOARD_PV150] = {
2394 .tuner_type = TUNER_LG_TDVS_H062F, 2005 /* Luc Van Hoeylandt <luc@e-magic.be> */
2395 .tuner_addr = ADDR_UNSET, 2006 .name = "ProVideo PV150", /* 0x4f */
2396 .video_inputs = 3, 2007 .video_inputs = 2,
2397 .audio_inputs = 1, 2008 .audio_inputs = 0,
2398 .svhs = 2, 2009 .tuner = -1,
2399 .muxsel = { 2, 3, 1 }, 2010 .svhs = -1,
2400 .gpiomask = 0x00e00007, 2011 .gpiomask = 0,
2401 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, 2012 .muxsel = { 2, 3 },
2402 .no_msp34xx = 1, 2013 .audiomux = { 0 },
2403 .no_tda9875 = 1, 2014 .needs_tvaudio = 0,
2404 .no_tda7432 = 1, 2015 .no_msp34xx = 1,
2405},{ 2016 .pll = PLL_28,
2406 /* ---- card 0x88---------------------------------- */ 2017 .tuner_type = UNSET,
2407 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ 2018 .tuner_addr = ADDR_UNSET,
2408 .name = "Acorp Y878F", 2019 .radio_addr = ADDR_UNSET,
2409 .video_inputs = 3, 2020 },
2410 .audio_inputs = 1, 2021 [BTTV_BOARD_AD_TVK503] = {
2411 .tuner = 0, 2022 /* Hiroshi Takekawa <sian@big.or.jp> */
2412 .svhs = 2, 2023 /* This card lacks subsystem ID */
2413 .gpiomask = 0x01fe00, 2024 .name = "AD-TVK503", /* 0x63 */
2414 .muxsel = { 2, 3, 1, 1}, 2025 .video_inputs = 4,
2415 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 2026 .audio_inputs = 1,
2416 .needs_tvaudio = 1, 2027 .tuner = 0,
2417 .pll = PLL_28, 2028 .svhs = 2,
2418 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, 2029 .gpiomask = 0x001e8007,
2419 .tuner_addr = 0xc1 >>1, 2030 .muxsel = { 2, 3, 1, 0 },
2420 .has_radio = 1, 2031 /* Tuner, Radio, external, internal, off, on */
2421}}; 2032 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
2033 .needs_tvaudio = 0,
2034 .no_msp34xx = 1,
2035 .pll = PLL_28,
2036 .tuner_type = 2,
2037 .tuner_addr = ADDR_UNSET,
2038 .radio_addr = ADDR_UNSET,
2039 .audio_hook = adtvk503_audio,
2040 },
2041
2042 /* ---- card 0x64 ---------------------------------- */
2043 [BTTV_BOARD_HERCULES_SM_TV] = {
2044 .name = "Hercules Smart TV Stereo",
2045 .video_inputs = 4,
2046 .audio_inputs = 1,
2047 .tuner = 0,
2048 .svhs = 2,
2049 .gpiomask = 0x00,
2050 .muxsel = { 2, 3, 1, 1 },
2051 .needs_tvaudio = 1,
2052 .no_msp34xx = 1,
2053 .pll = PLL_28,
2054 .tuner_type = 5,
2055 .tuner_addr = ADDR_UNSET,
2056 .radio_addr = ADDR_UNSET,
2057 /* Notes:
2058 - card lacks subsystem ID
2059 - stereo variant w/ daughter board with tda9874a @0xb0
2060 - Audio Routing:
2061 always from tda9874 independent of GPIO (?)
2062 external line in: unknown
2063 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
2064 hef4053 (instead 4052) for unknown function
2065 */
2066 },
2067 [BTTV_BOARD_PACETV] = {
2068 .name = "Pace TV & Radio Card",
2069 .video_inputs = 4,
2070 .audio_inputs = 1,
2071 .tuner = 0,
2072 .svhs = 2,
2073 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
2074 .gpiomask = 0,
2075 .no_tda9875 = 1,
2076 .no_tda7432 = 1,
2077 .tuner_type = 1,
2078 .tuner_addr = ADDR_UNSET,
2079 .radio_addr = ADDR_UNSET,
2080 .has_radio = 1,
2081 .pll = PLL_28,
2082 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
2083 only internal line out: (4pin header) RGGL
2084 Radio must be decoded by msp3410d (not routed through)*/
2085 /*
2086 .digital_mode = DIGITAL_MODE_CAMERA, todo!
2087 */
2088 },
2089 [BTTV_BOARD_IVC200] = {
2090 /* Chris Willing <chris@vislab.usyd.edu.au> */
2091 .name = "IVC-200",
2092 .video_inputs = 1,
2093 .audio_inputs = 0,
2094 .tuner = -1,
2095 .tuner_type = -1,
2096 .tuner_addr = ADDR_UNSET,
2097 .radio_addr = ADDR_UNSET,
2098 .svhs = -1,
2099 .gpiomask = 0xdf,
2100 .muxsel = { 2 },
2101 .pll = PLL_28,
2102 },
2103 [BTTV_BOARD_XGUARD] = {
2104 .name = "Grand X-Guard / Trust 814PCI",
2105 .video_inputs = 16,
2106 .audio_inputs = 0,
2107 .tuner = -1,
2108 .svhs = -1,
2109 .tuner_type = 4,
2110 .tuner_addr = ADDR_UNSET,
2111 .radio_addr = ADDR_UNSET,
2112 .gpiomask2 = 0xff,
2113 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
2114 .muxsel_hook = xguard_muxsel,
2115 .no_msp34xx = 1,
2116 .no_tda9875 = 1,
2117 .no_tda7432 = 1,
2118 .pll = PLL_28,
2119 },
2120
2121 /* ---- card 0x68 ---------------------------------- */
2122 [BTTV_BOARD_NEBULA_DIGITV] = {
2123 .name = "Nebula Electronics DigiTV",
2124 .video_inputs = 1,
2125 .tuner = -1,
2126 .svhs = -1,
2127 .muxsel = { 2, 3, 1, 0},
2128 .no_msp34xx = 1,
2129 .no_tda9875 = 1,
2130 .no_tda7432 = 1,
2131 .pll = PLL_28,
2132 .tuner_type = -1,
2133 .tuner_addr = ADDR_UNSET,
2134 .radio_addr = ADDR_UNSET,
2135 .has_dvb = 1,
2136 .no_gpioirq = 1,
2137 },
2138 [BTTV_BOARD_PV143] = {
2139 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
2140 .name = "ProVideo PV143",
2141 .video_inputs = 4,
2142 .audio_inputs = 0,
2143 .tuner = -1,
2144 .svhs = -1,
2145 .gpiomask = 0,
2146 .muxsel = { 2, 3, 1, 0 },
2147 .audiomux = { 0 },
2148 .needs_tvaudio = 0,
2149 .no_msp34xx = 1,
2150 .pll = PLL_28,
2151 .tuner_type = -1,
2152 .tuner_addr = ADDR_UNSET,
2153 .radio_addr = ADDR_UNSET,
2154 },
2155 [BTTV_BOARD_VD009X1_MINIDIN] = {
2156 /* M.Klahr@phytec.de */
2157 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
2158 .video_inputs = 4,
2159 .audio_inputs = 0,
2160 .tuner = -1, /* card has no tuner */
2161 .svhs = 3,
2162 .gpiomask = 0x00,
2163 .muxsel = { 2, 3, 1, 0},
2164 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2165 .needs_tvaudio = 1,
2166 .pll = PLL_28,
2167 .tuner_type = -1,
2168 .tuner_addr = ADDR_UNSET,
2169 .radio_addr = ADDR_UNSET,
2170 },
2171 [BTTV_BOARD_VD009X1_COMBI] = {
2172 .name = "PHYTEC VD-009-X1 Combi (bt878)",
2173 .video_inputs = 4,
2174 .audio_inputs = 0,
2175 .tuner = -1, /* card has no tuner */
2176 .svhs = 3,
2177 .gpiomask = 0x00,
2178 .muxsel = { 2, 3, 1, 1},
2179 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2180 .needs_tvaudio = 1,
2181 .pll = PLL_28,
2182 .tuner_type = -1,
2183 .tuner_addr = ADDR_UNSET,
2184 .radio_addr = ADDR_UNSET,
2185 },
2186
2187 /* ---- card 0x6c ---------------------------------- */
2188 [BTTV_BOARD_VD009_MINIDIN] = {
2189 .name = "PHYTEC VD-009 MiniDIN (bt878)",
2190 .video_inputs = 10,
2191 .audio_inputs = 0,
2192 .tuner = -1, /* card has no tuner */
2193 .svhs = 9,
2194 .gpiomask = 0x00,
2195 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2196 via the upper nibble of muxsel. here: used for
2197 xternal video-mux */
2198 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
2199 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2200 .needs_tvaudio = 1,
2201 .pll = PLL_28,
2202 .tuner_type = -1,
2203 .tuner_addr = ADDR_UNSET,
2204 .radio_addr = ADDR_UNSET,
2205 },
2206 [BTTV_BOARD_VD009_COMBI] = {
2207 .name = "PHYTEC VD-009 Combi (bt878)",
2208 .video_inputs = 10,
2209 .audio_inputs = 0,
2210 .tuner = -1, /* card has no tuner */
2211 .svhs = 9,
2212 .gpiomask = 0x00,
2213 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2214 via the upper nibble of muxsel. here: used for
2215 xternal video-mux */
2216 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
2217 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2218 .needs_tvaudio = 1,
2219 .pll = PLL_28,
2220 .tuner_type = -1,
2221 .tuner_addr = ADDR_UNSET,
2222 .radio_addr = ADDR_UNSET,
2223 },
2224 [BTTV_BOARD_IVC100] = {
2225 .name = "IVC-100",
2226 .video_inputs = 4,
2227 .audio_inputs = 0,
2228 .tuner = -1,
2229 .tuner_type = -1,
2230 .tuner_addr = ADDR_UNSET,
2231 .radio_addr = ADDR_UNSET,
2232 .svhs = -1,
2233 .gpiomask = 0xdf,
2234 .muxsel = { 2, 3, 1, 0 },
2235 .pll = PLL_28,
2236 },
2237 [BTTV_BOARD_IVC120] = {
2238 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
2239 .name = "IVC-120G",
2240 .video_inputs = 16,
2241 .audio_inputs = 0, /* card has no audio */
2242 .tuner = -1, /* card has no tuner */
2243 .tuner_type = -1,
2244 .tuner_addr = ADDR_UNSET,
2245 .radio_addr = ADDR_UNSET,
2246 .svhs = -1, /* card has no svhs */
2247 .needs_tvaudio = 0,
2248 .no_msp34xx = 1,
2249 .no_tda9875 = 1,
2250 .no_tda7432 = 1,
2251 .gpiomask = 0x00,
2252 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2253 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
2254 .muxsel_hook = ivc120_muxsel,
2255 .pll = PLL_28,
2256 },
2257
2258 /* ---- card 0x70 ---------------------------------- */
2259 [BTTV_BOARD_PC_HDTV] = {
2260 .name = "pcHDTV HD-2000 TV",
2261 .video_inputs = 4,
2262 .audio_inputs = 1,
2263 .tuner = 0,
2264 .svhs = 2,
2265 .muxsel = { 2, 3, 1, 0},
2266 .tuner_type = TUNER_PHILIPS_ATSC,
2267 .tuner_addr = ADDR_UNSET,
2268 .radio_addr = ADDR_UNSET,
2269 .has_dvb = 1,
2270 },
2271 [BTTV_BOARD_TWINHAN_DST] = {
2272 .name = "Twinhan DST + clones",
2273 .no_msp34xx = 1,
2274 .no_tda9875 = 1,
2275 .no_tda7432 = 1,
2276 .tuner_type = TUNER_ABSENT,
2277 .tuner_addr = ADDR_UNSET,
2278 .radio_addr = ADDR_UNSET,
2279 .no_video = 1,
2280 .has_dvb = 1,
2281 },
2282 [BTTV_BOARD_WINFASTVC100] = {
2283 .name = "Winfast VC100",
2284 .video_inputs = 3,
2285 .audio_inputs = 0,
2286 .svhs = 1,
2287 .tuner = -1,
2288 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
2289 .no_msp34xx = 1,
2290 .no_tda9875 = 1,
2291 .no_tda7432 = 1,
2292 .tuner_type = TUNER_ABSENT,
2293 .tuner_addr = ADDR_UNSET,
2294 .radio_addr = ADDR_UNSET,
2295 .pll = PLL_28,
2296 },
2297 [BTTV_BOARD_TEV560] = {
2298 .name = "Teppro TEV-560/InterVision IV-560",
2299 .video_inputs = 3,
2300 .audio_inputs = 1,
2301 .tuner = 0,
2302 .svhs = 2,
2303 .gpiomask = 3,
2304 .muxsel = { 2, 3, 1, 1},
2305 .audiomux = { 1, 1, 1, 1, 0},
2306 .needs_tvaudio = 1,
2307 .tuner_type = TUNER_PHILIPS_PAL,
2308 .tuner_addr = ADDR_UNSET,
2309 .radio_addr = ADDR_UNSET,
2310 .pll = PLL_35,
2311 },
2312
2313 /* ---- card 0x74 ---------------------------------- */
2314 [BTTV_BOARD_SIMUS_GVC1100] = {
2315 .name = "SIMUS GVC1100",
2316 .video_inputs = 4,
2317 .audio_inputs = 0,
2318 .tuner = -1,
2319 .svhs = -1,
2320 .tuner_type = -1,
2321 .tuner_addr = ADDR_UNSET,
2322 .radio_addr = ADDR_UNSET,
2323 .pll = PLL_28,
2324 .muxsel = { 2, 2, 2, 2},
2325 .gpiomask = 0x3F,
2326 .muxsel_hook = gvc1100_muxsel,
2327 },
2328 [BTTV_BOARD_NGSTV_PLUS] = {
2329 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
2330 .name = "NGS NGSTV+",
2331 .video_inputs = 3,
2332 .tuner = 0,
2333 .svhs = 2,
2334 .gpiomask = 0x008007,
2335 .muxsel = {2, 3, 0, 0},
2336 .audiomux = {0, 0, 0, 0, 0x000003, 0},
2337 .pll = PLL_28,
2338 .tuner_type = TUNER_PHILIPS_PAL,
2339 .tuner_addr = ADDR_UNSET,
2340 .radio_addr = ADDR_UNSET,
2341 .has_remote = 1,
2342 },
2343 [BTTV_BOARD_LMLBT4] = {
2344 /* http://linuxmedialabs.com */
2345 .name = "LMLBT4",
2346 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
2347 .audio_inputs = 0,
2348 .tuner = -1,
2349 .svhs = -1,
2350 .muxsel = { 2, 3, 1, 0 },
2351 .no_msp34xx = 1,
2352 .no_tda9875 = 1,
2353 .no_tda7432 = 1,
2354 .needs_tvaudio = 0,
2355 .tuner_type = -1,
2356 .tuner_addr = ADDR_UNSET,
2357 .radio_addr = ADDR_UNSET,
2358 },
2359 [BTTV_BOARD_TEKRAM_M205] = {
2360 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
2361 .name = "Tekram M205 PRO",
2362 .video_inputs = 3,
2363 .audio_inputs = 1,
2364 .tuner = 0,
2365 .tuner_type = TUNER_PHILIPS_PAL,
2366 .tuner_addr = ADDR_UNSET,
2367 .radio_addr = ADDR_UNSET,
2368 .svhs = 2,
2369 .needs_tvaudio = 0,
2370 .gpiomask = 0x68,
2371 .muxsel = { 2, 3, 1},
2372 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
2373 .pll = PLL_28,
2374 },
2375
2376 /* ---- card 0x78 ---------------------------------- */
2377 [BTTV_BOARD_CONTVFMI] = {
2378 /* Javier Cendan Ares <jcendan@lycos.es> */
2379 /* bt878 TV + FM without subsystem ID */
2380 .name = "Conceptronic CONTVFMi",
2381 .video_inputs = 3,
2382 .audio_inputs = 1,
2383 .tuner = 0,
2384 .svhs = 2,
2385 .gpiomask = 0x008007,
2386 .muxsel = { 2, 3, 1, 1 },
2387 .audiomux = { 0, 1, 2, 2, 3 },
2388 .needs_tvaudio = 0,
2389 .pll = PLL_28,
2390 .tuner_type = TUNER_PHILIPS_PAL,
2391 .tuner_addr = ADDR_UNSET,
2392 .radio_addr = ADDR_UNSET,
2393 .has_remote = 1,
2394 .has_radio = 1,
2395 },
2396 [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
2397 /*Eric DEBIEF <debief@telemsa.com>*/
2398 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
2399 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
2400 /*0x79 in bttv.h*/
2401 .name = "Euresys Picolo Tetra",
2402 .video_inputs = 4,
2403 .audio_inputs = 0,
2404 .tuner = -1,
2405 .svhs = -1,
2406 .gpiomask = 0,
2407 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
2408 .no_msp34xx = 1,
2409 .no_tda9875 = 1,
2410 .no_tda7432 = 1,
2411 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
2412 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2413 .pll = PLL_28,
2414 .needs_tvaudio = 0,
2415 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2416 .tuner_type = -1,
2417 .tuner_addr = ADDR_UNSET,
2418 .radio_addr = ADDR_UNSET,
2419 },
2420 [BTTV_BOARD_SPIRIT_TV] = {
2421 /* Spirit TV Tuner from http://spiritmodems.com.au */
2422 /* Stafford Goodsell <surge@goliath.homeunix.org> */
2423 .name = "Spirit TV Tuner",
2424 .video_inputs = 3,
2425 .audio_inputs = 1,
2426 .tuner = 0,
2427 .svhs = 2,
2428 .gpiomask = 0x0000000f,
2429 .muxsel = { 2, 1, 1 },
2430 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
2431 .tuner_type = TUNER_TEMIC_PAL,
2432 .tuner_addr = ADDR_UNSET,
2433 .radio_addr = ADDR_UNSET,
2434 .no_msp34xx = 1,
2435 .no_tda9875 = 1,
2436 },
2437 [BTTV_BOARD_AVDVBT_771] = {
2438 /* Wolfram Joost <wojo@frokaschwei.de> */
2439 .name = "AVerMedia AVerTV DVB-T 771",
2440 .video_inputs = 2,
2441 .svhs = 1,
2442 .tuner = -1,
2443 .tuner_type = TUNER_ABSENT,
2444 .tuner_addr = ADDR_UNSET,
2445 .radio_addr = ADDR_UNSET,
2446 .muxsel = { 3 , 3 },
2447 .no_msp34xx = 1,
2448 .no_tda9875 = 1,
2449 .no_tda7432 = 1,
2450 .pll = PLL_28,
2451 .has_dvb = 1,
2452 .no_gpioirq = 1,
2453 .has_remote = 1,
2454 },
2455 /* ---- card 0x7c ---------------------------------- */
2456 [BTTV_BOARD_AVDVBT_761] = {
2457 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
2458 /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
2459 .name = "AverMedia AverTV DVB-T 761",
2460 .video_inputs = 2,
2461 .tuner = -1,
2462 .svhs = 1,
2463 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
2464 .no_msp34xx = 1,
2465 .no_tda9875 = 1,
2466 .no_tda7432 = 1,
2467 .pll = PLL_28,
2468 .tuner_type = -1,
2469 .tuner_addr = ADDR_UNSET,
2470 .radio_addr = ADDR_UNSET,
2471 .has_dvb = 1,
2472 .no_gpioirq = 1,
2473 .has_remote = 1,
2474 },
2475 [BTTV_BOARD_MATRIX_VISIONSQ] = {
2476 /* andre.schwarz@matrix-vision.de */
2477 .name = "MATRIX Vision Sigma-SQ",
2478 .video_inputs = 16,
2479 .audio_inputs = 0,
2480 .tuner = -1,
2481 .svhs = -1,
2482 .gpiomask = 0x0,
2483 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2484 3, 3, 3, 3, 3, 3, 3, 3 },
2485 .muxsel_hook = sigmaSQ_muxsel,
2486 .audiomux = { 0 },
2487 .no_msp34xx = 1,
2488 .pll = PLL_28,
2489 .tuner_type = -1,
2490 .tuner_addr = ADDR_UNSET,
2491 .radio_addr = ADDR_UNSET,
2492 },
2493 [BTTV_BOARD_MATRIX_VISIONSLC] = {
2494 /* andre.schwarz@matrix-vision.de */
2495 .name = "MATRIX Vision Sigma-SLC",
2496 .video_inputs = 4,
2497 .audio_inputs = 0,
2498 .tuner = -1,
2499 .svhs = -1,
2500 .gpiomask = 0x0,
2501 .muxsel = { 2, 2, 2, 2 },
2502 .muxsel_hook = sigmaSLC_muxsel,
2503 .audiomux = { 0 },
2504 .no_msp34xx = 1,
2505 .pll = PLL_28,
2506 .tuner_type = -1,
2507 .tuner_addr = ADDR_UNSET,
2508 .radio_addr = ADDR_UNSET,
2509 },
2510 /* BTTV_BOARD_APAC_VIEWCOMP */
2511 [BTTV_BOARD_APAC_VIEWCOMP] = {
2512 /* Attila Kondoros <attila.kondoros@chello.hu> */
2513 /* bt878 TV + FM 0x00000000 subsystem ID */
2514 .name = "APAC Viewcomp 878(AMAX)",
2515 .video_inputs = 2,
2516 .audio_inputs = 1,
2517 .tuner = 0,
2518 .svhs = -1,
2519 .gpiomask = 0xFF,
2520 .muxsel = { 2, 3, 1, 1},
2521 .audiomux = { 2, 0, 0, 0, 10},
2522 .needs_tvaudio = 0,
2523 .pll = PLL_28,
2524 .tuner_type = TUNER_PHILIPS_PAL,
2525 .tuner_addr = ADDR_UNSET,
2526 .radio_addr = ADDR_UNSET,
2527 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2528 .has_radio = 1, /* not every card has radio */
2529 },
2530
2531 /* ---- card 0x80 ---------------------------------- */
2532 [BTTV_BOARD_DVICO_DVBT_LITE] = {
2533 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2534 .name = "DViCO FusionHDTV DVB-T Lite",
2535 .tuner = -1,
2536 .no_msp34xx = 1,
2537 .no_tda9875 = 1,
2538 .no_tda7432 = 1,
2539 .pll = PLL_28,
2540 .no_video = 1,
2541 .has_dvb = 1,
2542 .tuner_type = -1,
2543 .tuner_addr = ADDR_UNSET,
2544 .radio_addr = ADDR_UNSET,
2545 },
2546 [BTTV_BOARD_VGEAR_MYVCD] = {
2547 /* Steven <photon38@pchome.com.tw> */
2548 .name = "V-Gear MyVCD",
2549 .video_inputs = 3,
2550 .audio_inputs = 1,
2551 .tuner = 0,
2552 .svhs = 2,
2553 .gpiomask = 0x3f,
2554 .muxsel = {2, 3, 1, 0},
2555 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
2556 .no_msp34xx = 1,
2557 .pll = PLL_28,
2558 .tuner_type = TUNER_PHILIPS_NTSC_M,
2559 .tuner_addr = ADDR_UNSET,
2560 .radio_addr = ADDR_UNSET,
2561 .has_radio = 0,
2562 #if 0
2563 .has_remote = 1,
2564 #endif
2565 },
2566 [BTTV_BOARD_SUPER_TV] = {
2567 /* Rick C <cryptdragoon@gmail.com> */
2568 .name = "Super TV Tuner",
2569 .video_inputs = 4,
2570 .audio_inputs = 1,
2571 .tuner = 0,
2572 .svhs = 2,
2573 .muxsel = { 2, 3, 1, 0},
2574 .tuner_type = TUNER_PHILIPS_NTSC,
2575 .tuner_addr = ADDR_UNSET,
2576 .radio_addr = ADDR_UNSET,
2577 .gpiomask = 0x008007,
2578 .audiomux = { 0, 0x000001,0,0, 0},
2579 .needs_tvaudio = 1,
2580 .has_radio = 1,
2581 },
2582 [BTTV_BOARD_TIBET_CS16] = {
2583 /* Chris Fanning <video4linux@haydon.net> */
2584 .name = "Tibet Systems 'Progress DVR' CS16",
2585 .video_inputs = 16,
2586 .audio_inputs = 0,
2587 .tuner = -1,
2588 .svhs = -1,
2589 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2590 .pll = PLL_28,
2591 .no_msp34xx = 1,
2592 .no_tda9875 = 1,
2593 .no_tda7432 = 1,
2594 .tuner_type = -1,
2595 .tuner_addr = ADDR_UNSET,
2596 .radio_addr = ADDR_UNSET,
2597 .muxsel_hook = tibetCS16_muxsel,
2598 },
2599 [BTTV_BOARD_KODICOM_4400R] = {
2600 /* Bill Brack <wbrack@mmm.com.hk> */
2601 /*
2602 * Note that, because of the card's wiring, the "master"
2603 * BT878A chip (i.e. the one which controls the analog switch
2604 * and must use this card type) is the 2nd one detected. The
2605 * other 3 chips should use card type 0x85, whose description
2606 * follows this one. There is a EEPROM on the card (which is
2607 * connected to the I2C of one of those other chips), but is
2608 * not currently handled. There is also a facility for a
2609 * "monitor", which is also not currently implemented.
2610 */
2611 .name = "Kodicom 4400R (master)",
2612 .video_inputs = 16,
2613 .audio_inputs = 0,
2614 .tuner = -1,
2615 .tuner_type = -1,
2616 .tuner_addr = ADDR_UNSET,
2617 .radio_addr = ADDR_UNSET,
2618 .svhs = -1,
2619 /* GPIO bits 0-9 used for analog switch:
2620 * 00 - 03: camera selector
2621 * 04 - 06: channel (controller) selector
2622 * 07: data (1->on, 0->off)
2623 * 08: strobe
2624 * 09: reset
2625 * bit 16 is input from sync separator for the channel
2626 */
2627 .gpiomask = 0x0003ff,
2628 .no_gpioirq = 1,
2629 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2630 .pll = PLL_28,
2631 .no_msp34xx = 1,
2632 .no_tda7432 = 1,
2633 .no_tda9875 = 1,
2634 .muxsel_hook = kodicom4400r_muxsel,
2635 },
2636 [BTTV_BOARD_KODICOM_4400R_SL] = {
2637 /* Bill Brack <wbrack@mmm.com.hk> */
2638 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2639 * one which controls the analog switch, and must use the card type)
2640 * is the 2nd one detected. The other 3 chips should use this card
2641 * type
2642 */
2643 .name = "Kodicom 4400R (slave)",
2644 .video_inputs = 16,
2645 .audio_inputs = 0,
2646 .tuner = -1,
2647 .tuner_type = -1,
2648 .tuner_addr = ADDR_UNSET,
2649 .radio_addr = ADDR_UNSET,
2650 .svhs = -1,
2651 .gpiomask = 0x010000,
2652 .no_gpioirq = 1,
2653 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2654 .pll = PLL_28,
2655 .no_msp34xx = 1,
2656 .no_tda7432 = 1,
2657 .no_tda9875 = 1,
2658 .muxsel_hook = kodicom4400r_muxsel,
2659 },
2660 /* ---- card 0x86---------------------------------- */
2661 [BTTV_BOARD_ADLINK_RTV24] = {
2662 /* Michael Henson <mhenson@clarityvi.com> */
2663 /* Adlink RTV24 with special unlock codes */
2664 .name = "Adlink RTV24",
2665 .video_inputs = 4,
2666 .audio_inputs = 1,
2667 .tuner = 0,
2668 .svhs = 2,
2669 .muxsel = { 2, 3, 1, 0},
2670 .tuner_type = -1,
2671 .tuner_addr = ADDR_UNSET,
2672 .radio_addr = ADDR_UNSET,
2673 .pll = PLL_28,
2674 },
2675 /* ---- card 0x87---------------------------------- */
2676 [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
2677 /* Michael Krufky <mkrufky@m1k.net> */
2678 .name = "DViCO FusionHDTV 5 Lite",
2679 .tuner = 0,
2680 .tuner_type = TUNER_LG_TDVS_H062F,
2681 .tuner_addr = ADDR_UNSET,
2682 .radio_addr = ADDR_UNSET,
2683 .video_inputs = 3,
2684 .audio_inputs = 1,
2685 .svhs = 2,
2686 .muxsel = { 2, 3, 1 },
2687 .gpiomask = 0x00e00007,
2688 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
2689 .no_msp34xx = 1,
2690 .no_tda9875 = 1,
2691 .no_tda7432 = 1,
2692 .has_dvb = 1,
2693 },
2694 /* ---- card 0x88---------------------------------- */
2695 [BTTV_BOARD_ACORP_Y878F] = {
2696 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
2697 .name = "Acorp Y878F",
2698 .video_inputs = 3,
2699 .audio_inputs = 1,
2700 .tuner = 0,
2701 .svhs = 2,
2702 .gpiomask = 0x01fe00,
2703 .muxsel = { 2, 3, 1, 1},
2704 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
2705 .needs_tvaudio = 1,
2706 .pll = PLL_28,
2707 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
2708 .tuner_addr = 0xc1 >>1,
2709 .radio_addr = 0xc1 >>1,
2710 .has_radio = 1,
2711 },
2712 /* ---- card 0x89 ---------------------------------- */
2713 [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
2714 .name = "Conceptronic CTVFMi v2",
2715 .video_inputs = 3,
2716 .audio_inputs = 1,
2717 .tuner = 0,
2718 .svhs = 2,
2719 .gpiomask = 0x001c0007,
2720 .muxsel = { 2, 3, 1, 1 },
2721 .audiomux = { 0, 1, 2, 2, 3 },
2722 .needs_tvaudio = 0,
2723 .pll = PLL_28,
2724 .tuner_type = TUNER_TENA_9533_DI,
2725 .tuner_addr = ADDR_UNSET,
2726 .radio_addr = ADDR_UNSET,
2727 .has_remote = 1,
2728 .has_radio = 1,
2729 },
2730 /* ---- card 0x8a ---------------------------------- */
2731 [BTTV_BOARD_PV_BT878P_2E] = {
2732 .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
2733 .video_inputs = 5,
2734 .audio_inputs = 1,
2735 .tuner = 0,
2736 .svhs = 3,
2737 .gpiomask = 0x01fe00,
2738 .muxsel = { 2,3,1,1,-1 },
2739 .digital_mode = DIGITAL_MODE_CAMERA,
2740 .audiomux = { 0x00400, 0x10400, 0x04400, 0x80000, 0x12400, 0x46000 },
2741 .no_msp34xx = 1,
2742 .pll = PLL_28,
2743 .tuner_type = TUNER_LG_PAL_FM,
2744 .tuner_addr = ADDR_UNSET,
2745 .radio_addr = ADDR_UNSET,
2746 .has_remote = 1,
2747 },
2748 /* ---- card 0x8b ---------------------------------- */
2749 [BTTV_BOARD_PV_M4900] = {
2750 /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
2751 .name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
2752 .video_inputs = 3,
2753 .audio_inputs = 1,
2754 .tuner = 0,
2755 .svhs = 2,
2756 .gpiomask = 0x3f,
2757 .muxsel = { 2, 3, 1, 1 },
2758 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
2759 .no_msp34xx = 1,
2760 .pll = PLL_28,
2761 .tuner_type = TUNER_YMEC_TVF_5533MF,
2762 .tuner_addr = ADDR_UNSET,
2763 .radio_addr = ADDR_UNSET,
2764 .has_radio = 1,
2765 .has_remote = 1,
2766 },
2767 /* ---- card 0x8c ---------------------------------- */
2768 [BTTV_BOARD_OSPREY440] = {
2769 .name = "Osprey 440",
2770 .video_inputs = 1,
2771 .audio_inputs = 1,
2772 .tuner = -1,
2773 .svhs = 1,
2774 .muxsel = { 2 },
2775 .pll = PLL_28,
2776 .tuner_type = UNSET,
2777 .tuner_addr = ADDR_UNSET,
2778 .radio_addr = ADDR_UNSET,
2779 .no_msp34xx = 1,
2780 .no_tda9875 = 1,
2781 .no_tda7432 = 1,
2782 },
2783 /* ---- card 0x8d ---------------------------------- */
2784 [BTTV_BOARD_ASOUND_SKYEYE] = {
2785 .name = "Asound Skyeye PCTV",
2786 .video_inputs = 3,
2787 .audio_inputs = 1,
2788 .tuner = 0,
2789 .svhs = 2,
2790 .gpiomask = 15,
2791 .muxsel = { 2, 3, 1, 1},
2792 .audiomux = {2,0,0,0,1},
2793 .needs_tvaudio = 1,
2794 .pll = PLL_28,
2795 .tuner_type = 2,
2796 .tuner_addr = ADDR_UNSET,
2797 .radio_addr = ADDR_UNSET,
2798 },
2799
2800};
2422 2801
2423static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2802static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
2424 2803
@@ -2461,7 +2840,7 @@ void __devinit bttv_idcard(struct bttv *btv)
2461 btv->c.nr, btv->cardid & 0xffff, 2840 btv->c.nr, btv->cardid & 0xffff,
2462 (btv->cardid >> 16) & 0xffff); 2841 (btv->cardid >> 16) & 0xffff);
2463 printk(KERN_DEBUG "please mail id, board name and " 2842 printk(KERN_DEBUG "please mail id, board name and "
2464 "the correct card= insmod option to kraxel@bytesex.org\n"); 2843 "the correct card= insmod option to video4linux-list@redhat.com\n");
2465 } 2844 }
2466 } 2845 }
2467 2846
@@ -2510,11 +2889,11 @@ void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
2510 int type = -1; 2889 int type = -1;
2511 2890
2512 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) 2891 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
2513 type = BTTV_MODTEC_205; 2892 type = BTTV_BOARD_MODTEC_205;
2514 else if (0 == strncmp(eeprom_data+20,"Picolo",7)) 2893 else if (0 == strncmp(eeprom_data+20,"Picolo",7))
2515 type = BTTV_EURESYS_PICOLO; 2894 type = BTTV_BOARD_EURESYS_PICOLO;
2516 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0) 2895 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
2517 type = BTTV_HAUPPAUGE; /* old bt848 */ 2896 type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
2518 2897
2519 if (-1 != type) { 2898 if (-1 != type) {
2520 btv->c.type = type; 2899 btv->c.type = type;
@@ -2548,7 +2927,7 @@ static void flyvideo_gpio(struct bttv *btv)
2548 switch(ttype) { 2927 switch(ttype) {
2549 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ 2928 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
2550 break; 2929 break;
2551 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ 2930 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
2552 break; 2931 break;
2553 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ 2932 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
2554 break; 2933 break;
@@ -2564,7 +2943,7 @@ static void flyvideo_gpio(struct bttv *btv)
2564 has_radio = gpio & 0x400000; 2943 has_radio = gpio & 0x400000;
2565 /* unknown 0x200000; 2944 /* unknown 0x200000;
2566 * unknown2 0x100000; */ 2945 * unknown2 0x100000; */
2567 is_capture_only = !(gpio & 0x008000); /* GPIO15 */ 2946 is_capture_only = !(gpio & 0x008000); /* GPIO15 */
2568 has_tda9820_tda9821 = !(gpio & 0x004000); 2947 has_tda9820_tda9821 = !(gpio & 0x004000);
2569 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */ 2948 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
2570 /* 2949 /*
@@ -2601,7 +2980,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2601 char *info; 2980 char *info;
2602 2981
2603 gpio_inout(0xffffff, 0); 2982 gpio_inout(0xffffff, 0);
2604 gpio = gpio_read(); 2983 gpio = gpio_read();
2605 id = ((gpio>>10) & 63) -1; 2984 id = ((gpio>>10) & 63) -1;
2606 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); 2985 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
2607 if (id < 32) { 2986 if (id < 32) {
@@ -2620,10 +2999,10 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2620 btv->has_radio = 0; 2999 btv->has_radio = 0;
2621 } 3000 }
2622 if (-1 != msp) { 3001 if (-1 != msp) {
2623 if (btv->c.type == BTTV_MIRO) 3002 if (btv->c.type == BTTV_BOARD_MIRO)
2624 btv->c.type = BTTV_MIROPRO; 3003 btv->c.type = BTTV_BOARD_MIROPRO;
2625 if (btv->c.type == BTTV_PINNACLE) 3004 if (btv->c.type == BTTV_BOARD_PINNACLE)
2626 btv->c.type = BTTV_PINNACLEPRO; 3005 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2627 } 3006 }
2628 printk(KERN_INFO 3007 printk(KERN_INFO
2629 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", 3008 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
@@ -2664,7 +3043,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2664 break; 3043 break;
2665 } 3044 }
2666 if (-1 != msp) 3045 if (-1 != msp)
2667 btv->c.type = BTTV_PINNACLEPRO; 3046 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2668 printk(KERN_INFO 3047 printk(KERN_INFO
2669 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", 3048 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
2670 btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); 3049 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
@@ -2712,7 +3091,7 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input)
2712 3091
2713static void gvc1100_muxsel(struct bttv *btv, unsigned int input) 3092static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
2714{ 3093{
2715 static const int masks[] = {0x30, 0x01, 0x12, 0x23}; 3094 static const int masks[] = {0x30, 0x01, 0x12, 0x23};
2716 gpio_write(masks[input%4]); 3095 gpio_write(masks[input%4]);
2717} 3096}
2718 3097
@@ -2778,26 +3157,27 @@ static void bttv_reset_audio(struct bttv *btv)
2778void __devinit bttv_init_card1(struct bttv *btv) 3157void __devinit bttv_init_card1(struct bttv *btv)
2779{ 3158{
2780 switch (btv->c.type) { 3159 switch (btv->c.type) {
2781 case BTTV_HAUPPAUGE: 3160 case BTTV_BOARD_HAUPPAUGE:
2782 case BTTV_HAUPPAUGE878: 3161 case BTTV_BOARD_HAUPPAUGE878:
2783 boot_msp34xx(btv,5); 3162 boot_msp34xx(btv,5);
2784 break; 3163 break;
2785 case BTTV_VOODOOTV_FM: 3164 case BTTV_BOARD_VOODOOTV_FM:
2786 boot_msp34xx(btv,20); 3165 boot_msp34xx(btv,20);
2787 break; 3166 break;
2788 case BTTV_AVERMEDIA98: 3167 case BTTV_BOARD_AVERMEDIA98:
2789 boot_msp34xx(btv,11); 3168 boot_msp34xx(btv,11);
2790 break; 3169 break;
2791 case BTTV_HAUPPAUGEPVR: 3170 case BTTV_BOARD_HAUPPAUGEPVR:
2792 pvr_boot(btv); 3171 pvr_boot(btv);
2793 break; 3172 break;
2794 case BTTV_TWINHAN_DST: 3173 case BTTV_BOARD_TWINHAN_DST:
2795 case BTTV_AVDVBT_771: 3174 case BTTV_BOARD_AVDVBT_771:
3175 case BTTV_BOARD_PINNACLESAT:
2796 btv->use_i2c_hw = 1; 3176 btv->use_i2c_hw = 1;
2797 break; 3177 break;
2798 case BTTV_ADLINK_RTV24: 3178 case BTTV_BOARD_ADLINK_RTV24:
2799 init_RTV24( btv ); 3179 init_RTV24( btv );
2800 break; 3180 break;
2801 3181
2802 } 3182 }
2803 if (!bttv_tvcards[btv->c.type].has_dvb) 3183 if (!bttv_tvcards[btv->c.type].has_dvb)
@@ -2810,53 +3190,53 @@ void __devinit bttv_init_card2(struct bttv *btv)
2810 int tda9887; 3190 int tda9887;
2811 int addr=ADDR_UNSET; 3191 int addr=ADDR_UNSET;
2812 3192
2813 btv->tuner_type = -1; 3193 btv->tuner_type = -1;
2814 3194
2815 if (BTTV_UNKNOWN == btv->c.type) { 3195 if (BTTV_BOARD_UNKNOWN == btv->c.type) {
2816 bttv_readee(btv,eeprom_data,0xa0); 3196 bttv_readee(btv,eeprom_data,0xa0);
2817 identify_by_eeprom(btv,eeprom_data); 3197 identify_by_eeprom(btv,eeprom_data);
2818 } 3198 }
2819 3199
2820 switch (btv->c.type) { 3200 switch (btv->c.type) {
2821 case BTTV_MIRO: 3201 case BTTV_BOARD_MIRO:
2822 case BTTV_MIROPRO: 3202 case BTTV_BOARD_MIROPRO:
2823 case BTTV_PINNACLE: 3203 case BTTV_BOARD_PINNACLE:
2824 case BTTV_PINNACLEPRO: 3204 case BTTV_BOARD_PINNACLEPRO:
2825 /* miro/pinnacle */ 3205 /* miro/pinnacle */
2826 miro_pinnacle_gpio(btv); 3206 miro_pinnacle_gpio(btv);
2827 break; 3207 break;
2828 case BTTV_FLYVIDEO_98: 3208 case BTTV_BOARD_FLYVIDEO_98:
2829 case BTTV_MAXI: 3209 case BTTV_BOARD_MAXI:
2830 case BTTV_LIFE_FLYKIT: 3210 case BTTV_BOARD_LIFE_FLYKIT:
2831 case BTTV_FLYVIDEO: 3211 case BTTV_BOARD_FLYVIDEO:
2832 case BTTV_TYPHOON_TVIEW: 3212 case BTTV_BOARD_TYPHOON_TVIEW:
2833 case BTTV_CHRONOS_VS2: 3213 case BTTV_BOARD_CHRONOS_VS2:
2834 case BTTV_FLYVIDEO_98FM: 3214 case BTTV_BOARD_FLYVIDEO_98FM:
2835 case BTTV_FLYVIDEO2000: 3215 case BTTV_BOARD_FLYVIDEO2000:
2836 case BTTV_FLYVIDEO98EZ: 3216 case BTTV_BOARD_FLYVIDEO98EZ:
2837 case BTTV_CONFERENCETV: 3217 case BTTV_BOARD_CONFERENCETV:
2838 case BTTV_LIFETEC_9415: 3218 case BTTV_BOARD_LIFETEC_9415:
2839 flyvideo_gpio(btv); 3219 flyvideo_gpio(btv);
2840 break; 3220 break;
2841 case BTTV_HAUPPAUGE: 3221 case BTTV_BOARD_HAUPPAUGE:
2842 case BTTV_HAUPPAUGE878: 3222 case BTTV_BOARD_HAUPPAUGE878:
2843 case BTTV_HAUPPAUGEPVR: 3223 case BTTV_BOARD_HAUPPAUGEPVR:
2844 /* pick up some config infos from the eeprom */ 3224 /* pick up some config infos from the eeprom */
2845 bttv_readee(btv,eeprom_data,0xa0); 3225 bttv_readee(btv,eeprom_data,0xa0);
2846 hauppauge_eeprom(btv); 3226 hauppauge_eeprom(btv);
2847 break; 3227 break;
2848 case BTTV_AVERMEDIA98: 3228 case BTTV_BOARD_AVERMEDIA98:
2849 case BTTV_AVPHONE98: 3229 case BTTV_BOARD_AVPHONE98:
2850 bttv_readee(btv,eeprom_data,0xa0); 3230 bttv_readee(btv,eeprom_data,0xa0);
2851 avermedia_eeprom(btv); 3231 avermedia_eeprom(btv);
2852 break; 3232 break;
2853 case BTTV_PXC200: 3233 case BTTV_BOARD_PXC200:
2854 init_PXC200(btv); 3234 init_PXC200(btv);
2855 break; 3235 break;
2856 case BTTV_PICOLO_TETRA_CHIP: 3236 case BTTV_BOARD_PICOLO_TETRA_CHIP:
2857 picolo_tetra_init(btv); 3237 picolo_tetra_init(btv);
2858 break; 3238 break;
2859 case BTTV_VHX: 3239 case BTTV_BOARD_VHX:
2860 btv->has_radio = 1; 3240 btv->has_radio = 1;
2861 btv->has_matchbox = 1; 3241 btv->has_matchbox = 1;
2862 btv->mbox_we = 0x20; 3242 btv->mbox_we = 0x20;
@@ -2865,58 +3245,58 @@ void __devinit bttv_init_card2(struct bttv *btv)
2865 btv->mbox_data = 0x10; 3245 btv->mbox_data = 0x10;
2866 btv->mbox_mask = 0x38; 3246 btv->mbox_mask = 0x38;
2867 break; 3247 break;
2868 case BTTV_VOBIS_BOOSTAR: 3248 case BTTV_BOARD_VOBIS_BOOSTAR:
2869 case BTTV_TERRATV: 3249 case BTTV_BOARD_TERRATV:
2870 terratec_active_radio_upgrade(btv); 3250 terratec_active_radio_upgrade(btv);
2871 break; 3251 break;
2872 case BTTV_MAGICTVIEW061: 3252 case BTTV_BOARD_MAGICTVIEW061:
2873 if (btv->cardid == 0x3002144f) { 3253 if (btv->cardid == 0x3002144f) {
2874 btv->has_radio=1; 3254 btv->has_radio=1;
2875 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr); 3255 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
2876 } 3256 }
2877 break; 3257 break;
2878 case BTTV_STB2: 3258 case BTTV_BOARD_STB2:
2879 if (btv->cardid == 0x3060121a) { 3259 if (btv->cardid == 0x3060121a) {
2880 /* Fix up entry for 3DFX VoodooTV 100, 3260 /* Fix up entry for 3DFX VoodooTV 100,
2881 which is an OEM STB card variant. */ 3261 which is an OEM STB card variant. */
2882 btv->has_radio=0; 3262 btv->has_radio=0;
2883 btv->tuner_type=TUNER_TEMIC_NTSC; 3263 btv->tuner_type=TUNER_TEMIC_NTSC;
2884 } 3264 }
2885 break; 3265 break;
2886 case BTTV_OSPREY1x0: 3266 case BTTV_BOARD_OSPREY1x0:
2887 case BTTV_OSPREY1x0_848: 3267 case BTTV_BOARD_OSPREY1x0_848:
2888 case BTTV_OSPREY101_848: 3268 case BTTV_BOARD_OSPREY101_848:
2889 case BTTV_OSPREY1x1: 3269 case BTTV_BOARD_OSPREY1x1:
2890 case BTTV_OSPREY1x1_SVID: 3270 case BTTV_BOARD_OSPREY1x1_SVID:
2891 case BTTV_OSPREY2xx: 3271 case BTTV_BOARD_OSPREY2xx:
2892 case BTTV_OSPREY2x0_SVID: 3272 case BTTV_BOARD_OSPREY2x0_SVID:
2893 case BTTV_OSPREY2x0: 3273 case BTTV_BOARD_OSPREY2x0:
2894 case BTTV_OSPREY500: 3274 case BTTV_BOARD_OSPREY500:
2895 case BTTV_OSPREY540: 3275 case BTTV_BOARD_OSPREY540:
2896 case BTTV_OSPREY2000: 3276 case BTTV_BOARD_OSPREY2000:
2897 bttv_readee(btv,eeprom_data,0xa0); 3277 bttv_readee(btv,eeprom_data,0xa0);
2898 osprey_eeprom(btv); 3278 osprey_eeprom(btv);
2899 break; 3279 break;
2900 case BTTV_IDS_EAGLE: 3280 case BTTV_BOARD_IDS_EAGLE:
2901 init_ids_eagle(btv); 3281 init_ids_eagle(btv);
2902 break; 3282 break;
2903 case BTTV_MODTEC_205: 3283 case BTTV_BOARD_MODTEC_205:
2904 bttv_readee(btv,eeprom_data,0xa0); 3284 bttv_readee(btv,eeprom_data,0xa0);
2905 modtec_eeprom(btv); 3285 modtec_eeprom(btv);
2906 break; 3286 break;
2907 case BTTV_LMLBT4: 3287 case BTTV_BOARD_LMLBT4:
2908 init_lmlbt4x(btv); 3288 init_lmlbt4x(btv);
2909 break; 3289 break;
2910 case BTTV_TIBET_CS16: 3290 case BTTV_BOARD_TIBET_CS16:
2911 tibetCS16_init(btv); 3291 tibetCS16_init(btv);
2912 break; 3292 break;
2913 case BTTV_KODICOM_4400R: 3293 case BTTV_BOARD_KODICOM_4400R:
2914 kodicom4400r_init(btv); 3294 kodicom4400r_init(btv);
2915 break; 3295 break;
2916 } 3296 }
2917 3297
2918 /* pll configuration */ 3298 /* pll configuration */
2919 if (!(btv->id==848 && btv->revision==0x11)) { 3299 if (!(btv->id==848 && btv->revision==0x11)) {
2920 /* defaults from card list */ 3300 /* defaults from card list */
2921 if (PLL_28 == bttv_tvcards[btv->c.type].pll) { 3301 if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
2922 btv->pll.pll_ifreq=28636363; 3302 btv->pll.pll_ifreq=28636363;
@@ -2927,26 +3307,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2927 btv->pll.pll_crystal=BT848_IFORM_XT1; 3307 btv->pll.pll_crystal=BT848_IFORM_XT1;
2928 } 3308 }
2929 /* insmod options can override */ 3309 /* insmod options can override */
2930 switch (pll[btv->c.nr]) { 3310 switch (pll[btv->c.nr]) {
2931 case 0: /* none */ 3311 case 0: /* none */
2932 btv->pll.pll_crystal = 0; 3312 btv->pll.pll_crystal = 0;
2933 btv->pll.pll_ifreq = 0; 3313 btv->pll.pll_ifreq = 0;
2934 btv->pll.pll_ofreq = 0; 3314 btv->pll.pll_ofreq = 0;
2935 break; 3315 break;
2936 case 1: /* 28 MHz */ 3316 case 1: /* 28 MHz */
2937 case 28: 3317 case 28:
2938 btv->pll.pll_ifreq = 28636363; 3318 btv->pll.pll_ifreq = 28636363;
2939 btv->pll.pll_ofreq = 0; 3319 btv->pll.pll_ofreq = 0;
2940 btv->pll.pll_crystal = BT848_IFORM_XT0; 3320 btv->pll.pll_crystal = BT848_IFORM_XT0;
2941 break; 3321 break;
2942 case 2: /* 35 MHz */ 3322 case 2: /* 35 MHz */
2943 case 35: 3323 case 35:
2944 btv->pll.pll_ifreq = 35468950; 3324 btv->pll.pll_ifreq = 35468950;
2945 btv->pll.pll_ofreq = 0; 3325 btv->pll.pll_ofreq = 0;
2946 btv->pll.pll_crystal = BT848_IFORM_XT1; 3326 btv->pll.pll_crystal = BT848_IFORM_XT1;
2947 break; 3327 break;
2948 } 3328 }
2949 } 3329 }
2950 btv->pll.pll_current = -1; 3330 btv->pll.pll_current = -1;
2951 3331
2952 /* tuner configuration (from card list / autodetect / insmod option) */ 3332 /* tuner configuration (from card list / autodetect / insmod option) */
@@ -2955,23 +3335,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2955 3335
2956 if (UNSET != bttv_tvcards[btv->c.type].tuner_type) 3336 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2957 if(UNSET == btv->tuner_type) 3337 if(UNSET == btv->tuner_type)
2958 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; 3338 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
2959 if (UNSET != tuner[btv->c.nr]) 3339 if (UNSET != tuner[btv->c.nr])
2960 btv->tuner_type = tuner[btv->c.nr]; 3340 btv->tuner_type = tuner[btv->c.nr];
2961 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); 3341 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
2962 if (btv->pinnacle_id != UNSET) 3342
2963 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
2964 &btv->pinnacle_id);
2965 if (btv->tuner_type != UNSET) { 3343 if (btv->tuner_type != UNSET) {
2966 struct tuner_setup tun_setup; 3344 struct tuner_setup tun_setup;
2967 3345
2968 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 3346 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
2969 tun_setup.type = btv->tuner_type; 3347 tun_setup.type = btv->tuner_type;
2970 tun_setup.addr = addr; 3348 tun_setup.addr = addr;
2971 3349
2972 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); 3350 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
2973 } 3351 }
2974 3352
3353 if (btv->pinnacle_id != UNSET) {
3354 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
3355 &btv->pinnacle_id);
3356 }
3357
2975 btv->svhs = bttv_tvcards[btv->c.type].svhs; 3358 btv->svhs = bttv_tvcards[btv->c.type].svhs;
2976 if (svhs[btv->c.nr] != UNSET) 3359 if (svhs[btv->c.nr] != UNSET)
2977 btv->svhs = svhs[btv->c.nr]; 3360 btv->svhs = svhs[btv->c.nr];
@@ -2982,8 +3365,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
2982 btv->has_radio=1; 3365 btv->has_radio=1;
2983 if (bttv_tvcards[btv->c.type].has_remote) 3366 if (bttv_tvcards[btv->c.type].has_remote)
2984 btv->has_remote=1; 3367 btv->has_remote=1;
2985 if (bttv_tvcards[btv->c.type].no_gpioirq) 3368 if (!bttv_tvcards[btv->c.type].no_gpioirq)
2986 btv->gpioirq=0; 3369 btv->gpioirq=1;
2987 if (bttv_tvcards[btv->c.type].audio_hook) 3370 if (bttv_tvcards[btv->c.type].audio_hook)
2988 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; 3371 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
2989 3372
@@ -3024,6 +3407,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
3024 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && 3407 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
3025 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) 3408 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
3026 tda9887 = 1; 3409 tda9887 = 1;
3410 /* Hybrid DVB card, DOES have a tda9887 */
3411 if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE)
3412 tda9887 = 1;
3027 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) || 3413 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
3028 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) || 3414 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
3029 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) || 3415 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
@@ -3045,11 +3431,11 @@ static void modtec_eeprom(struct bttv *btv)
3045 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { 3431 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
3046 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; 3432 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
3047 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3433 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3048 btv->c.nr,&eeprom_data[0x1e]); 3434 btv->c.nr,&eeprom_data[0x1e]);
3049 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { 3435 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
3050 btv->tuner_type=TUNER_PHILIPS_NTSC; 3436 btv->tuner_type=TUNER_PHILIPS_NTSC;
3051 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3437 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3052 btv->c.nr,&eeprom_data[0x1e]); 3438 btv->c.nr,&eeprom_data[0x1e]);
3053 } else { 3439 } else {
3054 printk("bttv%d: Modtec: Unknown TunerString: %s\n", 3440 printk("bttv%d: Modtec: Unknown TunerString: %s\n",
3055 btv->c.nr,&eeprom_data[0x1e]); 3441 btv->c.nr,&eeprom_data[0x1e]);
@@ -3114,7 +3500,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
3114static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) 3500static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3115{ 3501{
3116 u32 n; 3502 u32 n;
3117 u8 bits; 3503 u8 bits;
3118 int i; 3504 int i;
3119 3505
3120 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); 3506 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
@@ -3150,19 +3536,19 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3150 3536
3151static int __devinit pvr_boot(struct bttv *btv) 3537static int __devinit pvr_boot(struct bttv *btv)
3152{ 3538{
3153 const struct firmware *fw_entry; 3539 const struct firmware *fw_entry;
3154 int rc; 3540 int rc;
3155 3541
3156 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); 3542 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
3157 if (rc != 0) { 3543 if (rc != 0) {
3158 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", 3544 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
3159 btv->c.nr); 3545 btv->c.nr);
3160 return rc; 3546 return rc;
3161 } 3547 }
3162 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); 3548 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
3163 printk(KERN_INFO "bttv%d: altera firmware upload %s\n", 3549 printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
3164 btv->c.nr, (rc < 0) ? "failed" : "ok"); 3550 btv->c.nr, (rc < 0) ? "failed" : "ok");
3165 release_firmware(fw_entry); 3551 release_firmware(fw_entry);
3166 return rc; 3552 return rc;
3167} 3553}
3168 3554
@@ -3176,33 +3562,33 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3176 unsigned long serial = 0; 3562 unsigned long serial = 0;
3177 3563
3178 if (btv->c.type == 0) { 3564 if (btv->c.type == 0) {
3179 /* this might be an antique... check for MMAC label in eeprom */ 3565 /* this might be an antique... check for MMAC label in eeprom */
3180 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { 3566 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3181 unsigned char checksum = 0; 3567 unsigned char checksum = 0;
3182 for (i =0; i<21; i++) 3568 for (i =0; i<21; i++)
3183 checksum += ee[i]; 3569 checksum += ee[i];
3184 if (checksum != ee[21]) 3570 if (checksum != ee[21])
3185 return; 3571 return;
3186 btv->c.type = BTTV_OSPREY1x0_848; 3572 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3187 for (i = 12; i < 21; i++) 3573 for (i = 12; i < 21; i++)
3188 serial *= 10, serial += ee[i] - '0'; 3574 serial *= 10, serial += ee[i] - '0';
3189 } 3575 }
3190 } else { 3576 } else {
3191 unsigned short type; 3577 unsigned short type;
3192 int offset = 4*16; 3578 int offset = 4*16;
3193 3579
3194 for(; offset < 8*16; offset += 16) { 3580 for(; offset < 8*16; offset += 16) {
3195 unsigned short checksum = 0; 3581 unsigned short checksum = 0;
3196 /* verify the checksum */ 3582 /* verify the checksum */
3197 for(i = 0; i<14; i++) checksum += ee[i+offset]; 3583 for(i = 0; i<14; i++) checksum += ee[i+offset];
3198 checksum = ~checksum; /* no idea why */ 3584 checksum = ~checksum; /* no idea why */
3199 if ((((checksum>>8)&0x0FF) == ee[offset+14]) && 3585 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3200 ((checksum & 0x0FF) == ee[offset+15])) { 3586 ((checksum & 0x0FF) == ee[offset+15])) {
3201 break; 3587 break;
3202 } 3588 }
3203 } 3589 }
3204 3590
3205 if (offset >= 8*16) 3591 if (offset >= 8*16)
3206 return; 3592 return;
3207 3593
3208 /* found a valid descriptor */ 3594 /* found a valid descriptor */
@@ -3212,47 +3598,47 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3212 3598
3213 /* 848 based */ 3599 /* 848 based */
3214 case 0x0004: 3600 case 0x0004:
3215 btv->c.type = BTTV_OSPREY1x0_848; 3601 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3216 break; 3602 break;
3217 case 0x0005: 3603 case 0x0005:
3218 btv->c.type = BTTV_OSPREY101_848; 3604 btv->c.type = BTTV_BOARD_OSPREY101_848;
3219 break; 3605 break;
3220 3606
3221 /* 878 based */ 3607 /* 878 based */
3222 case 0x0012: 3608 case 0x0012:
3223 case 0x0013: 3609 case 0x0013:
3224 btv->c.type = BTTV_OSPREY1x0; 3610 btv->c.type = BTTV_BOARD_OSPREY1x0;
3225 break; 3611 break;
3226 case 0x0014: 3612 case 0x0014:
3227 case 0x0015: 3613 case 0x0015:
3228 btv->c.type = BTTV_OSPREY1x1; 3614 btv->c.type = BTTV_BOARD_OSPREY1x1;
3229 break; 3615 break;
3230 case 0x0016: 3616 case 0x0016:
3231 case 0x0017: 3617 case 0x0017:
3232 case 0x0020: 3618 case 0x0020:
3233 btv->c.type = BTTV_OSPREY1x1_SVID; 3619 btv->c.type = BTTV_BOARD_OSPREY1x1_SVID;
3234 break; 3620 break;
3235 case 0x0018: 3621 case 0x0018:
3236 case 0x0019: 3622 case 0x0019:
3237 case 0x001E: 3623 case 0x001E:
3238 case 0x001F: 3624 case 0x001F:
3239 btv->c.type = BTTV_OSPREY2xx; 3625 btv->c.type = BTTV_BOARD_OSPREY2xx;
3240 break; 3626 break;
3241 case 0x001A: 3627 case 0x001A:
3242 case 0x001B: 3628 case 0x001B:
3243 btv->c.type = BTTV_OSPREY2x0_SVID; 3629 btv->c.type = BTTV_BOARD_OSPREY2x0_SVID;
3244 break; 3630 break;
3245 case 0x0040: 3631 case 0x0040:
3246 btv->c.type = BTTV_OSPREY500; 3632 btv->c.type = BTTV_BOARD_OSPREY500;
3247 break; 3633 break;
3248 case 0x0050: 3634 case 0x0050:
3249 case 0x0056: 3635 case 0x0056:
3250 btv->c.type = BTTV_OSPREY540; 3636 btv->c.type = BTTV_BOARD_OSPREY540;
3251 /* bttv_osprey_540_init(btv); */ 3637 /* bttv_osprey_540_init(btv); */
3252 break; 3638 break;
3253 case 0x0060: 3639 case 0x0060:
3254 case 0x0070: 3640 case 0x0070:
3255 btv->c.type = BTTV_OSPREY2x0; 3641 btv->c.type = BTTV_BOARD_OSPREY2x0;
3256 /* enable output on select control lines */ 3642 /* enable output on select control lines */
3257 gpio_inout(0xffffff,0x000303); 3643 gpio_inout(0xffffff,0x000303);
3258 break; 3644 break;
@@ -3274,27 +3660,27 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3274/* AVermedia specific stuff, from bktr_card.c */ 3660/* AVermedia specific stuff, from bktr_card.c */
3275 3661
3276static int tuner_0_table[] = { 3662static int tuner_0_table[] = {
3277 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, 3663 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
3278 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, 3664 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
3279 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, 3665 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
3280 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, 3666 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
3281 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, 3667 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
3282 TUNER_PHILIPS_FM1216ME_MK3 }; 3668 TUNER_PHILIPS_FM1216ME_MK3 };
3283 3669
3284static int tuner_1_table[] = { 3670static int tuner_1_table[] = {
3285 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, 3671 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3286 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3672 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3287 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3673 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3288 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */ 3674 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
3289 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; 3675 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3290 3676
3291static void __devinit avermedia_eeprom(struct bttv *btv) 3677static void __devinit avermedia_eeprom(struct bttv *btv)
3292{ 3678{
3293 int tuner_make,tuner_tv_fm,tuner_format,tuner=0; 3679 int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
3294 3680
3295 tuner_make = (eeprom_data[0x41] & 0x7); 3681 tuner_make = (eeprom_data[0x41] & 0x7);
3296 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; 3682 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
3297 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; 3683 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
3298 btv->has_remote = (eeprom_data[0x42] & 0x01); 3684 btv->has_remote = (eeprom_data[0x42] & 0x01);
3299 3685
3300 if (tuner_make == 0 || tuner_make == 2) 3686 if (tuner_make == 0 || tuner_make == 2)
@@ -3325,13 +3711,13 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3325{ 3711{
3326 /* fix up our card entry */ 3712 /* fix up our card entry */
3327 if(norm==VIDEO_MODE_NTSC) { 3713 if(norm==VIDEO_MODE_NTSC) {
3328 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff; 3714 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x957fff;
3329 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff; 3715 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x957fff;
3330 dprintk("bttv_tda9880_setnorm to NTSC\n"); 3716 dprintk("bttv_tda9880_setnorm to NTSC\n");
3331 } 3717 }
3332 else { 3718 else {
3333 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff; 3719 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x947fff;
3334 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff; 3720 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x947fff;
3335 dprintk("bttv_tda9880_setnorm to PAL\n"); 3721 dprintk("bttv_tda9880_setnorm to PAL\n");
3336 } 3722 }
3337 /* set GPIO according */ 3723 /* set GPIO according */
@@ -3342,7 +3728,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3342 3728
3343/* 3729/*
3344 * reset/enable the MSP on some Hauppauge cards 3730 * reset/enable the MSP on some Hauppauge cards
3345 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! 3731 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
3346 * 3732 *
3347 * Hauppauge: pin 5 3733 * Hauppauge: pin 5
3348 * Voodoo: pin 20 3734 * Voodoo: pin 20
@@ -3353,7 +3739,7 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
3353 3739
3354 gpio_inout(mask,mask); 3740 gpio_inout(mask,mask);
3355 gpio_bits(mask,0); 3741 gpio_bits(mask,0);
3356 udelay(2500); 3742 udelay(2500);
3357 gpio_bits(mask,mask); 3743 gpio_bits(mask,mask);
3358 3744
3359 if (bttv_gpio) 3745 if (bttv_gpio)
@@ -3429,7 +3815,7 @@ static void __devinit init_PXC200(struct bttv *btv)
3429 udelay(10); 3815 udelay(10);
3430 gpio_write(1<<2); 3816 gpio_write(1<<2);
3431 3817
3432 for (i = 0; i < ARRAY_SIZE(vals); i++) { 3818 for (i = 0; i < ARRAY_SIZE(vals); i++) {
3433 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); 3819 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
3434 if (tmp != -1) { 3820 if (tmp != -1) {
3435 printk(KERN_INFO 3821 printk(KERN_INFO
@@ -3872,30 +4258,30 @@ avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
3872static void 4258static void
3873lt9415_audio(struct bttv *btv, struct video_audio *v, int set) 4259lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
3874{ 4260{
3875 int val = 0; 4261 int val = 0;
3876 4262
3877 if (gpio_read() & 0x4000) { 4263 if (gpio_read() & 0x4000) {
3878 v->mode = VIDEO_SOUND_MONO; 4264 v->mode = VIDEO_SOUND_MONO;
3879 return; 4265 return;
3880 } 4266 }
3881 4267
3882 if (set) { 4268 if (set) {
3883 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */ 4269 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
3884 val = 0x0080; 4270 val = 0x0080;
3885 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */ 4271 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
3886 val = 0x0880; 4272 val = 0x0880;
3887 if ((v->mode & VIDEO_SOUND_LANG1) || 4273 if ((v->mode & VIDEO_SOUND_LANG1) ||
3888 (v->mode & VIDEO_SOUND_MONO)) 4274 (v->mode & VIDEO_SOUND_MONO))
3889 val = 0; 4275 val = 0;
3890 gpio_bits(0x0880, val); 4276 gpio_bits(0x0880, val);
3891 if (bttv_gpio) 4277 if (bttv_gpio)
3892 bttv_gpio_tracking(btv,"lt9415"); 4278 bttv_gpio_tracking(btv,"lt9415");
3893 } else { 4279 } else {
3894 /* autodetect doesn't work with this card :-( */ 4280 /* autodetect doesn't work with this card :-( */
3895 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4281 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3896 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4282 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3897 return; 4283 return;
3898 } 4284 }
3899} 4285}
3900 4286
3901/* TDA9821 on TerraTV+ Bt848, Bt878 */ 4287/* TDA9821 on TerraTV+ Bt848, Bt878 */
@@ -4018,26 +4404,26 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
4018static void 4404static void
4019windvr_audio(struct bttv *btv, struct video_audio *v, int set) 4405windvr_audio(struct bttv *btv, struct video_audio *v, int set)
4020{ 4406{
4021 unsigned long val = 0; 4407 unsigned long val = 0;
4022 4408
4023 if (set) { 4409 if (set) {
4024 if (v->mode & VIDEO_SOUND_MONO) 4410 if (v->mode & VIDEO_SOUND_MONO)
4025 val = 0x040000; 4411 val = 0x040000;
4026 if (v->mode & VIDEO_SOUND_LANG1) 4412 if (v->mode & VIDEO_SOUND_LANG1)
4027 val = 0; 4413 val = 0;
4028 if (v->mode & VIDEO_SOUND_LANG2) 4414 if (v->mode & VIDEO_SOUND_LANG2)
4029 val = 0x100000; 4415 val = 0x100000;
4030 if (v->mode & VIDEO_SOUND_STEREO) 4416 if (v->mode & VIDEO_SOUND_STEREO)
4031 val = 0; 4417 val = 0;
4032 if (val) { 4418 if (val) {
4033 gpio_bits(0x140000, val); 4419 gpio_bits(0x140000, val);
4034 if (bttv_gpio) 4420 if (bttv_gpio)
4035 bttv_gpio_tracking(btv,"windvr"); 4421 bttv_gpio_tracking(btv,"windvr");
4036 } 4422 }
4037 } else { 4423 } else {
4038 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4424 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4039 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4425 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4040 } 4426 }
4041} 4427}
4042 4428
4043/* 4429/*
@@ -4280,10 +4666,10 @@ static void kodicom4400r_init(struct bttv *btv)
4280static void xguard_muxsel(struct bttv *btv, unsigned int input) 4666static void xguard_muxsel(struct bttv *btv, unsigned int input)
4281{ 4667{
4282 static const int masks[] = { 4668 static const int masks[] = {
4283 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, 4669 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
4284 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, 4670 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
4285 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, 4671 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
4286 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, 4672 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
4287 }; 4673 };
4288 gpio_write(masks[input%16]); 4674 gpio_write(masks[input%16]);
4289} 4675}
@@ -4388,10 +4774,10 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4388 4774
4389static void PXC200_muxsel(struct bttv *btv, unsigned int input) 4775static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4390{ 4776{
4391 int rc; 4777 int rc;
4392 long mux; 4778 long mux;
4393 int bitmask; 4779 int bitmask;
4394 unsigned char buf[2]; 4780 unsigned char buf[2];
4395 4781
4396 /* Read PIC config to determine if this is a PXC200F */ 4782 /* Read PIC config to determine if this is a PXC200F */
4397 /* PX_I2C_CMD_CFG*/ 4783 /* PX_I2C_CMD_CFG*/
@@ -4421,14 +4807,14 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4421 /* bitmask=0x30f; */ 4807 /* bitmask=0x30f; */
4422 bitmask=0x302; 4808 bitmask=0x302;
4423 /* check whether we have a PXC200A */ 4809 /* check whether we have a PXC200A */
4424 if (btv->cardid == PX_PXC200A_CARDID) { 4810 if (btv->cardid == PX_PXC200A_CARDID) {
4425 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ 4811 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
4426 bitmask |= 7<<4; /* the DAC */ 4812 bitmask |= 7<<4; /* the DAC */
4427 } 4813 }
4428 btwrite(bitmask, BT848_GPIO_OUT_EN); 4814 btwrite(bitmask, BT848_GPIO_OUT_EN);
4429 4815
4430 bitmask = btread(BT848_GPIO_DATA); 4816 bitmask = btread(BT848_GPIO_DATA);
4431 if (btv->cardid == PX_PXC200A_CARDID) 4817 if (btv->cardid == PX_PXC200A_CARDID)
4432 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); 4818 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
4433 else /* older device */ 4819 else /* older device */
4434 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); 4820 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
@@ -4441,7 +4827,7 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4441 * 4827 *
4442 * needed because bttv-driver sets mux before calling this function 4828 * needed because bttv-driver sets mux before calling this function
4443 */ 4829 */
4444 if (btv->cardid == PX_PXC200A_CARDID) 4830 if (btv->cardid == PX_PXC200A_CARDID)
4445 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); 4831 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
4446 else /* older device */ 4832 else /* older device */
4447 btand(~BT848_IFORM_MUXSEL,BT848_IFORM); 4833 btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
@@ -4485,10 +4871,9 @@ void __devinit bttv_check_chipset(void)
4485 } 4871 }
4486 if (UNSET != latency) 4872 if (UNSET != latency)
4487 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency); 4873 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
4488 4874 while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
4489 while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
4490 PCI_DEVICE_ID_INTEL_82441, dev))) { 4875 PCI_DEVICE_ID_INTEL_82441, dev))) {
4491 unsigned char b; 4876 unsigned char b;
4492 pci_read_config_byte(dev, 0x53, &b); 4877 pci_read_config_byte(dev, 0x53, &b);
4493 if (bttv_debug) 4878 if (bttv_debug)
4494 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, " 4879 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
@@ -4498,7 +4883,7 @@ void __devinit bttv_check_chipset(void)
4498 4883
4499int __devinit bttv_handle_chipset(struct bttv *btv) 4884int __devinit bttv_handle_chipset(struct bttv *btv)
4500{ 4885{
4501 unsigned char command; 4886 unsigned char command;
4502 4887
4503 if (!triton1 && !vsfx && UNSET == latency) 4888 if (!triton1 && !vsfx && UNSET == latency)
4504 return 0; 4889 return 0;
@@ -4519,13 +4904,13 @@ int __devinit bttv_handle_chipset(struct bttv *btv)
4519 btv->triton1 = BT848_INT_ETBF; 4904 btv->triton1 = BT848_INT_ETBF;
4520 } else { 4905 } else {
4521 /* bt878 has a bit in the pci config space for it */ 4906 /* bt878 has a bit in the pci config space for it */
4522 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); 4907 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
4523 if (triton1) 4908 if (triton1)
4524 command |= BT878_EN_TBFX; 4909 command |= BT878_EN_TBFX;
4525 if (vsfx) 4910 if (vsfx)
4526 command |= BT878_EN_VSFX; 4911 command |= BT878_EN_VSFX;
4527 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); 4912 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
4528 } 4913 }
4529 if (UNSET != latency) 4914 if (UNSET != latency)
4530 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); 4915 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
4531 return 0; 4916 return 0;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index d538a994ff04..0005741d5514 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3,7 +3,7 @@
3 bttv - Bt848 frame grabber driver 3 bttv - Bt848 frame grabber driver
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> 5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
6 & Marcus Metzler <mocm@thp.uni-koeln.de> 6 & Marcus Metzler <mocm@thp.uni-koeln.de>
7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org> 7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
8 8
9 some v4l2 code lines are taken from Justin's bttv2 driver which is 9 some v4l2 code lines are taken from Justin's bttv2 driver which is
@@ -192,8 +192,8 @@ static u8 SRAM_Table[][60] =
192 192
193const struct bttv_tvnorm bttv_tvnorms[] = { 193const struct bttv_tvnorm bttv_tvnorms[] = {
194 /* PAL-BDGHI */ 194 /* PAL-BDGHI */
195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ 195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ 196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
197 { 197 {
198 .v4l2_id = V4L2_STD_PAL, 198 .v4l2_id = V4L2_STD_PAL,
199 .name = "PAL", 199 .name = "PAL",
@@ -806,9 +806,9 @@ static void bt848A_set_timing(struct bttv *btv)
806 btv->c.nr,table_idx); 806 btv->c.nr,table_idx);
807 807
808 /* timing change...reset timing generator address */ 808 /* timing change...reset timing generator address */
809 btwrite(0x00, BT848_TGCTRL); 809 btwrite(0x00, BT848_TGCTRL);
810 btwrite(0x02, BT848_TGCTRL); 810 btwrite(0x02, BT848_TGCTRL);
811 btwrite(0x00, BT848_TGCTRL); 811 btwrite(0x00, BT848_TGCTRL);
812 812
813 len=SRAM_Table[table_idx][0]; 813 len=SRAM_Table[table_idx][0];
814 for(i = 1; i <= len; i++) 814 for(i = 1; i <= len; i++)
@@ -847,7 +847,7 @@ static void bt848_hue(struct bttv *btv, int hue)
847 847
848 /* -128 to 127 */ 848 /* -128 to 127 */
849 value = (hue >> 8) - 128; 849 value = (hue >> 8) - 128;
850 btwrite(value & 0xff, BT848_HUE); 850 btwrite(value & 0xff, BT848_HUE);
851} 851}
852 852
853static void bt848_contrast(struct bttv *btv, int cont) 853static void bt848_contrast(struct bttv *btv, int cont)
@@ -859,9 +859,9 @@ static void bt848_contrast(struct bttv *btv, int cont)
859 /* 0-511 */ 859 /* 0-511 */
860 value = (cont >> 7); 860 value = (cont >> 7);
861 hibit = (value >> 6) & 4; 861 hibit = (value >> 6) & 4;
862 btwrite(value & 0xff, BT848_CONTRAST_LO); 862 btwrite(value & 0xff, BT848_CONTRAST_LO);
863 btaor(hibit, ~4, BT848_E_CONTROL); 863 btaor(hibit, ~4, BT848_E_CONTROL);
864 btaor(hibit, ~4, BT848_O_CONTROL); 864 btaor(hibit, ~4, BT848_O_CONTROL);
865} 865}
866 866
867static void bt848_sat(struct bttv *btv, int color) 867static void bt848_sat(struct bttv *btv, int color)
@@ -873,12 +873,12 @@ static void bt848_sat(struct bttv *btv, int color)
873 /* 0-511 for the color */ 873 /* 0-511 for the color */
874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; 874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; 875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
876 hibits = (val_u >> 7) & 2; 876 hibits = (val_u >> 7) & 2;
877 hibits |= (val_v >> 8) & 1; 877 hibits |= (val_v >> 8) & 1;
878 btwrite(val_u & 0xff, BT848_SAT_U_LO); 878 btwrite(val_u & 0xff, BT848_SAT_U_LO);
879 btwrite(val_v & 0xff, BT848_SAT_V_LO); 879 btwrite(val_v & 0xff, BT848_SAT_V_LO);
880 btaor(hibits, ~3, BT848_E_CONTROL); 880 btaor(hibits, ~3, BT848_E_CONTROL);
881 btaor(hibits, ~3, BT848_O_CONTROL); 881 btaor(hibits, ~3, BT848_O_CONTROL);
882} 882}
883 883
884/* ----------------------------------------------------------------------- */ 884/* ----------------------------------------------------------------------- */
@@ -891,7 +891,7 @@ video_mux(struct bttv *btv, unsigned int input)
891 if (input >= bttv_tvcards[btv->c.type].video_inputs) 891 if (input >= bttv_tvcards[btv->c.type].video_inputs)
892 return -EINVAL; 892 return -EINVAL;
893 893
894 /* needed by RemoteVideo MX */ 894 /* needed by RemoteVideo MX */
895 mask2 = bttv_tvcards[btv->c.type].gpiomask2; 895 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
896 if (mask2) 896 if (mask2)
897 gpio_inout(mask2,mask2); 897 gpio_inout(mask2,mask2);
@@ -964,7 +964,7 @@ i2c_vidiocschan(struct bttv *btv)
964 c.norm = btv->tvnorm; 964 c.norm = btv->tvnorm;
965 c.channel = btv->input; 965 c.channel = btv->input;
966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); 966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
967 if (btv->c.type == BTTV_VOODOOTV_FM) 967 if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
968 bttv_tda9880_setnorm(btv,c.norm); 968 bttv_tda9880_setnorm(btv,c.norm);
969} 969}
970 970
@@ -988,7 +988,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
988 bt848A_set_timing(btv); 988 bt848A_set_timing(btv);
989 989
990 switch (btv->c.type) { 990 switch (btv->c.type) {
991 case BTTV_VOODOOTV_FM: 991 case BTTV_BOARD_VOODOOTV_FM:
992 bttv_tda9880_setnorm(btv,norm); 992 bttv_tda9880_setnorm(btv,norm);
993 break; 993 break;
994 } 994 }
@@ -1055,22 +1055,22 @@ static void init_bt848(struct bttv *btv)
1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); 1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); 1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1057 1057
1058 /* set planar and packed mode trigger points and */ 1058 /* set planar and packed mode trigger points and */
1059 /* set rising edge of inverted GPINTR pin as irq trigger */ 1059 /* set rising edge of inverted GPINTR pin as irq trigger */
1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32| 1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1061 BT848_GPIO_DMA_CTL_PLTP1_16| 1061 BT848_GPIO_DMA_CTL_PLTP1_16|
1062 BT848_GPIO_DMA_CTL_PLTP23_16| 1062 BT848_GPIO_DMA_CTL_PLTP23_16|
1063 BT848_GPIO_DMA_CTL_GPINTC| 1063 BT848_GPIO_DMA_CTL_GPINTC|
1064 BT848_GPIO_DMA_CTL_GPINTI, 1064 BT848_GPIO_DMA_CTL_GPINTI,
1065 BT848_GPIO_DMA_CTL); 1065 BT848_GPIO_DMA_CTL);
1066 1066
1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; 1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1068 btwrite(val, BT848_E_SCLOOP); 1068 btwrite(val, BT848_E_SCLOOP);
1069 btwrite(val, BT848_O_SCLOOP); 1069 btwrite(val, BT848_O_SCLOOP);
1070 1070
1071 btwrite(0x20, BT848_E_VSCALE_HI); 1071 btwrite(0x20, BT848_E_VSCALE_HI);
1072 btwrite(0x20, BT848_O_VSCALE_HI); 1072 btwrite(0x20, BT848_O_VSCALE_HI);
1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), 1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1074 BT848_ADC); 1074 BT848_ADC);
1075 1075
1076 btwrite(whitecrush_upper, BT848_WC_UP); 1076 btwrite(whitecrush_upper, BT848_WC_UP);
@@ -1089,7 +1089,7 @@ static void init_bt848(struct bttv *btv)
1089 bt848_contrast(btv, btv->contrast); 1089 bt848_contrast(btv, btv->contrast);
1090 bt848_sat(btv, btv->saturation); 1090 bt848_sat(btv, btv->saturation);
1091 1091
1092 /* interrupt */ 1092 /* interrupt */
1093 init_irqreg(btv); 1093 init_irqreg(btv);
1094} 1094}
1095 1095
@@ -1105,7 +1105,7 @@ static void bttv_reinit_bt848(struct bttv *btv)
1105 spin_unlock_irqrestore(&btv->s_lock,flags); 1105 spin_unlock_irqrestore(&btv->s_lock,flags);
1106 1106
1107 init_bt848(btv); 1107 init_bt848(btv);
1108 btv->pll.pll_current = -1; 1108 btv->pll.pll_current = -1;
1109 set_input(btv,btv->input); 1109 set_input(btv,btv->input);
1110} 1110}
1111 1111
@@ -1398,7 +1398,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1398/* video4linux (1) interface */ 1398/* video4linux (1) interface */
1399 1399
1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, 1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
1401 const struct bttv_format *fmt, 1401 const struct bttv_format *fmt,
1402 unsigned int width, unsigned int height, 1402 unsigned int width, unsigned int height,
1403 enum v4l2_field field) 1403 enum v4l2_field field)
1404{ 1404{
@@ -1521,8 +1521,8 @@ static const char *v4l1_ioctls[] = {
1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) 1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1522{ 1522{
1523 switch (cmd) { 1523 switch (cmd) {
1524 case BTTV_VERSION: 1524 case BTTV_VERSION:
1525 return BTTV_VERSION_CODE; 1525 return BTTV_VERSION_CODE;
1526 1526
1527 /* *** v4l1 *** ************************************************ */ 1527 /* *** v4l1 *** ************************************************ */
1528 case VIDIOCGFREQ: 1528 case VIDIOCGFREQ:
@@ -1576,32 +1576,32 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1576 return 0; 1576 return 0;
1577 } 1577 }
1578 1578
1579 case VIDIOCGCHAN: 1579 case VIDIOCGCHAN:
1580 { 1580 {
1581 struct video_channel *v = arg; 1581 struct video_channel *v = arg;
1582 unsigned int channel = v->channel; 1582 unsigned int channel = v->channel;
1583 1583
1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1585 return -EINVAL; 1585 return -EINVAL;
1586 v->tuners=0; 1586 v->tuners=0;
1587 v->flags = VIDEO_VC_AUDIO; 1587 v->flags = VIDEO_VC_AUDIO;
1588 v->type = VIDEO_TYPE_CAMERA; 1588 v->type = VIDEO_TYPE_CAMERA;
1589 v->norm = btv->tvnorm; 1589 v->norm = btv->tvnorm;
1590 if (channel == bttv_tvcards[btv->c.type].tuner) { 1590 if (channel == bttv_tvcards[btv->c.type].tuner) {
1591 strcpy(v->name,"Television"); 1591 strcpy(v->name,"Television");
1592 v->flags|=VIDEO_VC_TUNER; 1592 v->flags|=VIDEO_VC_TUNER;
1593 v->type=VIDEO_TYPE_TV; 1593 v->type=VIDEO_TYPE_TV;
1594 v->tuners=1; 1594 v->tuners=1;
1595 } else if (channel == btv->svhs) { 1595 } else if (channel == btv->svhs) {
1596 strcpy(v->name,"S-Video"); 1596 strcpy(v->name,"S-Video");
1597 } else { 1597 } else {
1598 sprintf(v->name,"Composite%d",channel); 1598 sprintf(v->name,"Composite%d",channel);
1599 } 1599 }
1600 return 0; 1600 return 0;
1601 } 1601 }
1602 case VIDIOCSCHAN: 1602 case VIDIOCSCHAN:
1603 { 1603 {
1604 struct video_channel *v = arg; 1604 struct video_channel *v = arg;
1605 unsigned int channel = v->channel; 1605 unsigned int channel = v->channel;
1606 1606
1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
@@ -1623,7 +1623,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1623 return 0; 1623 return 0;
1624 } 1624 }
1625 1625
1626 case VIDIOCGAUDIO: 1626 case VIDIOCGAUDIO:
1627 { 1627 {
1628 struct video_audio *v = arg; 1628 struct video_audio *v = arg;
1629 1629
@@ -1728,7 +1728,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1728 } else if (i->index == btv->svhs) { 1728 } else if (i->index == btv->svhs) {
1729 sprintf(i->name, "S-Video"); 1729 sprintf(i->name, "S-Video");
1730 } else { 1730 } else {
1731 sprintf(i->name,"Composite%d",i->index); 1731 sprintf(i->name,"Composite%d",i->index);
1732 } 1732 }
1733 if (i->index == btv->input) { 1733 if (i->index == btv->input) {
1734 __u32 dstatus = btread(BT848_DSTATUS); 1734 __u32 dstatus = btread(BT848_DSTATUS);
@@ -1851,6 +1851,11 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1851 up(&btv->lock); 1851 up(&btv->lock);
1852 return 0; 1852 return 0;
1853 } 1853 }
1854 case VIDIOC_LOG_STATUS:
1855 {
1856 bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, 0);
1857 return 0;
1858 }
1854 1859
1855 default: 1860 default:
1856 return -ENOIOCTLCMD; 1861 return -ENOIOCTLCMD;
@@ -2163,7 +2168,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2163 if (0 != retval) 2168 if (0 != retval)
2164 return retval; 2169 return retval;
2165 if (locked_btres(fh->btv, RESOURCE_VBI)) 2170 if (locked_btres(fh->btv, RESOURCE_VBI))
2166 return -EBUSY; 2171 return -EBUSY;
2167 bttv_vbi_try_fmt(fh,f); 2172 bttv_vbi_try_fmt(fh,f);
2168 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]); 2173 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2169 bttv_vbi_get_fmt(fh,f); 2174 bttv_vbi_get_fmt(fh,f);
@@ -2201,9 +2206,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2201 bttv_reinit_bt848(btv); 2206 bttv_reinit_bt848(btv);
2202 2207
2203 switch (cmd) { 2208 switch (cmd) {
2204 case VIDIOCSFREQ: 2209 case VIDIOCSFREQ:
2205 case VIDIOCSTUNER: 2210 case VIDIOCSTUNER:
2206 case VIDIOCSCHAN: 2211 case VIDIOCSCHAN:
2207 case VIDIOC_S_CTRL: 2212 case VIDIOC_S_CTRL:
2208 case VIDIOC_S_STD: 2213 case VIDIOC_S_STD:
2209 case VIDIOC_S_INPUT: 2214 case VIDIOC_S_INPUT:
@@ -2219,10 +2224,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2219 /* *** v4l1 *** ************************************************ */ 2224 /* *** v4l1 *** ************************************************ */
2220 case VIDIOCGCAP: 2225 case VIDIOCGCAP:
2221 { 2226 {
2222 struct video_capability *cap = arg; 2227 struct video_capability *cap = arg;
2223 2228
2224 memset(cap,0,sizeof(*cap)); 2229 memset(cap,0,sizeof(*cap));
2225 strcpy(cap->name,btv->video_dev->name); 2230 strcpy(cap->name,btv->video_dev->name);
2226 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 2231 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2227 /* vbi */ 2232 /* vbi */
2228 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; 2233 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
@@ -2242,7 +2247,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2242 } 2247 }
2243 cap->channels = bttv_tvcards[btv->c.type].video_inputs; 2248 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2244 cap->audios = bttv_tvcards[btv->c.type].audio_inputs; 2249 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
2245 return 0; 2250 return 0;
2246 } 2251 }
2247 2252
2248 case VIDIOCGPICT: 2253 case VIDIOCGPICT:
@@ -2291,7 +2296,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2291 bt848_hue(btv,pic->hue); 2296 bt848_hue(btv,pic->hue);
2292 bt848_sat(btv,pic->colour); 2297 bt848_sat(btv,pic->colour);
2293 up(&fh->cap.lock); 2298 up(&fh->cap.lock);
2294 return 0; 2299 return 0;
2295 } 2300 }
2296 2301
2297 case VIDIOCGWIN: 2302 case VIDIOCGWIN:
@@ -2352,8 +2357,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2352 unsigned long end; 2357 unsigned long end;
2353 2358
2354 if(!capable(CAP_SYS_ADMIN) && 2359 if(!capable(CAP_SYS_ADMIN) &&
2355 !capable(CAP_SYS_RAWIO)) 2360 !capable(CAP_SYS_RAWIO))
2356 return -EPERM; 2361 return -EPERM;
2357 end = (unsigned long)fbuf->base + 2362 end = (unsigned long)fbuf->base +
2358 fbuf->height * fbuf->bytesperline; 2363 fbuf->height * fbuf->bytesperline;
2359 down(&fh->cap.lock); 2364 down(&fh->cap.lock);
@@ -2427,7 +2432,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2427 } 2432 }
2428 2433
2429 /* switch over */ 2434 /* switch over */
2430 retval = bttv_switch_overlay(btv,fh,new); 2435 retval = bttv_switch_overlay(btv,fh,new);
2431 up(&fh->cap.lock); 2436 up(&fh->cap.lock);
2432 return retval; 2437 return retval;
2433 } 2438 }
@@ -2566,13 +2571,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2566 return 0; 2571 return 0;
2567 } 2572 }
2568 2573
2569 case BTTV_VERSION: 2574 case BTTV_VERSION:
2570 case VIDIOCGFREQ: 2575 case VIDIOCGFREQ:
2571 case VIDIOCSFREQ: 2576 case VIDIOCSFREQ:
2572 case VIDIOCGTUNER: 2577 case VIDIOCGTUNER:
2573 case VIDIOCSTUNER: 2578 case VIDIOCSTUNER:
2574 case VIDIOCGCHAN: 2579 case VIDIOCGCHAN:
2575 case VIDIOCSCHAN: 2580 case VIDIOCSCHAN:
2576 case VIDIOCGAUDIO: 2581 case VIDIOCGAUDIO:
2577 case VIDIOCSAUDIO: 2582 case VIDIOCSAUDIO:
2578 return bttv_common_ioctls(btv,cmd,arg); 2583 return bttv_common_ioctls(btv,cmd,arg);
@@ -2584,8 +2589,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2584 2589
2585 if (0 == v4l2) 2590 if (0 == v4l2)
2586 return -EINVAL; 2591 return -EINVAL;
2587 strcpy(cap->driver,"bttv"); 2592 strcpy(cap->driver,"bttv");
2588 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); 2593 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
2589 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); 2594 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
2590 cap->version = BTTV_VERSION_CODE; 2595 cap->version = BTTV_VERSION_CODE;
2591 cap->capabilities = 2596 cap->capabilities =
@@ -2856,6 +2861,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2856 case VIDIOC_S_TUNER: 2861 case VIDIOC_S_TUNER:
2857 case VIDIOC_G_FREQUENCY: 2862 case VIDIOC_G_FREQUENCY:
2858 case VIDIOC_S_FREQUENCY: 2863 case VIDIOC_S_FREQUENCY:
2864 case VIDIOC_LOG_STATUS:
2859 return bttv_common_ioctls(btv,cmd,arg); 2865 return bttv_common_ioctls(btv,cmd,arg);
2860 2866
2861 default: 2867 default:
@@ -3091,7 +3097,7 @@ static struct video_device bttv_video_template =
3091{ 3097{
3092 .name = "UNSET", 3098 .name = "UNSET",
3093 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| 3099 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
3094 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 3100 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3095 .hardware = VID_HARDWARE_BT848, 3101 .hardware = VID_HARDWARE_BT848,
3096 .fops = &bttv_fops, 3102 .fops = &bttv_fops,
3097 .minor = -1, 3103 .minor = -1,
@@ -3137,7 +3143,7 @@ static int radio_open(struct inode *inode, struct file *file)
3137 audio_mux(btv,AUDIO_RADIO); 3143 audio_mux(btv,AUDIO_RADIO);
3138 3144
3139 up(&btv->lock); 3145 up(&btv->lock);
3140 return 0; 3146 return 0;
3141} 3147}
3142 3148
3143static int radio_release(struct inode *inode, struct file *file) 3149static int radio_release(struct inode *inode, struct file *file)
@@ -3160,34 +3166,34 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
3160 switch (cmd) { 3166 switch (cmd) {
3161 case VIDIOCGCAP: 3167 case VIDIOCGCAP:
3162 { 3168 {
3163 struct video_capability *cap = arg; 3169 struct video_capability *cap = arg;
3164 3170
3165 memset(cap,0,sizeof(*cap)); 3171 memset(cap,0,sizeof(*cap));
3166 strcpy(cap->name,btv->radio_dev->name); 3172 strcpy(cap->name,btv->radio_dev->name);
3167 cap->type = VID_TYPE_TUNER; 3173 cap->type = VID_TYPE_TUNER;
3168 cap->channels = 1; 3174 cap->channels = 1;
3169 cap->audios = 1; 3175 cap->audios = 1;
3170 return 0; 3176 return 0;
3171 } 3177 }
3172 3178
3173 case VIDIOCGTUNER: 3179 case VIDIOCGTUNER:
3174 { 3180 {
3175 struct video_tuner *v = arg; 3181 struct video_tuner *v = arg;
3176 3182
3177 if(v->tuner) 3183 if(v->tuner)
3178 return -EINVAL; 3184 return -EINVAL;
3179 memset(v,0,sizeof(*v)); 3185 memset(v,0,sizeof(*v));
3180 strcpy(v->name, "Radio"); 3186 strcpy(v->name, "Radio");
3181 bttv_call_i2c_clients(btv,cmd,v); 3187 bttv_call_i2c_clients(btv,cmd,v);
3182 return 0; 3188 return 0;
3183 } 3189 }
3184 case VIDIOCSTUNER: 3190 case VIDIOCSTUNER:
3185 /* nothing to do */ 3191 /* nothing to do */
3186 return 0; 3192 return 0;
3187 3193
3188 case BTTV_VERSION: 3194 case BTTV_VERSION:
3189 case VIDIOCGFREQ: 3195 case VIDIOCGFREQ:
3190 case VIDIOCSFREQ: 3196 case VIDIOCSFREQ:
3191 case VIDIOCGAUDIO: 3197 case VIDIOCGAUDIO:
3192 case VIDIOCSAUDIO: 3198 case VIDIOCSAUDIO:
3193 return bttv_common_ioctls(btv,cmd,arg); 3199 return bttv_common_ioctls(btv,cmd,arg);
@@ -3693,7 +3699,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3693 } 3699 }
3694 3700
3695 if (astat&BT848_INT_VSYNC) 3701 if (astat&BT848_INT_VSYNC)
3696 btv->field_count++; 3702 btv->field_count++;
3697 3703
3698 if (astat & BT848_INT_GPINT) { 3704 if (astat & BT848_INT_GPINT) {
3699 wake_up(&btv->gpioq); 3705 wake_up(&btv->gpioq);
@@ -3705,13 +3711,13 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3705 wake_up(&btv->i2c_queue); 3711 wake_up(&btv->i2c_queue);
3706 } 3712 }
3707 3713
3708 if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) 3714 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
3709 bttv_irq_switch_vbi(btv); 3715 bttv_irq_switch_vbi(btv);
3710 3716
3711 if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) 3717 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
3712 bttv_irq_wakeup_top(btv); 3718 bttv_irq_wakeup_top(btv);
3713 3719
3714 if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) 3720 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
3715 bttv_irq_switch_video(btv); 3721 bttv_irq_switch_video(btv);
3716 3722
3717 if ((astat & BT848_INT_HLOCK) && btv->opt_automute) 3723 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
@@ -3736,10 +3742,22 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3736 3742
3737 count++; 3743 count++;
3738 if (count > 4) { 3744 if (count > 4) {
3739 btwrite(0, BT848_INT_MASK); 3745
3740 printk(KERN_ERR 3746 if (count > 8 || !(astat & BT848_INT_GPINT)) {
3741 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr); 3747 btwrite(0, BT848_INT_MASK);
3748
3749 printk(KERN_ERR
3750 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3751 } else {
3752 printk(KERN_ERR
3753 "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr);
3754
3755 btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
3756 BT848_INT_MASK);
3757 };
3758
3742 bttv_print_irqbits(stat,astat); 3759 bttv_print_irqbits(stat,astat);
3760
3743 printk("]\n"); 3761 printk("]\n");
3744 } 3762 }
3745 } 3763 }
@@ -3808,7 +3826,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
3808 3826
3809 /* video */ 3827 /* video */
3810 btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); 3828 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
3811 if (NULL == btv->video_dev) 3829 if (NULL == btv->video_dev)
3812 goto err; 3830 goto err;
3813 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) 3831 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3814 goto err; 3832 goto err;
@@ -3818,18 +3836,18 @@ static int __devinit bttv_register_video(struct bttv *btv)
3818 3836
3819 /* vbi */ 3837 /* vbi */
3820 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); 3838 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
3821 if (NULL == btv->vbi_dev) 3839 if (NULL == btv->vbi_dev)
3822 goto err; 3840 goto err;
3823 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 3841 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
3824 goto err; 3842 goto err;
3825 printk(KERN_INFO "bttv%d: registered device vbi%d\n", 3843 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3826 btv->c.nr,btv->vbi_dev->minor & 0x1f); 3844 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3827 3845
3828 if (!btv->has_radio) 3846 if (!btv->has_radio)
3829 return 0; 3847 return 0;
3830 /* radio */ 3848 /* radio */
3831 btv->radio_dev = vdev_init(btv, &radio_template, "radio"); 3849 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
3832 if (NULL == btv->radio_dev) 3850 if (NULL == btv->radio_dev)
3833 goto err; 3851 goto err;
3834 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) 3852 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3835 goto err; 3853 goto err;
@@ -3850,11 +3868,11 @@ static int __devinit bttv_register_video(struct bttv *btv)
3850static void pci_set_command(struct pci_dev *dev) 3868static void pci_set_command(struct pci_dev *dev)
3851{ 3869{
3852#if defined(__powerpc__) 3870#if defined(__powerpc__)
3853 unsigned int cmd; 3871 unsigned int cmd;
3854 3872
3855 pci_read_config_dword(dev, PCI_COMMAND, &cmd); 3873 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3856 cmd = (cmd | PCI_COMMAND_MEMORY ); 3874 cmd = (cmd | PCI_COMMAND_MEMORY );
3857 pci_write_config_dword(dev, PCI_COMMAND, cmd); 3875 pci_write_config_dword(dev, PCI_COMMAND, cmd);
3858#endif 3876#endif
3859} 3877}
3860 3878
@@ -3868,63 +3886,62 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3868 if (bttv_num == BTTV_MAX) 3886 if (bttv_num == BTTV_MAX)
3869 return -ENOMEM; 3887 return -ENOMEM;
3870 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); 3888 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
3871 btv=&bttvs[bttv_num]; 3889 btv=&bttvs[bttv_num];
3872 memset(btv,0,sizeof(*btv)); 3890 memset(btv,0,sizeof(*btv));
3873 btv->c.nr = bttv_num; 3891 btv->c.nr = bttv_num;
3874 sprintf(btv->c.name,"bttv%d",btv->c.nr); 3892 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3875 3893
3876 /* initialize structs / fill in defaults */ 3894 /* initialize structs / fill in defaults */
3877 init_MUTEX(&btv->lock); 3895 init_MUTEX(&btv->lock);
3878 init_MUTEX(&btv->reslock); 3896 init_MUTEX(&btv->reslock);
3879 spin_lock_init(&btv->s_lock); 3897 spin_lock_init(&btv->s_lock);
3880 spin_lock_init(&btv->gpio_lock); 3898 spin_lock_init(&btv->gpio_lock);
3881 init_waitqueue_head(&btv->gpioq); 3899 init_waitqueue_head(&btv->gpioq);
3882 init_waitqueue_head(&btv->i2c_queue); 3900 init_waitqueue_head(&btv->i2c_queue);
3883 INIT_LIST_HEAD(&btv->c.subs); 3901 INIT_LIST_HEAD(&btv->c.subs);
3884 INIT_LIST_HEAD(&btv->capture); 3902 INIT_LIST_HEAD(&btv->capture);
3885 INIT_LIST_HEAD(&btv->vcapture); 3903 INIT_LIST_HEAD(&btv->vcapture);
3886 v4l2_prio_init(&btv->prio); 3904 v4l2_prio_init(&btv->prio);
3887 3905
3888 init_timer(&btv->timeout); 3906 init_timer(&btv->timeout);
3889 btv->timeout.function = bttv_irq_timeout; 3907 btv->timeout.function = bttv_irq_timeout;
3890 btv->timeout.data = (unsigned long)btv; 3908 btv->timeout.data = (unsigned long)btv;
3891 3909
3892 btv->i2c_rc = -1; 3910 btv->i2c_rc = -1;
3893 btv->tuner_type = UNSET; 3911 btv->tuner_type = UNSET;
3894 btv->pinnacle_id = UNSET; 3912 btv->pinnacle_id = UNSET;
3895 btv->new_input = UNSET; 3913 btv->new_input = UNSET;
3896 btv->gpioirq = 1;
3897 btv->has_radio=radio[btv->c.nr]; 3914 btv->has_radio=radio[btv->c.nr];
3898 3915
3899 /* pci stuff (init, get irq/mmio, ... */ 3916 /* pci stuff (init, get irq/mmio, ... */
3900 btv->c.pci = dev; 3917 btv->c.pci = dev;
3901 btv->id = dev->device; 3918 btv->id = dev->device;
3902 if (pci_enable_device(dev)) { 3919 if (pci_enable_device(dev)) {
3903 printk(KERN_WARNING "bttv%d: Can't enable device.\n", 3920 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
3904 btv->c.nr); 3921 btv->c.nr);
3905 return -EIO; 3922 return -EIO;
3906 } 3923 }
3907 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { 3924 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
3908 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", 3925 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
3909 btv->c.nr); 3926 btv->c.nr);
3910 return -EIO; 3927 return -EIO;
3911 } 3928 }
3912 if (!request_mem_region(pci_resource_start(dev,0), 3929 if (!request_mem_region(pci_resource_start(dev,0),
3913 pci_resource_len(dev,0), 3930 pci_resource_len(dev,0),
3914 btv->c.name)) { 3931 btv->c.name)) {
3915 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", 3932 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
3916 btv->c.nr, pci_resource_start(dev,0)); 3933 btv->c.nr, pci_resource_start(dev,0));
3917 return -EBUSY; 3934 return -EBUSY;
3918 } 3935 }
3919 pci_set_master(dev); 3936 pci_set_master(dev);
3920 pci_set_command(dev); 3937 pci_set_command(dev);
3921 pci_set_drvdata(dev,btv); 3938 pci_set_drvdata(dev,btv);
3922 3939
3923 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); 3940 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
3924 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 3941 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
3925 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", 3942 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
3926 bttv_num,btv->id, btv->revision, pci_name(dev)); 3943 bttv_num,btv->id, btv->revision, pci_name(dev));
3927 printk("irq: %d, latency: %d, mmio: 0x%lx\n", 3944 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
3928 btv->c.pci->irq, lat, pci_resource_start(dev,0)); 3945 btv->c.pci->irq, lat, pci_resource_start(dev,0));
3929 schedule(); 3946 schedule();
3930 3947
@@ -3935,23 +3952,23 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3935 goto fail1; 3952 goto fail1;
3936 } 3953 }
3937 3954
3938 /* identify card */ 3955 /* identify card */
3939 bttv_idcard(btv); 3956 bttv_idcard(btv);
3940 3957
3941 /* disable irqs, register irq handler */ 3958 /* disable irqs, register irq handler */
3942 btwrite(0, BT848_INT_MASK); 3959 btwrite(0, BT848_INT_MASK);
3943 result = request_irq(btv->c.pci->irq, bttv_irq, 3960 result = request_irq(btv->c.pci->irq, bttv_irq,
3944 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv); 3961 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
3945 if (result < 0) { 3962 if (result < 0) {
3946 printk(KERN_ERR "bttv%d: can't get IRQ %d\n", 3963 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
3947 bttv_num,btv->c.pci->irq); 3964 bttv_num,btv->c.pci->irq);
3948 goto fail1; 3965 goto fail1;
3949 } 3966 }
3950 3967
3951 if (0 != bttv_handle_chipset(btv)) { 3968 if (0 != bttv_handle_chipset(btv)) {
3952 result = -EIO; 3969 result = -EIO;
3953 goto fail2; 3970 goto fail2;
3954 } 3971 }
3955 3972
3956 /* init options from insmod args */ 3973 /* init options from insmod args */
3957 btv->opt_combfilter = combfilter; 3974 btv->opt_combfilter = combfilter;
@@ -3977,29 +3994,29 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3977 btv->input = 0; 3994 btv->input = 0;
3978 3995
3979 /* initialize hardware */ 3996 /* initialize hardware */
3980 if (bttv_gpio) 3997 if (bttv_gpio)
3981 bttv_gpio_tracking(btv,"pre-init"); 3998 bttv_gpio_tracking(btv,"pre-init");
3982 3999
3983 bttv_risc_init_main(btv); 4000 bttv_risc_init_main(btv);
3984 init_bt848(btv); 4001 init_bt848(btv);
3985 4002
3986 /* gpio */ 4003 /* gpio */
3987 btwrite(0x00, BT848_GPIO_REG_INP); 4004 btwrite(0x00, BT848_GPIO_REG_INP);
3988 btwrite(0x00, BT848_GPIO_OUT_EN); 4005 btwrite(0x00, BT848_GPIO_OUT_EN);
3989 if (bttv_verbose) 4006 if (bttv_verbose)
3990 bttv_gpio_tracking(btv,"init"); 4007 bttv_gpio_tracking(btv,"init");
3991 4008
3992 /* needs to be done before i2c is registered */ 4009 /* needs to be done before i2c is registered */
3993 bttv_init_card1(btv); 4010 bttv_init_card1(btv);
3994 4011
3995 /* register i2c + gpio */ 4012 /* register i2c + gpio */
3996 init_bttv_i2c(btv); 4013 init_bttv_i2c(btv);
3997 4014
3998 /* some card-specific stuff (needs working i2c) */ 4015 /* some card-specific stuff (needs working i2c) */
3999 bttv_init_card2(btv); 4016 bttv_init_card2(btv);
4000 init_irqreg(btv); 4017 init_irqreg(btv);
4001 4018
4002 /* register video4linux + input */ 4019 /* register video4linux + input */
4003 if (!bttv_tvcards[btv->c.type].no_video) { 4020 if (!bttv_tvcards[btv->c.type].no_video) {
4004 bttv_register_video(btv); 4021 bttv_register_video(btv);
4005 bt848_bright(btv,32768); 4022 bt848_bright(btv,32768);
@@ -4018,10 +4035,10 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4018 4035
4019 /* everything is fine */ 4036 /* everything is fine */
4020 bttv_num++; 4037 bttv_num++;
4021 return 0; 4038 return 0;
4022 4039
4023 fail2: 4040 fail2:
4024 free_irq(btv->c.pci->irq,btv); 4041 free_irq(btv->c.pci->irq,btv);
4025 4042
4026 fail1: 4043 fail1:
4027 if (btv->bt848_mmio) 4044 if (btv->bt848_mmio)
@@ -4034,12 +4051,12 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4034 4051
4035static void __devexit bttv_remove(struct pci_dev *pci_dev) 4052static void __devexit bttv_remove(struct pci_dev *pci_dev)
4036{ 4053{
4037 struct bttv *btv = pci_get_drvdata(pci_dev); 4054 struct bttv *btv = pci_get_drvdata(pci_dev);
4038 4055
4039 if (bttv_verbose) 4056 if (bttv_verbose)
4040 printk("bttv%d: unloading\n",btv->c.nr); 4057 printk("bttv%d: unloading\n",btv->c.nr);
4041 4058
4042 /* shutdown everything (DMA+IRQs) */ 4059 /* shutdown everything (DMA+IRQs) */
4043 btand(~15, BT848_GPIO_DMA_CTL); 4060 btand(~15, BT848_GPIO_DMA_CTL);
4044 btwrite(0, BT848_INT_MASK); 4061 btwrite(0, BT848_INT_MASK);
4045 btwrite(~0x0, BT848_INT_STAT); 4062 btwrite(~0x0, BT848_INT_STAT);
@@ -4052,7 +4069,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4052 wake_up(&btv->gpioq); 4069 wake_up(&btv->gpioq);
4053 bttv_sub_del_devices(&btv->c); 4070 bttv_sub_del_devices(&btv->c);
4054 4071
4055 /* unregister i2c_bus + input */ 4072 /* unregister i2c_bus + input */
4056 fini_bttv_i2c(btv); 4073 fini_bttv_i2c(btv);
4057 4074
4058 /* unregister video4linux */ 4075 /* unregister video4linux */
@@ -4062,18 +4079,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4062 btcx_riscmem_free(btv->c.pci,&btv->main); 4079 btcx_riscmem_free(btv->c.pci,&btv->main);
4063 4080
4064 /* free ressources */ 4081 /* free ressources */
4065 free_irq(btv->c.pci->irq,btv); 4082 free_irq(btv->c.pci->irq,btv);
4066 iounmap(btv->bt848_mmio); 4083 iounmap(btv->bt848_mmio);
4067 release_mem_region(pci_resource_start(btv->c.pci,0), 4084 release_mem_region(pci_resource_start(btv->c.pci,0),
4068 pci_resource_len(btv->c.pci,0)); 4085 pci_resource_len(btv->c.pci,0));
4069 4086
4070 pci_set_drvdata(pci_dev, NULL); 4087 pci_set_drvdata(pci_dev, NULL);
4071 return; 4088 return;
4072} 4089}
4073 4090
4074static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) 4091static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4075{ 4092{
4076 struct bttv *btv = pci_get_drvdata(pci_dev); 4093 struct bttv *btv = pci_get_drvdata(pci_dev);
4077 struct bttv_buffer_set idle; 4094 struct bttv_buffer_set idle;
4078 unsigned long flags; 4095 unsigned long flags;
4079 4096
@@ -4108,7 +4125,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4108 4125
4109static int bttv_resume(struct pci_dev *pci_dev) 4126static int bttv_resume(struct pci_dev *pci_dev)
4110{ 4127{
4111 struct bttv *btv = pci_get_drvdata(pci_dev); 4128 struct bttv *btv = pci_get_drvdata(pci_dev);
4112 unsigned long flags; 4129 unsigned long flags;
4113 int err; 4130 int err;
4114 4131
@@ -4153,24 +4170,24 @@ static int bttv_resume(struct pci_dev *pci_dev)
4153} 4170}
4154 4171
4155static struct pci_device_id bttv_pci_tbl[] = { 4172static struct pci_device_id bttv_pci_tbl[] = {
4156 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, 4173 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4157 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4158 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, 4175 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4159 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4160 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878, 4177 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4161 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4178 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4162 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879, 4179 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4163 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4180 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4164 {0,} 4181 {0,}
4165}; 4182};
4166 4183
4167MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); 4184MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4168 4185
4169static struct pci_driver bttv_pci_driver = { 4186static struct pci_driver bttv_pci_driver = {
4170 .name = "bttv", 4187 .name = "bttv",
4171 .id_table = bttv_pci_tbl, 4188 .id_table = bttv_pci_tbl,
4172 .probe = bttv_probe, 4189 .probe = bttv_probe,
4173 .remove = __devexit_p(bttv_remove), 4190 .remove = __devexit_p(bttv_remove),
4174 .suspend = bttv_suspend, 4191 .suspend = bttv_suspend,
4175 .resume = bttv_resume, 4192 .resume = bttv_resume,
4176}; 4193};
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 6b280c03e398..575ce8b8e714 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -7,7 +7,7 @@
7 7
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index e684df37eb0e..77619eb131f6 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -5,7 +5,7 @@
5 bttv - Bt848 frame grabber driver 5 bttv - Bt848 frame grabber driver
6 6
7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
8 & Marcus Metzler (mocm@thp.uni-koeln.de) 8 & Marcus Metzler (mocm@thp.uni-koeln.de)
9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
@@ -237,7 +237,7 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
237 err: 237 err:
238 if (i2c_debug) 238 if (i2c_debug)
239 printk(" ERR: %d\n",retval); 239 printk(" ERR: %d\n",retval);
240 return retval; 240 return retval;
241} 241}
242 242
243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
@@ -290,7 +290,13 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = {
290 290
291static int attach_inform(struct i2c_client *client) 291static int attach_inform(struct i2c_client *client)
292{ 292{
293 struct bttv *btv = i2c_get_adapdata(client->adapter); 293 struct bttv *btv = i2c_get_adapdata(client->adapter);
294 int addr=ADDR_UNSET;
295
296
297 if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
298 addr = bttv_tvcards[btv->c.type].tuner_addr;
299
294 300
295 if (bttv_debug) 301 if (bttv_debug)
296 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", 302 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
@@ -300,19 +306,20 @@ static int attach_inform(struct i2c_client *client)
300 return 0; 306 return 0;
301 307
302 if (btv->tuner_type != UNSET) { 308 if (btv->tuner_type != UNSET) {
303 struct tuner_setup tun_setup; 309 struct tuner_setup tun_setup;
310
311 if ((addr==ADDR_UNSET) ||
312 (addr==client->addr)) {
304 313
305 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 314 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
306 tun_setup.type = btv->tuner_type; 315 tun_setup.type = btv->tuner_type;
307 tun_setup.addr = ADDR_UNSET; 316 tun_setup.addr = addr;
317 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
318 }
308 319
309 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
310 } 320 }
311 321
312 if (btv->pinnacle_id != UNSET) 322 return 0;
313 client->driver->command(client,AUDC_CONFIG_PINNACLE,
314 &btv->pinnacle_id);
315 return 0;
316} 323}
317 324
318void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) 325void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
@@ -330,43 +337,43 @@ static struct i2c_client bttv_i2c_client_template = {
330/* read I2C */ 337/* read I2C */
331int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) 338int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
332{ 339{
333 unsigned char buffer = 0; 340 unsigned char buffer = 0;
334 341
335 if (0 != btv->i2c_rc) 342 if (0 != btv->i2c_rc)
336 return -1; 343 return -1;
337 if (bttv_verbose && NULL != probe_for) 344 if (bttv_verbose && NULL != probe_for)
338 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", 345 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
339 btv->c.nr,probe_for,addr); 346 btv->c.nr,probe_for,addr);
340 btv->i2c_client.addr = addr >> 1; 347 btv->i2c_client.addr = addr >> 1;
341 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { 348 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
342 if (NULL != probe_for) { 349 if (NULL != probe_for) {
343 if (bttv_verbose) 350 if (bttv_verbose)
344 printk("not found\n"); 351 printk("not found\n");
345 } else 352 } else
346 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", 353 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
347 btv->c.nr,addr); 354 btv->c.nr,addr);
348 return -1; 355 return -1;
349 } 356 }
350 if (bttv_verbose && NULL != probe_for) 357 if (bttv_verbose && NULL != probe_for)
351 printk("found\n"); 358 printk("found\n");
352 return buffer; 359 return buffer;
353} 360}
354 361
355/* write I2C */ 362/* write I2C */
356int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, 363int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
357 unsigned char b2, int both) 364 unsigned char b2, int both)
358{ 365{
359 unsigned char buffer[2]; 366 unsigned char buffer[2];
360 int bytes = both ? 2 : 1; 367 int bytes = both ? 2 : 1;
361 368
362 if (0 != btv->i2c_rc) 369 if (0 != btv->i2c_rc)
363 return -1; 370 return -1;
364 btv->i2c_client.addr = addr >> 1; 371 btv->i2c_client.addr = addr >> 1;
365 buffer[0] = b1; 372 buffer[0] = b1;
366 buffer[1] = b2; 373 buffer[1] = b2;
367 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) 374 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
368 return -1; 375 return -1;
369 return 0; 376 return 0;
370} 377}
371 378
372/* read EEPROM content */ 379/* read EEPROM content */
@@ -431,8 +438,8 @@ int __devinit init_bttv_i2c(struct bttv *btv)
431 "bt%d #%d [%s]", btv->id, btv->c.nr, 438 "bt%d #%d [%s]", btv->id, btv->c.nr,
432 btv->use_i2c_hw ? "hw" : "sw"); 439 btv->use_i2c_hw ? "hw" : "sw");
433 440
434 i2c_set_adapdata(&btv->c.i2c_adap, btv); 441 i2c_set_adapdata(&btv->c.i2c_adap, btv);
435 btv->i2c_client.adapter = &btv->c.i2c_adap; 442 btv->i2c_client.adapter = &btv->c.i2c_adap;
436 443
437#ifdef I2C_CLASS_TV_ANALOG 444#ifdef I2C_CLASS_TV_ANALOG
438 if (bttv_tvcards[btv->c.type].no_video) 445 if (bttv_tvcards[btv->c.type].no_video)
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index e8aada772b89..19b564ab0e92 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -1,13 +1,13 @@
1/* 1/*
2 2
3 bttv-if.c -- old gpio interface to other kernel modules 3 bttv-if.c -- old gpio interface to other kernel modules
4 don't use in new code, will go away in 2.7 4 don't use in new code, will go away in 2.7
5 have a look at bttv-gpio.c instead. 5 have a look at bttv-gpio.c instead.
6 6
7 bttv - Bt848 frame grabber driver 7 bttv - Bt848 frame grabber driver
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index a5ed99b89445..b40e9734bf08 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -74,27 +74,27 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
74 } 74 }
75 if (bpl <= sg_dma_len(sg)-offset) { 75 if (bpl <= sg_dma_len(sg)-offset) {
76 /* fits into current chunk */ 76 /* fits into current chunk */
77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
78 BT848_RISC_EOL|bpl); 78 BT848_RISC_EOL|bpl);
79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
80 offset+=bpl; 80 offset+=bpl;
81 } else { 81 } else {
82 /* scanline needs to be splitted */ 82 /* scanline needs to be splitted */
83 todo = bpl; 83 todo = bpl;
84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
85 (sg_dma_len(sg)-offset)); 85 (sg_dma_len(sg)-offset));
86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
87 todo -= (sg_dma_len(sg)-offset); 87 todo -= (sg_dma_len(sg)-offset);
88 offset = 0; 88 offset = 0;
89 sg++; 89 sg++;
90 while (todo > sg_dma_len(sg)) { 90 while (todo > sg_dma_len(sg)) {
91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE| 91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
92 sg_dma_len(sg)); 92 sg_dma_len(sg));
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 93 *(rp++)=cpu_to_le32(sg_dma_address(sg));
94 todo -= sg_dma_len(sg); 94 todo -= sg_dma_len(sg);
95 sg++; 95 sg++;
96 } 96 }
97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| 97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
98 todo); 98 todo);
99 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 99 *(rp++)=cpu_to_le32(sg_dma_address(sg));
100 offset += todo; 100 offset += todo;
@@ -201,8 +201,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
201 ri |= BT848_RISC_EOL; 201 ri |= BT848_RISC_EOL;
202 202
203 /* write risc instruction */ 203 /* write risc instruction */
204 *(rp++)=cpu_to_le32(ri | ylen); 204 *(rp++)=cpu_to_le32(ri | ylen);
205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) | 205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
206 (ylen >> hshift)); 206 (ylen >> hshift));
207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset); 207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
208 yoffset += ylen; 208 yoffset += ylen;
@@ -319,7 +319,7 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
319 int width, int height, int interleaved, int norm) 319 int width, int height, int interleaved, int norm)
320{ 320{
321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; 321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
322 u32 xsf, sr; 322 u32 xsf, sr;
323 int vdelay; 323 int vdelay;
324 324
325 int swidth = tvnorm->swidth; 325 int swidth = tvnorm->swidth;
@@ -334,52 +334,52 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
334 334
335 vdelay = tvnorm->vdelay; 335 vdelay = tvnorm->vdelay;
336 336
337 xsf = (width*scaledtwidth)/swidth; 337 xsf = (width*scaledtwidth)/swidth;
338 geo->hscale = ((totalwidth*4096UL)/xsf-4096); 338 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
339 geo->hdelay = tvnorm->hdelayx1; 339 geo->hdelay = tvnorm->hdelayx1;
340 geo->hdelay = (geo->hdelay*width)/swidth; 340 geo->hdelay = (geo->hdelay*width)/swidth;
341 geo->hdelay &= 0x3fe; 341 geo->hdelay &= 0x3fe;
342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; 342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
343 geo->vscale = (0x10000UL-sr) & 0x1fff; 343 geo->vscale = (0x10000UL-sr) & 0x1fff;
344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | 344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); 345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; 346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
347 geo->vdelay = vdelay; 347 geo->vdelay = vdelay;
348 geo->width = width; 348 geo->width = width;
349 geo->sheight = tvnorm->sheight; 349 geo->sheight = tvnorm->sheight;
350 geo->vtotal = tvnorm->vtotal; 350 geo->vtotal = tvnorm->vtotal;
351 351
352 if (btv->opt_combfilter) { 352 if (btv->opt_combfilter) {
353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
354 geo->comb = (width < 769) ? 1 : 0; 354 geo->comb = (width < 769) ? 1 : 0;
355 } else { 355 } else {
356 geo->vtc = 0; 356 geo->vtc = 0;
357 geo->comb = 0; 357 geo->comb = 0;
358 } 358 }
359} 359}
360 360
361static void 361static void
362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) 362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
363{ 363{
364 int off = odd ? 0x80 : 0x00; 364 int off = odd ? 0x80 : 0x00;
365 365
366 if (geo->comb) 366 if (geo->comb)
367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
368 else 368 else
369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
370 370
371 btwrite(geo->vtc, BT848_E_VTC+off); 371 btwrite(geo->vtc, BT848_E_VTC+off);
372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); 372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); 373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); 374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); 375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); 376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); 377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); 378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); 379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
380 btwrite(geo->crop, BT848_E_CROP+off); 380 btwrite(geo->crop, BT848_E_CROP+off);
381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); 381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); 382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
383} 383}
384 384
385/* ---------------------------------------------------------- */ 385/* ---------------------------------------------------------- */
@@ -420,7 +420,7 @@ bttv_set_dma(struct bttv *btv, int override)
420 } else { 420 } else {
421 del_timer(&btv->timeout); 421 del_timer(&btv->timeout);
422 } 422 }
423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); 423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
424 424
425 btaor(capctl, ~0x0f, BT848_CAP_CTL); 425 btaor(capctl, ~0x0f, BT848_CAP_CTL);
426 if (capctl) { 426 if (capctl) {
@@ -432,7 +432,7 @@ bttv_set_dma(struct bttv *btv, int override)
432 } else { 432 } else {
433 if (!btv->dma_on) 433 if (!btv->dma_on)
434 return; 434 return;
435 btand(~3, BT848_GPIO_DMA_CTL); 435 btand(~3, BT848_GPIO_DMA_CTL);
436 btv->dma_on = 0; 436 btv->dma_on = 0;
437 } 437 }
438 return; 438 return;
@@ -460,19 +460,19 @@ bttv_risc_init_main(struct bttv *btv)
460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); 460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); 461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
462 462
463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
464 BT848_FIFO_STATUS_VRO); 464 BT848_FIFO_STATUS_VRO);
465 btv->main.cpu[9] = cpu_to_le32(0); 465 btv->main.cpu[9] = cpu_to_le32(0);
466 466
467 /* bottom field */ 467 /* bottom field */
468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); 468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); 469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); 470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); 471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
472 472
473 /* jump back to top field */ 473 /* jump back to top field */
474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); 474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); 475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
476 476
477 return 0; 477 return 0;
478} 478}
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index d254e90e3bb9..124ea41dada4 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -20,123 +20,148 @@
20/* ---------------------------------------------------------- */ 20/* ---------------------------------------------------------- */
21/* exported by bttv-cards.c */ 21/* exported by bttv-cards.c */
22 22
23#define BTTV_UNKNOWN 0x00 23#define BTTV_BOARD_UNKNOWN 0x00
24#define BTTV_MIRO 0x01 24#define BTTV_BOARD_MIRO 0x01
25#define BTTV_HAUPPAUGE 0x02 25#define BTTV_BOARD_HAUPPAUGE 0x02
26#define BTTV_STB 0x03 26#define BTTV_BOARD_STB 0x03
27#define BTTV_INTEL 0x04 27#define BTTV_BOARD_INTEL 0x04
28#define BTTV_DIAMOND 0x05 28#define BTTV_BOARD_DIAMOND 0x05
29#define BTTV_AVERMEDIA 0x06 29#define BTTV_BOARD_AVERMEDIA 0x06
30#define BTTV_MATRIX_VISION 0x07 30#define BTTV_BOARD_MATRIX_VISION 0x07
31#define BTTV_FLYVIDEO 0x08 31#define BTTV_BOARD_FLYVIDEO 0x08
32#define BTTV_TURBOTV 0x09 32#define BTTV_BOARD_TURBOTV 0x09
33#define BTTV_HAUPPAUGE878 0x0a 33#define BTTV_BOARD_HAUPPAUGE878 0x0a
34#define BTTV_MIROPRO 0x0b 34#define BTTV_BOARD_MIROPRO 0x0b
35#define BTTV_ADSTECH_TV 0x0c 35#define BTTV_BOARD_ADSTECH_TV 0x0c
36#define BTTV_AVERMEDIA98 0x0d 36#define BTTV_BOARD_AVERMEDIA98 0x0d
37#define BTTV_VHX 0x0e 37#define BTTV_BOARD_VHX 0x0e
38#define BTTV_ZOLTRIX 0x0f 38#define BTTV_BOARD_ZOLTRIX 0x0f
39#define BTTV_PIXVIEWPLAYTV 0x10 39#define BTTV_BOARD_PIXVIEWPLAYTV 0x10
40#define BTTV_WINVIEW_601 0x11 40#define BTTV_BOARD_WINVIEW_601 0x11
41#define BTTV_AVEC_INTERCAP 0x12 41#define BTTV_BOARD_AVEC_INTERCAP 0x12
42#define BTTV_LIFE_FLYKIT 0x13 42#define BTTV_BOARD_LIFE_FLYKIT 0x13
43#define BTTV_CEI_RAFFLES 0x14 43#define BTTV_BOARD_CEI_RAFFLES 0x14
44#define BTTV_CONFERENCETV 0x15 44#define BTTV_BOARD_CONFERENCETV 0x15
45#define BTTV_PHOEBE_TVMAS 0x16 45#define BTTV_BOARD_PHOEBE_TVMAS 0x16
46#define BTTV_MODTEC_205 0x17 46#define BTTV_BOARD_MODTEC_205 0x17
47#define BTTV_MAGICTVIEW061 0x18 47#define BTTV_BOARD_MAGICTVIEW061 0x18
48#define BTTV_VOBIS_BOOSTAR 0x19 48#define BTTV_BOARD_VOBIS_BOOSTAR 0x19
49#define BTTV_HAUPPAUG_WCAM 0x1a 49#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a
50#define BTTV_MAXI 0x1b 50#define BTTV_BOARD_MAXI 0x1b
51#define BTTV_TERRATV 0x1c 51#define BTTV_BOARD_TERRATV 0x1c
52#define BTTV_PXC200 0x1d 52#define BTTV_BOARD_PXC200 0x1d
53#define BTTV_FLYVIDEO_98 0x1e 53#define BTTV_BOARD_FLYVIDEO_98 0x1e
54#define BTTV_IPROTV 0x1f 54#define BTTV_BOARD_IPROTV 0x1f
55#define BTTV_INTEL_C_S_PCI 0x20 55#define BTTV_BOARD_INTEL_C_S_PCI 0x20
56#define BTTV_TERRATVALUE 0x21 56#define BTTV_BOARD_TERRATVALUE 0x21
57#define BTTV_WINFAST2000 0x22 57#define BTTV_BOARD_WINFAST2000 0x22
58#define BTTV_CHRONOS_VS2 0x23 58#define BTTV_BOARD_CHRONOS_VS2 0x23
59#define BTTV_TYPHOON_TVIEW 0x24 59#define BTTV_BOARD_TYPHOON_TVIEW 0x24
60#define BTTV_PXELVWPLTVPRO 0x25 60#define BTTV_BOARD_PXELVWPLTVPRO 0x25
61#define BTTV_MAGICTVIEW063 0x26 61#define BTTV_BOARD_MAGICTVIEW063 0x26
62#define BTTV_PINNACLE 0x27 62#define BTTV_BOARD_PINNACLE 0x27
63#define BTTV_STB2 0x28 63#define BTTV_BOARD_STB2 0x28
64#define BTTV_AVPHONE98 0x29 64#define BTTV_BOARD_AVPHONE98 0x29
65#define BTTV_PV951 0x2a 65#define BTTV_BOARD_PV951 0x2a
66#define BTTV_ONAIR_TV 0x2b 66#define BTTV_BOARD_ONAIR_TV 0x2b
67#define BTTV_SIGMA_TVII_FM 0x2c 67#define BTTV_BOARD_SIGMA_TVII_FM 0x2c
68#define BTTV_MATRIX_VISION2 0x2d 68#define BTTV_BOARD_MATRIX_VISION2 0x2d
69#define BTTV_ZOLTRIX_GENIE 0x2e 69#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e
70#define BTTV_TERRATVRADIO 0x2f 70#define BTTV_BOARD_TERRATVRADIO 0x2f
71#define BTTV_DYNALINK 0x30 71#define BTTV_BOARD_DYNALINK 0x30
72#define BTTV_GVBCTV3PCI 0x31 72#define BTTV_BOARD_GVBCTV3PCI 0x31
73#define BTTV_PXELVWPLTVPAK 0x32 73#define BTTV_BOARD_PXELVWPLTVPAK 0x32
74#define BTTV_EAGLE 0x33 74#define BTTV_BOARD_EAGLE 0x33
75#define BTTV_PINNACLEPRO 0x34 75#define BTTV_BOARD_PINNACLEPRO 0x34
76#define BTTV_TVIEW_RDS_FM 0x35 76#define BTTV_BOARD_TVIEW_RDS_FM 0x35
77#define BTTV_LIFETEC_9415 0x36 77#define BTTV_BOARD_LIFETEC_9415 0x36
78#define BTTV_BESTBUY_EASYTV 0x37 78#define BTTV_BOARD_BESTBUY_EASYTV 0x37
79#define BTTV_FLYVIDEO_98FM 0x38 79#define BTTV_BOARD_FLYVIDEO_98FM 0x38
80#define BTTV_GMV1 0x3d 80#define BTTV_BOARD_GRANDTEC 0x39
81#define BTTV_BESTBUY_EASYTV2 0x3e 81#define BTTV_BOARD_ASKEY_CPH060 0x3a
82#define BTTV_ATI_TVWONDER 0x3f 82#define BTTV_BOARD_ASKEY_CPH03X 0x3b
83#define BTTV_ATI_TVWONDERVE 0x40 83#define BTTV_BOARD_MM100PCTV 0x3c
84#define BTTV_FLYVIDEO2000 0x41 84#define BTTV_BOARD_GMV1 0x3d
85#define BTTV_TERRATVALUER 0x42 85#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e
86#define BTTV_GVBCTV4PCI 0x43 86#define BTTV_BOARD_ATI_TVWONDER 0x3f
87#define BTTV_VOODOOTV_FM 0x44 87#define BTTV_BOARD_ATI_TVWONDERVE 0x40
88#define BTTV_AIMMS 0x45 88#define BTTV_BOARD_FLYVIDEO2000 0x41
89#define BTTV_PV_BT878P_PLUS 0x46 89#define BTTV_BOARD_TERRATVALUER 0x42
90#define BTTV_FLYVIDEO98EZ 0x47 90#define BTTV_BOARD_GVBCTV4PCI 0x43
91#define BTTV_PV_BT878P_9B 0x48 91#define BTTV_BOARD_VOODOOTV_FM 0x44
92#define BTTV_SENSORAY311 0x49 92#define BTTV_BOARD_AIMMS 0x45
93#define BTTV_RV605 0x4a 93#define BTTV_BOARD_PV_BT878P_PLUS 0x46
94#define BTTV_WINDVR 0x4c 94#define BTTV_BOARD_FLYVIDEO98EZ 0x47
95#define BTTV_GRANDTEC 0x4d 95#define BTTV_BOARD_PV_BT878P_9B 0x48
96#define BTTV_KWORLD 0x4e 96#define BTTV_BOARD_SENSORAY311 0x49
97#define BTTV_HAUPPAUGEPVR 0x50 97#define BTTV_BOARD_RV605 0x4a
98#define BTTV_GVBCTV5PCI 0x51 98#define BTTV_BOARD_POWERCLR_MTV878 0x4b
99#define BTTV_OSPREY1x0 0x52 99#define BTTV_BOARD_WINDVR 0x4c
100#define BTTV_OSPREY1x0_848 0x53 100#define BTTV_BOARD_GRANDTEC_MULTI 0x4d
101#define BTTV_OSPREY101_848 0x54 101#define BTTV_BOARD_KWORLD 0x4e
102#define BTTV_OSPREY1x1 0x55 102#define BTTV_BOARD_DSP_TCVIDEO 0x4f
103#define BTTV_OSPREY1x1_SVID 0x56 103#define BTTV_BOARD_HAUPPAUGEPVR 0x50
104#define BTTV_OSPREY2xx 0x57 104#define BTTV_BOARD_GVBCTV5PCI 0x51
105#define BTTV_OSPREY2x0_SVID 0x58 105#define BTTV_BOARD_OSPREY1x0 0x52
106#define BTTV_OSPREY2x0 0x59 106#define BTTV_BOARD_OSPREY1x0_848 0x53
107#define BTTV_OSPREY500 0x5a 107#define BTTV_BOARD_OSPREY101_848 0x54
108#define BTTV_OSPREY540 0x5b 108#define BTTV_BOARD_OSPREY1x1 0x55
109#define BTTV_OSPREY2000 0x5c 109#define BTTV_BOARD_OSPREY1x1_SVID 0x56
110#define BTTV_IDS_EAGLE 0x5d 110#define BTTV_BOARD_OSPREY2xx 0x57
111#define BTTV_PINNACLESAT 0x5e 111#define BTTV_BOARD_OSPREY2x0_SVID 0x58
112#define BTTV_FORMAC_PROTV 0x5f 112#define BTTV_BOARD_OSPREY2x0 0x59
113#define BTTV_EURESYS_PICOLO 0x61 113#define BTTV_BOARD_OSPREY500 0x5a
114#define BTTV_PV150 0x62 114#define BTTV_BOARD_OSPREY540 0x5b
115#define BTTV_AD_TVK503 0x63 115#define BTTV_BOARD_OSPREY2000 0x5c
116#define BTTV_IVC200 0x66 116#define BTTV_BOARD_IDS_EAGLE 0x5d
117#define BTTV_XGUARD 0x67 117#define BTTV_BOARD_PINNACLESAT 0x5e
118#define BTTV_NEBULA_DIGITV 0x68 118#define BTTV_BOARD_FORMAC_PROTV 0x5f
119#define BTTV_PV143 0x69 119#define BTTV_BOARD_MACHTV 0x60
120#define BTTV_IVC100 0x6e 120#define BTTV_BOARD_EURESYS_PICOLO 0x61
121#define BTTV_IVC120 0x6f 121#define BTTV_BOARD_PV150 0x62
122#define BTTV_PC_HDTV 0x70 122#define BTTV_BOARD_AD_TVK503 0x63
123#define BTTV_TWINHAN_DST 0x71 123#define BTTV_BOARD_HERCULES_SM_TV 0x64
124#define BTTV_WINFASTVC100 0x72 124#define BTTV_BOARD_PACETV 0x65
125#define BTTV_SIMUS_GVC1100 0x74 125#define BTTV_BOARD_IVC200 0x66
126#define BTTV_NGSTV_PLUS 0x75 126#define BTTV_BOARD_XGUARD 0x67
127#define BTTV_LMLBT4 0x76 127#define BTTV_BOARD_NEBULA_DIGITV 0x68
128#define BTTV_PICOLO_TETRA_CHIP 0x79 128#define BTTV_BOARD_PV143 0x69
129#define BTTV_AVDVBT_771 0x7b 129#define BTTV_BOARD_VD009X1_MINIDIN 0x6a
130#define BTTV_AVDVBT_761 0x7c 130#define BTTV_BOARD_VD009X1_COMBI 0x6b
131#define BTTV_MATRIX_VISIONSQ 0x7d 131#define BTTV_BOARD_VD009_MINIDIN 0x6c
132#define BTTV_MATRIX_VISIONSLC 0x7e 132#define BTTV_BOARD_VD009_COMBI 0x6d
133#define BTTV_APAC_VIEWCOMP 0x7f 133#define BTTV_BOARD_IVC100 0x6e
134#define BTTV_DVICO_DVBT_LITE 0x80 134#define BTTV_BOARD_IVC120 0x6f
135#define BTTV_TIBET_CS16 0x83 135#define BTTV_BOARD_PC_HDTV 0x70
136#define BTTV_KODICOM_4400R 0x84 136#define BTTV_BOARD_TWINHAN_DST 0x71
137#define BTTV_ADLINK_RTV24 0x86 137#define BTTV_BOARD_WINFASTVC100 0x72
138#define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87 138#define BTTV_BOARD_TEV560 0x73
139#define BTTV_ACORP_Y878F 0x88 139#define BTTV_BOARD_SIMUS_GVC1100 0x74
140#define BTTV_BOARD_NGSTV_PLUS 0x75
141#define BTTV_BOARD_LMLBT4 0x76
142#define BTTV_BOARD_TEKRAM_M205 0x77
143#define BTTV_BOARD_CONTVFMI 0x78
144#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79
145#define BTTV_BOARD_SPIRIT_TV 0x7a
146#define BTTV_BOARD_AVDVBT_771 0x7b
147#define BTTV_BOARD_AVDVBT_761 0x7c
148#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d
149#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e
150#define BTTV_BOARD_APAC_VIEWCOMP 0x7f
151#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
152#define BTTV_BOARD_VGEAR_MYVCD 0x81
153#define BTTV_BOARD_SUPER_TV 0x82
154#define BTTV_BOARD_TIBET_CS16 0x83
155#define BTTV_BOARD_KODICOM_4400R 0x84
156#define BTTV_BOARD_KODICOM_4400R_SL 0x85
157#define BTTV_BOARD_ADLINK_RTV24 0x86
158#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
159#define BTTV_BOARD_ACORP_Y878F 0x88
160#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89
161#define BTTV_BOARD_PV_BT878P_2E 0x8a
162#define BTTV_BOARD_PV_M4900 0x8b
163#define BTTV_BOARD_OSPREY440 0x8c
164#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
140 165
141/* i2c address list */ 166/* i2c address list */
142#define I2C_TSA5522 0xc2 167#define I2C_TSA5522 0xc2
@@ -177,7 +202,7 @@ struct bttv_core {
177 struct list_head subs; /* struct bttv_sub_device */ 202 struct list_head subs; /* struct bttv_sub_device */
178 203
179 /* device config */ 204 /* device config */
180 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ 205 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
181 unsigned int type; /* card type (pointer into tvcards[]) */ 206 unsigned int type; /* card type (pointer into tvcards[]) */
182 char name[8]; /* dev name */ 207 char name[8]; /* dev name */
183}; 208};
@@ -186,16 +211,16 @@ struct bttv;
186 211
187struct tvcard 212struct tvcard
188{ 213{
189 char *name; 214 char *name;
190 unsigned int video_inputs; 215 unsigned int video_inputs;
191 unsigned int audio_inputs; 216 unsigned int audio_inputs;
192 unsigned int tuner; 217 unsigned int tuner;
193 unsigned int svhs; 218 unsigned int svhs;
194 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO 219 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
195 u32 gpiomask; 220 u32 gpiomask;
196 u32 muxsel[16]; 221 u32 muxsel[16];
197 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ 222 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
198 u32 gpiomask2; /* GPIO MUX mask */ 223 u32 gpiomask2; /* GPIO MUX mask */
199 224
200 /* i2c audio flags */ 225 /* i2c audio flags */
201 unsigned int no_msp34xx:1; 226 unsigned int no_msp34xx:1;
@@ -218,6 +243,7 @@ struct tvcard
218 243
219 unsigned int tuner_type; 244 unsigned int tuner_type;
220 unsigned int tuner_addr; 245 unsigned int tuner_addr;
246 unsigned int radio_addr;
221 247
222 unsigned int has_radio; 248 unsigned int has_radio;
223 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); 249 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
@@ -246,7 +272,7 @@ extern int bttv_handle_chipset(struct bttv *btv);
246 interface below for new code */ 272 interface below for new code */
247 273
248/* returns card type + card ID (for bt878-based ones) 274/* returns card type + card ID (for bt878-based ones)
249 for possible values see lines below beginning with #define BTTV_UNKNOWN 275 for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN
250 returns negative value if error occurred 276 returns negative value if error occurred
251*/ 277*/
252extern int bttv_get_cardinfo(unsigned int card, int *type, 278extern int bttv_get_cardinfo(unsigned int card, int *type,
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index e0e7c7a84bc5..386f546f7d11 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -77,14 +77,14 @@
77struct bttv_tvnorm { 77struct bttv_tvnorm {
78 int v4l2_id; 78 int v4l2_id;
79 char *name; 79 char *name;
80 u32 Fsc; 80 u32 Fsc;
81 u16 swidth, sheight; /* scaled standard width, height */ 81 u16 swidth, sheight; /* scaled standard width, height */
82 u16 totalwidth; 82 u16 totalwidth;
83 u8 adelay, bdelay, iform; 83 u8 adelay, bdelay, iform;
84 u32 scaledtwidth; 84 u32 scaledtwidth;
85 u16 hdelayx1, hactivex1; 85 u16 hdelayx1, hactivex1;
86 u16 vdelay; 86 u16 vdelay;
87 u8 vbipack; 87 u8 vbipack;
88 u16 vtotal; 88 u16 vtotal;
89 int sram; 89 int sram;
90}; 90};
@@ -267,8 +267,8 @@ struct bttv {
267 267
268 /* card configuration info */ 268 /* card configuration info */
269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */ 269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
270 unsigned int tuner_type; /* tuner chip type */ 270 unsigned int tuner_type; /* tuner chip type */
271 unsigned int pinnacle_id; 271 unsigned int pinnacle_id;
272 unsigned int svhs; 272 unsigned int svhs;
273 struct bttv_pll_info pll; 273 struct bttv_pll_info pll;
274 int triton1; 274 int triton1;
@@ -301,9 +301,9 @@ struct bttv {
301 301
302 /* locking */ 302 /* locking */
303 spinlock_t s_lock; 303 spinlock_t s_lock;
304 struct semaphore lock; 304 struct semaphore lock;
305 int resources; 305 int resources;
306 struct semaphore reslock; 306 struct semaphore reslock;
307#ifdef VIDIOC_G_PRIORITY 307#ifdef VIDIOC_G_PRIORITY
308 struct v4l2_prio_state prio; 308 struct v4l2_prio_state prio;
309#endif 309#endif
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
new file mode 100644
index 000000000000..780b352ec119
--- /dev/null
+++ b/drivers/media/video/cs53l32a.c
@@ -0,0 +1,240 @@
1/*
2 * cs53l32a (Adaptec AVC-2010 and AVC-2410) i2c ivtv driver.
3 * Copyright (C) 2005 Martin Vaughan
4 *
5 * Audio source switching for Adaptec AVC-2410 added by Trev Jackson
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23#include <linux/module.h>
24#include <linux/types.h>
25#include <linux/ioctl.h>
26#include <asm/uaccess.h>
27#include <linux/i2c.h>
28#include <linux/i2c-id.h>
29#include <linux/videodev.h>
30#include <media/audiochip.h>
31
32MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
33MODULE_AUTHOR("Martin Vaughan");
34MODULE_LICENSE("GPL");
35
36static int debug = 0;
37
38module_param(debug, bool, 0644);
39
40MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
41
42#define cs53l32a_dbg(fmt, arg...) \
43 do { \
44 if (debug) \
45 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
46 i2c_adapter_id(client->adapter), client->addr , ## arg); \
47 } while (0)
48
49#define cs53l32a_err(fmt, arg...) do { \
50 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
51 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
52#define cs53l32a_info(fmt, arg...) do { \
53 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
54 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
55
56static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
57
58
59I2C_CLIENT_INSMOD;
60
61/* ----------------------------------------------------------------------- */
62
63static int cs53l32a_write(struct i2c_client *client, u8 reg, u8 value)
64{
65 return i2c_smbus_write_byte_data(client, reg, value);
66}
67
68static int cs53l32a_read(struct i2c_client *client, u8 reg)
69{
70 return i2c_smbus_read_byte_data(client, reg);
71}
72
73static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
74 void *arg)
75{
76 int *input = arg;
77
78 switch (cmd) {
79 case AUDC_SET_INPUT:
80 switch (*input) {
81 case AUDIO_TUNER:
82 cs53l32a_write(client, 0x01, 0x01);
83 break;
84 case AUDIO_EXTERN:
85 cs53l32a_write(client, 0x01, 0x21);
86 break;
87 case AUDIO_MUTE:
88 cs53l32a_write(client, 0x03, 0xF0);
89 break;
90 case AUDIO_UNMUTE:
91 cs53l32a_write(client, 0x03, 0x30);
92 break;
93 default:
94 cs53l32a_err("Invalid input %d.\n", *input);
95 return -EINVAL;
96 }
97 break;
98
99 case VIDIOC_S_CTRL:
100 {
101 struct v4l2_control *ctrl = arg;
102
103 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
104 return -EINVAL;
105 if (ctrl->value > 12 || ctrl->value < -90)
106 return -EINVAL;
107 cs53l32a_write(client, 0x04, (u8) ctrl->value);
108 cs53l32a_write(client, 0x05, (u8) ctrl->value);
109 break;
110 }
111
112 case VIDIOC_LOG_STATUS:
113 {
114 u8 v = cs53l32a_read(client, 0x01);
115 u8 m = cs53l32a_read(client, 0x03);
116
117 cs53l32a_info("Input: %s%s\n",
118 v == 0x21 ? "external line in" : "tuner",
119 (m & 0xC0) ? " (muted)" : "");
120 break;
121 }
122
123 default:
124 return -EINVAL;
125 }
126 return 0;
127}
128
129/* ----------------------------------------------------------------------- */
130
131/* i2c implementation */
132
133/*
134 * Generic i2c probe
135 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
136 */
137
138static struct i2c_driver i2c_driver;
139
140static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
141{
142 struct i2c_client *client;
143 int i;
144
145 /* Check if the adapter supports the needed features */
146 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
147 return 0;
148
149 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
150 if (client == 0)
151 return -ENOMEM;
152
153 memset(client, 0, sizeof(struct i2c_client));
154 client->addr = address;
155 client->adapter = adapter;
156 client->driver = &i2c_driver;
157 client->flags = I2C_CLIENT_ALLOW_USE;
158 snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
159
160 cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
161
162 for (i = 1; i <= 7; i++) {
163 u8 v = cs53l32a_read(client, i);
164
165 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
166 }
167
168 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
169
170 cs53l32a_write(client, 0x01, (u8) 0x21);
171 cs53l32a_write(client, 0x02, (u8) 0x29);
172 cs53l32a_write(client, 0x03, (u8) 0x30);
173 cs53l32a_write(client, 0x04, (u8) 0x00);
174 cs53l32a_write(client, 0x05, (u8) 0x00);
175 cs53l32a_write(client, 0x06, (u8) 0x00);
176 cs53l32a_write(client, 0x07, (u8) 0x00);
177
178 /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */
179
180 for (i = 1; i <= 7; i++) {
181 u8 v = cs53l32a_read(client, i);
182
183 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
184 }
185
186 i2c_attach_client(client);
187
188 return 0;
189}
190
191static int cs53l32a_probe(struct i2c_adapter *adapter)
192{
193#ifdef I2C_CLASS_TV_ANALOG
194 if (adapter->class & I2C_CLASS_TV_ANALOG)
195#else
196 if (adapter->id == I2C_HW_B_BT848)
197#endif
198 return i2c_probe(adapter, &addr_data, cs53l32a_attach);
199 return 0;
200}
201
202static int cs53l32a_detach(struct i2c_client *client)
203{
204 int err;
205
206 err = i2c_detach_client(client);
207 if (err) {
208 return err;
209 }
210 kfree(client);
211
212 return 0;
213}
214
215/* ----------------------------------------------------------------------- */
216
217/* i2c implementation */
218static struct i2c_driver i2c_driver = {
219 .name = "cs53l32a",
220 .id = I2C_DRIVERID_CS53L32A,
221 .flags = I2C_DF_NOTIFY,
222 .attach_adapter = cs53l32a_probe,
223 .detach_client = cs53l32a_detach,
224 .command = cs53l32a_command,
225 .owner = THIS_MODULE,
226};
227
228
229static int __init cs53l32a_init_module(void)
230{
231 return i2c_add_driver(&i2c_driver);
232}
233
234static void __exit cs53l32a_cleanup_module(void)
235{
236 i2c_del_driver(&i2c_driver);
237}
238
239module_init(cs53l32a_init_module);
240module_exit(cs53l32a_cleanup_module);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
new file mode 100644
index 000000000000..41818b6205b3
--- /dev/null
+++ b/drivers/media/video/cx88/Kconfig
@@ -0,0 +1,91 @@
1config VIDEO_CX88
2 tristate "Conexant 2388x (bt878 successor) support"
3 depends on VIDEO_DEV && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_BTCX
7 select VIDEO_BUF
8 select VIDEO_TUNER
9 select VIDEO_TVEEPROM
10 select VIDEO_IR
11 ---help---
12 This is a video4linux driver for Conexant 2388x based
13 TV cards.
14
15 To compile this driver as a module, choose M here: the
16 module will be called cx8800
17
18config VIDEO_CX88_DVB
19 tristate "DVB/ATSC Support for cx2388x based TV cards"
20 depends on VIDEO_CX88 && DVB_CORE
21 select VIDEO_BUF_DVB
22 ---help---
23 This adds support for DVB/ATSC cards based on the
24 Connexant 2388x chip.
25
26 To compile this driver as a module, choose M here: the
27 module will be called cx88-dvb.
28
29 You must also select one or more DVB/ATSC demodulators.
30 If you are unsure which you need, choose all of them.
31
32config VIDEO_CX88_DVB_ALL_FRONTENDS
33 bool "Build all supported frontends for cx2388x based TV cards"
34 default y
35 depends on VIDEO_CX88_DVB
36 select DVB_MT352
37 select DVB_OR51132
38 select DVB_CX22702
39 select DVB_LGDT330X
40 select DVB_NXT200X
41 ---help---
42 This builds cx88-dvb with all currently supported frontend
43 demodulators. If you wish to tweak your configuration, and
44 only include support for the hardware that you need, choose N here.
45
46 If you are unsure, choose Y.
47
48config VIDEO_CX88_DVB_MT352
49 tristate "Zarlink MT352 DVB-T Support"
50 default m
51 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
52 select DVB_MT352
53 ---help---
54 This adds DVB-T support for cards based on the
55 Connexant 2388x chip and the MT352 demodulator.
56
57config VIDEO_CX88_DVB_OR51132
58 tristate "OR51132 ATSC Support"
59 default m
60 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
61 select DVB_OR51132
62 ---help---
63 This adds ATSC 8VSB and QAM64/256 support for cards based on the
64 Connexant 2388x chip and the OR51132 demodulator.
65
66config VIDEO_CX88_DVB_CX22702
67 tristate "Conexant CX22702 DVB-T Support"
68 default m
69 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
70 select DVB_CX22702
71 ---help---
72 This adds DVB-T support for cards based on the
73 Connexant 2388x chip and the CX22702 demodulator.
74
75config VIDEO_CX88_DVB_LGDT330X
76 tristate "LG Electronics DT3302/DT3303 ATSC Support"
77 default m
78 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
79 select DVB_LGDT330X
80 ---help---
81 This adds ATSC 8VSB and QAM64/256 support for cards based on the
82 Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
83
84config VIDEO_CX88_DVB_NXT200X
85 tristate "NXT2002/NXT2004 ATSC Support"
86 default m
87 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
88 select DVB_NXT200X
89 ---help---
90 This adds ATSC 8VSB and QAM64/256 support for cards based on the
91 Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 107e48645e3a..0df40b773454 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -9,6 +9,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
9EXTRA_CFLAGS += -I$(src)/.. 9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
12ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
13 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
14endif
12ifneq ($(CONFIG_DVB_CX22702),n) 15ifneq ($(CONFIG_DVB_CX22702),n)
13 EXTRA_CFLAGS += -DHAVE_CX22702=1 16 EXTRA_CFLAGS += -DHAVE_CX22702=1
14endif 17endif
@@ -21,3 +24,6 @@ endif
21ifneq ($(CONFIG_DVB_MT352),n) 24ifneq ($(CONFIG_DVB_MT352),n)
22 EXTRA_CFLAGS += -DHAVE_MT352=1 25 EXTRA_CFLAGS += -DHAVE_MT352=1
23endif 26endif
27ifneq ($(CONFIG_DVB_NXT200X),n)
28 EXTRA_CFLAGS += -DHAVE_NXT200X=1
29endif
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 0c0c59e94774..4ae3f78cccf2 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static unsigned int mpegbufs = 8; 41static unsigned int mpegbufs = 32;
42module_param(mpegbufs,int,0644); 42module_param(mpegbufs,int,0644);
43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); 43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
44 44
@@ -436,7 +436,7 @@ static int memory_write(struct cx88_core *core, u32 address, u32 value)
436 436
437static int memory_read(struct cx88_core *core, u32 address, u32 *value) 437static int memory_read(struct cx88_core *core, u32 address, u32 *value)
438{ 438{
439 int retval; 439 int retval;
440 u32 val; 440 u32 val;
441 441
442 /* Warning: address is dword address (4 bytes) */ 442 /* Warning: address is dword address (4 bytes) */
@@ -605,11 +605,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
605 u32 *dataptr; 605 u32 *dataptr;
606 606
607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); 607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); 609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); 610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
611 msleep(1); 611 msleep(1);
612 retval |= register_write(dev->core, IVTV_REG_APU, 0); 612 retval |= register_write(dev->core, IVTV_REG_APU, 0);
613 613
614 if (retval < 0) 614 if (retval < 0)
615 dprintk(0, "Error with register_write\n"); 615 dprintk(0, "Error with register_write\n");
@@ -657,13 +657,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
657 release_firmware(firmware); 657 release_firmware(firmware);
658 dprintk(0, "Firmware upload successful.\n"); 658 dprintk(0, "Firmware upload successful.\n");
659 659
660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
661 retval |= register_read(dev->core, IVTV_REG_SPU, &value); 661 retval |= register_read(dev->core, IVTV_REG_SPU, &value);
662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); 662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
663 msleep(1); 663 msleep(1);
664 664
665 retval |= register_read(dev->core, IVTV_REG_VPU, &value); 665 retval |= register_read(dev->core, IVTV_REG_VPU, &value);
666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); 666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
667 667
668 if (retval < 0) 668 if (retval < 0)
669 dprintk(0, "Error with register_write\n"); 669 dprintk(0, "Error with register_write\n");
@@ -683,84 +683,560 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
683================================================================================================================= 683=================================================================================================================
684*DB: "DirectBurn" 684*DB: "DirectBurn"
685*/ 685*/
686static void blackbird_codec_settings(struct cx8802_dev *dev) 686
687static struct blackbird_dnr default_dnr_params = {
688 .mode = BLACKBIRD_DNR_BITS_MANUAL,
689 .type = BLACKBIRD_MEDIAN_FILTER_DISABLED,
690 .spatial = 0,
691 .temporal = 0
692};
693static struct v4l2_mpeg_compression default_mpeg_params = {
694 .st_type = V4L2_MPEG_PS_2,
695 .st_bitrate = {
696 .mode = V4L2_BITRATE_CBR,
697 .min = 0,
698 .target = 0,
699 .max = 0
700 },
701 .ts_pid_pmt = 16,
702 .ts_pid_audio = 260,
703 .ts_pid_video = 256,
704 .ts_pid_pcr = 259,
705 .ps_size = 0,
706 .au_type = V4L2_MPEG_AU_2_II,
707 .au_bitrate = {
708 .mode = V4L2_BITRATE_CBR,
709 .min = 224,
710 .target = 224,
711 .max = 224
712 },
713 .au_sample_rate = 44100,
714 .au_pesid = 0,
715 .vi_type = V4L2_MPEG_VI_2,
716 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
717 .vi_bitrate = {
718 .mode = V4L2_BITRATE_CBR,
719 .min = 4000,
720 .target = 4500,
721 .max = 6000
722 },
723 .vi_frame_rate = 25,
724 .vi_frames_per_gop = 15,
725 .vi_bframes_count = 2,
726 .vi_pesid = 0,
727 .closed_gops = 0,
728 .pulldown = 0
729};
730
731static enum blackbird_stream_type mpeg_stream_types[] = {
732 [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1,
733 [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM,
734 [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT,
735 [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD,
736};
737static enum blackbird_aspect_ratio mpeg_stream_ratios[] = {
738 [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
739 [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3,
740 [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9,
741 [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100,
742};
743static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = {
744 [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR,
745 [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR,
746 [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR,
747};
748/* find the best layer I/II bitrate to fit a given numeric value */
749struct bitrate_bits {
750 u32 bits; /* layer bits for the best fit */
751 u32 rate; /* actual numeric value for the layer best fit */
752};
753struct bitrate_approximation {
754 u32 target; /* numeric value of the rate we want */
755 struct bitrate_bits layer[2];
756};
757static struct bitrate_approximation mpeg_audio_bitrates[] = {
758 /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
759 { 0, { { 0, 0, }, { 0, 0, }, }, },
760 { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, },
761 { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, },
762 { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, },
763 { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, },
764 { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, },
765 { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, },
766 { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, },
767 { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, },
768 { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, },
769 { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, },
770 { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, },
771 { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, },
772 { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
773 { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
774 { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
775 { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
776 { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
777 { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
778};
779static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates);
780
781static void blackbird_set_default_params(struct cx8802_dev *dev)
687{ 782{
688 int bitrate_mode = 1; 783 struct v4l2_mpeg_compression *params = &dev->params;
689 int bitrate = 7500000; 784 u32 au_params;
690 int bitrate_peak = 7500000;
691 bitrate_mode = BLACKBIRD_VIDEO_CBR;
692 bitrate = 4000*1024;
693 bitrate_peak = 4000*1024;
694 785
695 /* assign stream type */ 786 /* assign stream type */
696 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); 787 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
697 788 params->st_type = V4L2_MPEG_PS_2;
698 /* assign output port */ 789 if( params->st_type == V4L2_MPEG_SS_1 )
699 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ 790 params->vi_type = V4L2_MPEG_VI_1;
791 else
792 params->vi_type = V4L2_MPEG_VI_2;
793 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
700 794
701 /* assign framerate */ 795 /* assign framerate */
702 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); 796 if( params->vi_frame_rate <= 25 )
703 797 {
704 /* assign frame size */ 798 params->vi_frame_rate = 25;
705 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, 799 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
706 dev->height, dev->width); 800 }
801 else
802 {
803 params->vi_frame_rate = 30;
804 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
805 }
707 806
708 /* assign aspect ratio */ 807 /* assign aspect ratio */
709 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3); 808 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
710 809 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
711 /* assign bitrates */ 810 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
712 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
713 bitrate_mode, /* mode */
714 bitrate, /* bps */
715 bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
716 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
717 811
718 /* assign gop properties */ 812 /* assign gop properties */
719 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3); 813 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
814
815 /* assign gop closure */
816 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
720 817
721 /* assign 3 2 pulldown */ 818 /* assign 3 2 pulldown */
722 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED); 819 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
820
821 /* make sure the params are within bounds */
822 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
823 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
824 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
825 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
826 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
827 params->au_bitrate.mode = V4L2_BITRATE_NONE;
723 828
724 /* assign audio properties */ 829 /* assign audio properties */
725 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ 830 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
726 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); 831 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
727 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
728 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
729 BLACKBIRD_AUDIO_BITS_44100HZ |
730 BLACKBIRD_AUDIO_BITS_LAYER_2 |
731 BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
732 BLACKBIRD_AUDIO_BITS_STEREO |
733 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ 832 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
734 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | 833 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
735 BLACKBIRD_AUDIO_BITS_CRC_OFF | 834 BLACKBIRD_AUDIO_BITS_CRC_OFF |
736 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | 835 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
737 BLACKBIRD_AUDIO_BITS_COPY 836 BLACKBIRD_AUDIO_BITS_COPY |
738 ); 837 0;
838 if( params->au_sample_rate <= 32000 )
839 {
840 params->au_sample_rate = 32000;
841 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
842 }
843 else if( params->au_sample_rate <= 44100 )
844 {
845 params->au_sample_rate = 44100;
846 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
847 }
848 else
849 {
850 params->au_sample_rate = 48000;
851 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
852 }
853 if( params->au_type == V4L2_MPEG_AU_2_I )
854 {
855 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
856 }
857 else
858 {
859 /* TODO: try to handle the other formats more gracefully */
860 params->au_type = V4L2_MPEG_AU_2_II;
861 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
862 }
863 if( params->au_bitrate.mode )
864 {
865 int layer;
866
867 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
868 params->au_bitrate.max = params->vi_bitrate.target;
869 else
870 params->au_bitrate.target = params->vi_bitrate.max;
871
872 layer = params->au_type;
873 if( params->au_bitrate.target == 0 )
874 {
875 /* TODO: use the minimum possible bitrate instead of 0 ? */
876 au_params |= 0;
877 }
878 else if( params->au_bitrate.target >=
879 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
880 {
881 /* clamp the bitrate to the max supported by the standard */
882 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
883 params->au_bitrate.max = params->au_bitrate.target;
884 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
885 }
886 else
887 {
888 /* round up to the nearest supported bitrate */
889 int i;
890 for(i = 1; i < BITRATES_SIZE; i++)
891 {
892 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
893 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
894 {
895 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
896 params->au_bitrate.max = params->au_bitrate.target;
897 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
898 break;
899 }
900 }
901 }
902 }
903 else
904 {
905 /* TODO: ??? */
906 params->au_bitrate.target = params->au_bitrate.max = 0;
907 au_params |= 0;
908 }
909 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
910
911 /* assign bitrates */
912 if( params->vi_bitrate.mode )
913 {
914 /* bitrate is set, let's figure out the cbr/vbr mess */
915 if( params->vi_bitrate.max < params->vi_bitrate.target )
916 {
917 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
918 params->vi_bitrate.max = params->vi_bitrate.target;
919 else
920 params->vi_bitrate.target = params->vi_bitrate.max;
921 }
922 }
923 else
924 {
925 if( params->st_bitrate.max < params->st_bitrate.target )
926 {
927 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
928 params->st_bitrate.target = params->st_bitrate.max;
929 else
930 params->st_bitrate.max = params->st_bitrate.target;
931 }
932 /* calculate vi_bitrate = st_bitrate - au_bitrate */
933 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
934 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
935 }
936 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
937 mpeg_video_bitrates[params->vi_bitrate.mode],
938 params->vi_bitrate.target * 1000, /* kbps -> bps */
939 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
940 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
941
942 /* TODO: implement the stream ID stuff:
943 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
944 ps_size, au_pesid, vi_pesid
945 */
946}
947#define CHECK_PARAM( name ) ( dev->params.name != params->name )
948#define IF_PARAM( name ) if( CHECK_PARAM( name ) )
949#define UPDATE_PARAM( name ) dev->params.name = params->name
950void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params)
951{
952 u32 au_params;
953
954 /* assign stream type */
955 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
956 params->st_type = V4L2_MPEG_PS_2;
957 if( params->st_type == V4L2_MPEG_SS_1 )
958 params->vi_type = V4L2_MPEG_VI_1;
959 else
960 params->vi_type = V4L2_MPEG_VI_2;
961 if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) )
962 {
963 UPDATE_PARAM( st_type );
964 UPDATE_PARAM( vi_type );
965 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
966 }
967
968 /* assign framerate */
969 if( params->vi_frame_rate <= 25 )
970 params->vi_frame_rate = 25;
971 else
972 params->vi_frame_rate = 30;
973 IF_PARAM( vi_frame_rate )
974 {
975 UPDATE_PARAM( vi_frame_rate );
976 if( params->vi_frame_rate == 25 )
977 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
978 else
979 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
980 }
981
982 /* assign aspect ratio */
983 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
984 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
985 IF_PARAM( vi_aspect_ratio )
986 {
987 UPDATE_PARAM( vi_aspect_ratio );
988 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
989 }
990
991 /* assign gop properties */
992 if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) )
993 {
994 UPDATE_PARAM( vi_frames_per_gop );
995 UPDATE_PARAM( vi_bframes_count );
996 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
997 }
739 998
740 /* assign gop closure */ 999 /* assign gop closure */
741 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF); 1000 IF_PARAM( closed_gops )
1001 {
1002 UPDATE_PARAM( closed_gops );
1003 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
1004 }
1005
1006 /* assign 3 2 pulldown */
1007 IF_PARAM( pulldown )
1008 {
1009 UPDATE_PARAM( pulldown );
1010 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
1011 }
1012
1013 /* make sure the params are within bounds */
1014 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1015 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1016 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1017 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1018 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1019 params->au_bitrate.mode = V4L2_BITRATE_NONE;
1020
1021 /* assign audio properties */
1022 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
1023 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
1024 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
1025 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
1026 BLACKBIRD_AUDIO_BITS_CRC_OFF |
1027 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
1028 BLACKBIRD_AUDIO_BITS_COPY |
1029 0;
1030 if( params->au_sample_rate < 32000 )
1031 {
1032 params->au_sample_rate = 32000;
1033 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
1034 }
1035 else if( params->au_sample_rate < 44100 )
1036 {
1037 params->au_sample_rate = 44100;
1038 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
1039 }
1040 else
1041 {
1042 params->au_sample_rate = 48000;
1043 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
1044 }
1045 if( params->au_type == V4L2_MPEG_AU_2_I )
1046 {
1047 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
1048 }
1049 else
1050 {
1051 /* TODO: try to handle the other formats more gracefully */
1052 params->au_type = V4L2_MPEG_AU_2_II;
1053 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
1054 }
1055 if( params->au_bitrate.mode )
1056 {
1057 int layer;
1058
1059 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
1060 params->au_bitrate.max = params->vi_bitrate.target;
1061 else
1062 params->au_bitrate.target = params->vi_bitrate.max;
1063
1064 layer = params->au_type;
1065 if( params->au_bitrate.target == 0 )
1066 {
1067 /* TODO: use the minimum possible bitrate instead of 0 ? */
1068 au_params |= 0;
1069 }
1070 else if( params->au_bitrate.target >=
1071 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
1072 {
1073 /* clamp the bitrate to the max supported by the standard */
1074 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
1075 params->au_bitrate.max = params->au_bitrate.target;
1076 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
1077 }
1078 else
1079 {
1080 /* round up to the nearest supported bitrate */
1081 int i;
1082 for(i = 1; i < BITRATES_SIZE; i++)
1083 {
1084 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
1085 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
1086 {
1087 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
1088 params->au_bitrate.max = params->au_bitrate.target;
1089 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
1090 break;
1091 }
1092 }
1093 }
1094 }
1095 else
1096 {
1097 /* TODO: ??? */
1098 params->au_bitrate.target = params->au_bitrate.max = 0;
1099 au_params |= 0;
1100 }
1101 if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate )
1102 || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max )
1103 || CHECK_PARAM( au_bitrate.target )
1104 )
1105 {
1106 UPDATE_PARAM( au_type );
1107 UPDATE_PARAM( au_sample_rate );
1108 UPDATE_PARAM( au_bitrate );
1109 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
1110 }
1111
1112 /* assign bitrates */
1113 if( params->vi_bitrate.mode )
1114 {
1115 /* bitrate is set, let's figure out the cbr/vbr mess */
1116 if( params->vi_bitrate.max < params->vi_bitrate.target )
1117 {
1118 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
1119 params->vi_bitrate.max = params->vi_bitrate.target;
1120 else
1121 params->vi_bitrate.target = params->vi_bitrate.max;
1122 }
1123 }
1124 else
1125 {
1126 if( params->st_bitrate.max < params->st_bitrate.target )
1127 {
1128 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
1129 params->st_bitrate.target = params->st_bitrate.max;
1130 else
1131 params->st_bitrate.max = params->st_bitrate.target;
1132 }
1133 /* calculate vi_bitrate = st_bitrate - au_bitrate */
1134 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
1135 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
1136 }
1137 UPDATE_PARAM( st_bitrate );
1138 if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max )
1139 || CHECK_PARAM( vi_bitrate.target )
1140 )
1141 {
1142 UPDATE_PARAM( vi_bitrate );
1143 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
1144 mpeg_video_bitrates[params->vi_bitrate.mode],
1145 params->vi_bitrate.target * 1000, /* kbps -> bps */
1146 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
1147 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
1148 }
742 1149
1150 /* TODO: implement the stream ID stuff:
1151 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
1152 ps_size, au_pesid, vi_pesid
1153 */
1154 UPDATE_PARAM( ts_pid_pmt );
1155 UPDATE_PARAM( ts_pid_audio );
1156 UPDATE_PARAM( ts_pid_video );
1157 UPDATE_PARAM( ts_pid_pcr );
1158 UPDATE_PARAM( ps_size );
1159 UPDATE_PARAM( au_pesid );
1160 UPDATE_PARAM( vi_pesid );
1161}
743 1162
1163static void blackbird_set_default_dnr_params(struct cx8802_dev *dev)
1164{
744 /* assign dnr filter mode */ 1165 /* assign dnr filter mode */
1166 if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO )
1167 dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL;
1168 if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1169 dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
745 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, 1170 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
746 BLACKBIRD_DNR_BITS_MANUAL, 1171 dev->dnr_params.mode,
747 BLACKBIRD_MEDIAN_FILTER_DISABLED 1172 dev->dnr_params.type
748 ); 1173 );
749 1174
750 /* assign dnr filter props*/ 1175 /* assign dnr filter props*/
751 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0); 1176 if( dev->dnr_params.spatial > 15 )
1177 dev->dnr_params.spatial = 15;
1178 if( dev->dnr_params.temporal > 31 )
1179 dev->dnr_params.temporal = 31;
1180 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0,
1181 dev->dnr_params.spatial,
1182 dev->dnr_params.temporal
1183 );
1184}
1185#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
1186#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
1187void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params)
1188{
1189 /* assign dnr filter mode */
1190 /* clamp values */
1191 if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO )
1192 dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL;
1193 if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1194 dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
1195 /* check if the params actually changed */
1196 if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) )
1197 {
1198 UPDATE_DNR_PARAM( mode );
1199 UPDATE_DNR_PARAM( type );
1200 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type);
1201 }
1202
1203 /* assign dnr filter props*/
1204 if( dnr_params->spatial > 15 )
1205 dnr_params->spatial = 15;
1206 if( dnr_params->temporal > 31 )
1207 dnr_params->temporal = 31;
1208 if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) )
1209 {
1210 UPDATE_DNR_PARAM( spatial );
1211 UPDATE_DNR_PARAM( temporal );
1212 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal);
1213 }
1214}
1215
1216static void blackbird_codec_settings(struct cx8802_dev *dev)
1217{
1218
1219 /* assign output port */
1220 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
1221
1222 /* assign frame size */
1223 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
1224 dev->height, dev->width);
752 1225
753 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ 1226 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
754 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); 1227 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
755 1228
756 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ 1229 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
757 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, 1230 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
758 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, 1231 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
759 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ 1232 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
760 ); 1233 );
761 1234
762 /* assign frame drop rate */ 1235 /* assign frame drop rate */
763 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ 1236 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
1237
1238 blackbird_set_default_params(dev);
1239 blackbird_set_default_dnr_params(dev);
764} 1240}
765 1241
766static int blackbird_initialize_codec(struct cx8802_dev *dev) 1242static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -851,15 +1327,10 @@ static int bb_buf_setup(struct videobuf_queue *q,
851 struct cx8802_fh *fh = q->priv_data; 1327 struct cx8802_fh *fh = q->priv_data;
852 1328
853 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ 1329 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
854 fh->dev->ts_packet_count = 32; /* was: 100 */ 1330 fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
855 1331
856 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 1332 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
857 if (0 == *count) 1333 *count = fh->dev->ts_packet_count;
858 *count = mpegbufs;
859 if (*count < 2)
860 *count = 2;
861 if (*count > 32)
862 *count = 32;
863 return 0; 1334 return 0;
864} 1335}
865 1336
@@ -868,7 +1339,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
868 enum v4l2_field field) 1339 enum v4l2_field field)
869{ 1340{
870 struct cx8802_fh *fh = q->priv_data; 1341 struct cx8802_fh *fh = q->priv_data;
871 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb); 1342 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
872} 1343}
873 1344
874static void 1345static void
@@ -920,8 +1391,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
920 V4L2_CAP_VIDEO_CAPTURE | 1391 V4L2_CAP_VIDEO_CAPTURE |
921 V4L2_CAP_READWRITE | 1392 V4L2_CAP_READWRITE |
922 V4L2_CAP_STREAMING | 1393 V4L2_CAP_STREAMING |
923 V4L2_CAP_VBI_CAPTURE |
924 V4L2_CAP_VIDEO_OVERLAY |
925 0; 1394 0;
926 if (UNSET != core->tuner_type) 1395 if (UNSET != core->tuner_type)
927 cap->capabilities |= V4L2_CAP_TUNER; 1396 cap->capabilities |= V4L2_CAP_TUNER;
@@ -941,27 +1410,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
941 1410
942 memset(f,0,sizeof(*f)); 1411 memset(f,0,sizeof(*f));
943 f->index = index; 1412 f->index = index;
944 strlcpy(f->description, "MPEG TS", sizeof(f->description)); 1413 strlcpy(f->description, "MPEG", sizeof(f->description));
945 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1414 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
946 f->pixelformat = V4L2_PIX_FMT_MPEG; 1415 f->pixelformat = V4L2_PIX_FMT_MPEG;
947 return 0; 1416 return 0;
948 } 1417 }
949 case VIDIOC_G_FMT: 1418 case VIDIOC_G_FMT:
950 case VIDIOC_S_FMT:
951 case VIDIOC_TRY_FMT:
952 { 1419 {
953 /* FIXME -- quick'n'dirty for exactly one size ... */
954 struct v4l2_format *f = arg; 1420 struct v4l2_format *f = arg;
955 1421
956 memset(f,0,sizeof(*f)); 1422 memset(f,0,sizeof(*f));
957 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1423 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1424 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1425 f->fmt.pix.bytesperline = 0;
1426 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
1427 f->fmt.pix.colorspace = 0;
958 f->fmt.pix.width = dev->width; 1428 f->fmt.pix.width = dev->width;
959 f->fmt.pix.height = dev->height; 1429 f->fmt.pix.height = dev->height;
1430 f->fmt.pix.field = fh->mpegq.field;
1431 dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
1432 dev->width, dev->height, fh->mpegq.field );
1433 return 0;
1434 }
1435 case VIDIOC_TRY_FMT:
1436 {
1437 struct v4l2_format *f = arg;
1438
1439 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1440 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1441 f->fmt.pix.bytesperline = 0;
1442 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
1443 f->fmt.pix.colorspace = 0;
1444 dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
1445 dev->width, dev->height, fh->mpegq.field );
1446 return 0;
1447 }
1448 case VIDIOC_S_FMT:
1449 {
1450 struct v4l2_format *f = arg;
1451
1452 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
960 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 1453 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
961 f->fmt.pix.field = V4L2_FIELD_NONE;
962 f->fmt.pix.bytesperline = 0; 1454 f->fmt.pix.bytesperline = 0;
963 f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */; 1455 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
964 f->fmt.pix.colorspace = 0; 1456 f->fmt.pix.colorspace = 0;
1457 dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
1458 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
965 return 0; 1459 return 0;
966 } 1460 }
967 1461
@@ -985,6 +1479,22 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
985 case VIDIOC_STREAMOFF: 1479 case VIDIOC_STREAMOFF:
986 return videobuf_streamoff(&fh->mpegq); 1480 return videobuf_streamoff(&fh->mpegq);
987 1481
1482 /* --- mpeg compression -------------------------------------- */
1483 case VIDIOC_G_MPEGCOMP:
1484 {
1485 struct v4l2_mpeg_compression *f = arg;
1486
1487 memcpy(f,&dev->params,sizeof(*f));
1488 return 0;
1489 }
1490 case VIDIOC_S_MPEGCOMP:
1491 {
1492 struct v4l2_mpeg_compression *f = arg;
1493
1494 blackbird_set_params(dev, f);
1495 return 0;
1496 }
1497
988 default: 1498 default:
989 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); 1499 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
990 } 1500 }
@@ -1034,16 +1544,17 @@ static int mpeg_open(struct inode *inode, struct file *file)
1034 file->private_data = fh; 1544 file->private_data = fh;
1035 fh->dev = dev; 1545 fh->dev = dev;
1036 1546
1037 /* FIXME: locking against other video device */
1038 cx88_set_scale(dev->core, dev->width, dev->height,
1039 V4L2_FIELD_INTERLACED);
1040
1041 videobuf_queue_init(&fh->mpegq, &blackbird_qops, 1547 videobuf_queue_init(&fh->mpegq, &blackbird_qops,
1042 dev->pci, &dev->slock, 1548 dev->pci, &dev->slock,
1043 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1549 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1044 V4L2_FIELD_TOP, 1550 V4L2_FIELD_INTERLACED,
1045 sizeof(struct cx88_buffer), 1551 sizeof(struct cx88_buffer),
1046 fh); 1552 fh);
1553
1554 /* FIXME: locking against other video device */
1555 cx88_set_scale(dev->core, dev->width, dev->height,
1556 fh->mpegq.field);
1557
1047 return 0; 1558 return 0;
1048} 1559}
1049 1560
@@ -1173,6 +1684,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1173 dev->core = core; 1684 dev->core = core;
1174 dev->width = 720; 1685 dev->width = 720;
1175 dev->height = 576; 1686 dev->height = 576;
1687 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
1688 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
1176 1689
1177 err = cx8802_init_common(dev); 1690 err = cx8802_init_common(dev);
1178 if (0 != err) 1691 if (0 != err)
@@ -1199,7 +1712,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1199 1712
1200static void __devexit blackbird_remove(struct pci_dev *pci_dev) 1713static void __devexit blackbird_remove(struct pci_dev *pci_dev)
1201{ 1714{
1202 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 1715 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
1203 1716
1204 /* blackbird */ 1717 /* blackbird */
1205 blackbird_unregister_video(dev); 1718 blackbird_unregister_video(dev);
@@ -1215,8 +1728,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1215 { 1728 {
1216 .vendor = 0x14f1, 1729 .vendor = 0x14f1,
1217 .device = 0x8802, 1730 .device = 0x8802,
1218 .subvendor = PCI_ANY_ID, 1731 .subvendor = PCI_ANY_ID,
1219 .subdevice = PCI_ANY_ID, 1732 .subdevice = PCI_ANY_ID,
1220 },{ 1733 },{
1221 /* --- end of list --- */ 1734 /* --- end of list --- */
1222 } 1735 }
@@ -1224,10 +1737,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1224MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 1737MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
1225 1738
1226static struct pci_driver blackbird_pci_driver = { 1739static struct pci_driver blackbird_pci_driver = {
1227 .name = "cx88-blackbird", 1740 .name = "cx88-blackbird",
1228 .id_table = cx8802_pci_tbl, 1741 .id_table = cx8802_pci_tbl,
1229 .probe = blackbird_probe, 1742 .probe = blackbird_probe,
1230 .remove = __devexit_p(blackbird_remove), 1743 .remove = __devexit_p(blackbird_remove),
1231 .suspend = cx8802_suspend_common, 1744 .suspend = cx8802_suspend_common,
1232 .resume = cx8802_resume_common, 1745 .resume = cx8802_resume_common,
1233}; 1746};
@@ -1257,6 +1770,8 @@ module_exit(blackbird_fini);
1257 1770
1258EXPORT_SYMBOL(cx88_ioctl_hook); 1771EXPORT_SYMBOL(cx88_ioctl_hook);
1259EXPORT_SYMBOL(cx88_ioctl_translator); 1772EXPORT_SYMBOL(cx88_ioctl_translator);
1773EXPORT_SYMBOL(blackbird_set_params);
1774EXPORT_SYMBOL(blackbird_set_dnr_params);
1260 1775
1261/* ----------------------------------------------------------- */ 1776/* ----------------------------------------------------------- */
1262/* 1777/*
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 4da91d535a5b..f2268631b7c0 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -126,27 +126,27 @@ struct cx88_board cx88_boards[] = {
126 .input = {{ 126 .input = {{
127 .type = CX88_VMUX_TELEVISION, 127 .type = CX88_VMUX_TELEVISION,
128 .vmux = 0, 128 .vmux = 0,
129 .gpio0 = 0x03ff, 129 .gpio0 = 0x03ff,
130 },{ 130 },{
131 .type = CX88_VMUX_COMPOSITE1, 131 .type = CX88_VMUX_COMPOSITE1,
132 .vmux = 1, 132 .vmux = 1,
133 .gpio0 = 0x03fe, 133 .gpio0 = 0x03fe,
134 },{ 134 },{
135 .type = CX88_VMUX_SVIDEO, 135 .type = CX88_VMUX_SVIDEO,
136 .vmux = 2, 136 .vmux = 2,
137 .gpio0 = 0x03fe, 137 .gpio0 = 0x03fe,
138 }}, 138 }},
139 }, 139 },
140 [CX88_BOARD_WINFAST2000XP_EXPERT] = { 140 [CX88_BOARD_WINFAST2000XP_EXPERT] = {
141 .name = "Leadtek Winfast 2000XP Expert", 141 .name = "Leadtek Winfast 2000XP Expert",
142 .tuner_type = TUNER_PHILIPS_4IN1, 142 .tuner_type = TUNER_PHILIPS_4IN1,
143 .radio_type = UNSET, 143 .radio_type = UNSET,
144 .tuner_addr = ADDR_UNSET, 144 .tuner_addr = ADDR_UNSET,
145 .radio_addr = ADDR_UNSET, 145 .radio_addr = ADDR_UNSET,
146 .tda9887_conf = TDA9887_PRESENT, 146 .tda9887_conf = TDA9887_PRESENT,
147 .input = {{ 147 .input = {{
148 .type = CX88_VMUX_TELEVISION, 148 .type = CX88_VMUX_TELEVISION,
149 .vmux = 0, 149 .vmux = 0,
150 .gpio0 = 0x00F5e700, 150 .gpio0 = 0x00F5e700,
151 .gpio1 = 0x00003004, 151 .gpio1 = 0x00003004,
152 .gpio2 = 0x00F5e700, 152 .gpio2 = 0x00F5e700,
@@ -165,16 +165,16 @@ struct cx88_board cx88_boards[] = {
165 .gpio1 = 0x00003004, 165 .gpio1 = 0x00003004,
166 .gpio2 = 0x00F5c700, 166 .gpio2 = 0x00F5c700,
167 .gpio3 = 0x02000000, 167 .gpio3 = 0x02000000,
168 }}, 168 }},
169 .radio = { 169 .radio = {
170 .type = CX88_RADIO, 170 .type = CX88_RADIO,
171 .gpio0 = 0x00F5d700, 171 .gpio0 = 0x00F5d700,
172 .gpio1 = 0x00003004, 172 .gpio1 = 0x00003004,
173 .gpio2 = 0x00F5d700, 173 .gpio2 = 0x00F5d700,
174 .gpio3 = 0x02000000, 174 .gpio3 = 0x02000000,
175 }, 175 },
176 }, 176 },
177 [CX88_BOARD_AVERTV_303] = { 177 [CX88_BOARD_AVERTV_STUDIO_303] = {
178 .name = "AverTV Studio 303 (M126)", 178 .name = "AverTV Studio 303 (M126)",
179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
180 .radio_type = UNSET, 180 .radio_type = UNSET,
@@ -206,7 +206,7 @@ struct cx88_board cx88_boards[] = {
206 .radio_type = UNSET, 206 .radio_type = UNSET,
207 .tuner_addr = ADDR_UNSET, 207 .tuner_addr = ADDR_UNSET,
208 .radio_addr = ADDR_UNSET, 208 .radio_addr = ADDR_UNSET,
209 .tda9887_conf = TDA9887_PRESENT, 209 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
210 .input = {{ 210 .input = {{
211 .type = CX88_VMUX_TELEVISION, 211 .type = CX88_VMUX_TELEVISION,
212 .vmux = 0, 212 .vmux = 0,
@@ -214,32 +214,32 @@ struct cx88_board cx88_boards[] = {
214 .gpio1 = 0x000080c0, 214 .gpio1 = 0x000080c0,
215 .gpio2 = 0x0000ff40, 215 .gpio2 = 0x0000ff40,
216 },{ 216 },{
217 .type = CX88_VMUX_COMPOSITE1, 217 .type = CX88_VMUX_COMPOSITE1,
218 .vmux = 1, 218 .vmux = 1,
219 .gpio0 = 0x000040bf, 219 .gpio0 = 0x000040bf,
220 .gpio1 = 0x000080c0, 220 .gpio1 = 0x000080c0,
221 .gpio2 = 0x0000ff40, 221 .gpio2 = 0x0000ff40,
222 },{ 222 },{
223 .type = CX88_VMUX_SVIDEO, 223 .type = CX88_VMUX_SVIDEO,
224 .vmux = 2, 224 .vmux = 2,
225 .gpio0 = 0x000040bf, 225 .gpio0 = 0x000040bf,
226 .gpio1 = 0x000080c0, 226 .gpio1 = 0x000080c0,
227 .gpio2 = 0x0000ff40, 227 .gpio2 = 0x0000ff40,
228 }}, 228 }},
229 .radio = { 229 .radio = {
230 .type = CX88_RADIO, 230 .type = CX88_RADIO,
231 }, 231 },
232 }, 232 },
233 [CX88_BOARD_WINFAST_DV2000] = { 233 [CX88_BOARD_WINFAST_DV2000] = {
234 .name = "Leadtek Winfast DV2000", 234 .name = "Leadtek Winfast DV2000",
235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
236 .radio_type = UNSET, 236 .radio_type = UNSET,
237 .tuner_addr = ADDR_UNSET, 237 .tuner_addr = ADDR_UNSET,
238 .radio_addr = ADDR_UNSET, 238 .radio_addr = ADDR_UNSET,
239 .tda9887_conf = TDA9887_PRESENT, 239 .tda9887_conf = TDA9887_PRESENT,
240 .input = {{ 240 .input = {{
241 .type = CX88_VMUX_TELEVISION, 241 .type = CX88_VMUX_TELEVISION,
242 .vmux = 0, 242 .vmux = 0,
243 .gpio0 = 0x0035e700, 243 .gpio0 = 0x0035e700,
244 .gpio1 = 0x00003004, 244 .gpio1 = 0x00003004,
245 .gpio2 = 0x0035e700, 245 .gpio2 = 0x0035e700,
@@ -260,14 +260,14 @@ struct cx88_board cx88_boards[] = {
260 .gpio2 = 0x02000000, 260 .gpio2 = 0x02000000,
261 .gpio3 = 0x02000000, 261 .gpio3 = 0x02000000,
262 }}, 262 }},
263 .radio = { 263 .radio = {
264 .type = CX88_RADIO, 264 .type = CX88_RADIO,
265 .gpio0 = 0x0035d700, 265 .gpio0 = 0x0035d700,
266 .gpio1 = 0x00007004, 266 .gpio1 = 0x00007004,
267 .gpio2 = 0x0035d700, 267 .gpio2 = 0x0035d700,
268 .gpio3 = 0x02000000, 268 .gpio3 = 0x02000000,
269 }, 269 },
270 }, 270 },
271 [CX88_BOARD_LEADTEK_PVR2000] = { 271 [CX88_BOARD_LEADTEK_PVR2000] = {
272 // gpio values for PAL version from regspy by DScaler 272 // gpio values for PAL version from regspy by DScaler
273 .name = "Leadtek PVR 2000", 273 .name = "Leadtek PVR 2000",
@@ -296,25 +296,25 @@ struct cx88_board cx88_boards[] = {
296 .blackbird = 1, 296 .blackbird = 1,
297 }, 297 },
298 [CX88_BOARD_IODATA_GVVCP3PCI] = { 298 [CX88_BOARD_IODATA_GVVCP3PCI] = {
299 .name = "IODATA GV-VCP3/PCI", 299 .name = "IODATA GV-VCP3/PCI",
300 .tuner_type = TUNER_ABSENT, 300 .tuner_type = TUNER_ABSENT,
301 .radio_type = UNSET, 301 .radio_type = UNSET,
302 .tuner_addr = ADDR_UNSET, 302 .tuner_addr = ADDR_UNSET,
303 .radio_addr = ADDR_UNSET, 303 .radio_addr = ADDR_UNSET,
304 .input = {{ 304 .input = {{
305 .type = CX88_VMUX_COMPOSITE1, 305 .type = CX88_VMUX_COMPOSITE1,
306 .vmux = 0, 306 .vmux = 0,
307 },{ 307 },{
308 .type = CX88_VMUX_COMPOSITE2, 308 .type = CX88_VMUX_COMPOSITE2,
309 .vmux = 1, 309 .vmux = 1,
310 },{ 310 },{
311 .type = CX88_VMUX_SVIDEO, 311 .type = CX88_VMUX_SVIDEO,
312 .vmux = 2, 312 .vmux = 2,
313 }}, 313 }},
314 }, 314 },
315 [CX88_BOARD_PROLINK_PLAYTVPVR] = { 315 [CX88_BOARD_PROLINK_PLAYTVPVR] = {
316 .name = "Prolink PlayTV PVR", 316 .name = "Prolink PlayTV PVR",
317 .tuner_type = TUNER_PHILIPS_FM1236_MK3, 317 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
318 .radio_type = UNSET, 318 .radio_type = UNSET,
319 .tuner_addr = ADDR_UNSET, 319 .tuner_addr = ADDR_UNSET,
320 .radio_addr = ADDR_UNSET, 320 .radio_addr = ADDR_UNSET,
@@ -348,15 +348,15 @@ struct cx88_board cx88_boards[] = {
348 .type = CX88_VMUX_TELEVISION, 348 .type = CX88_VMUX_TELEVISION,
349 .vmux = 0, 349 .vmux = 0,
350 .gpio0 = 0x0000fde6, 350 .gpio0 = 0x0000fde6,
351 },{ 351 },{
352 .type = CX88_VMUX_SVIDEO, 352 .type = CX88_VMUX_SVIDEO,
353 .vmux = 2, 353 .vmux = 2,
354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? 354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
355 }}, 355 }},
356 .radio = { 356 .radio = {
357 .type = CX88_RADIO, 357 .type = CX88_RADIO,
358 .gpio0 = 0x0000fde2, 358 .gpio0 = 0x0000fde2,
359 }, 359 },
360 .blackbird = 1, 360 .blackbird = 1,
361 }, 361 },
362 [CX88_BOARD_MSI_TVANYWHERE] = { 362 [CX88_BOARD_MSI_TVANYWHERE] = {
@@ -372,34 +372,34 @@ struct cx88_board cx88_boards[] = {
372 .gpio0 = 0x00000fbf, 372 .gpio0 = 0x00000fbf,
373 .gpio2 = 0x0000fc08, 373 .gpio2 = 0x0000fc08,
374 },{ 374 },{
375 .type = CX88_VMUX_COMPOSITE1, 375 .type = CX88_VMUX_COMPOSITE1,
376 .vmux = 1, 376 .vmux = 1,
377 .gpio0 = 0x00000fbf, 377 .gpio0 = 0x00000fbf,
378 .gpio2 = 0x0000fc68, 378 .gpio2 = 0x0000fc68,
379 },{ 379 },{
380 .type = CX88_VMUX_SVIDEO, 380 .type = CX88_VMUX_SVIDEO,
381 .vmux = 2, 381 .vmux = 2,
382 .gpio0 = 0x00000fbf, 382 .gpio0 = 0x00000fbf,
383 .gpio2 = 0x0000fc68, 383 .gpio2 = 0x0000fc68,
384 }}, 384 }},
385 }, 385 },
386 [CX88_BOARD_KWORLD_DVB_T] = { 386 [CX88_BOARD_KWORLD_DVB_T] = {
387 .name = "KWorld/VStream XPert DVB-T", 387 .name = "KWorld/VStream XPert DVB-T",
388 .tuner_type = TUNER_ABSENT, 388 .tuner_type = TUNER_ABSENT,
389 .radio_type = UNSET, 389 .radio_type = UNSET,
390 .tuner_addr = ADDR_UNSET, 390 .tuner_addr = ADDR_UNSET,
391 .radio_addr = ADDR_UNSET, 391 .radio_addr = ADDR_UNSET,
392 .input = {{ 392 .input = {{
393 .type = CX88_VMUX_COMPOSITE1, 393 .type = CX88_VMUX_COMPOSITE1,
394 .vmux = 1, 394 .vmux = 1,
395 .gpio0 = 0x0700, 395 .gpio0 = 0x0700,
396 .gpio2 = 0x0101, 396 .gpio2 = 0x0101,
397 },{ 397 },{
398 .type = CX88_VMUX_SVIDEO, 398 .type = CX88_VMUX_SVIDEO,
399 .vmux = 2, 399 .vmux = 2,
400 .gpio0 = 0x0700, 400 .gpio0 = 0x0700,
401 .gpio2 = 0x0101, 401 .gpio2 = 0x0101,
402 }}, 402 }},
403 .dvb = 1, 403 .dvb = 1,
404 }, 404 },
405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { 405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
@@ -425,27 +425,27 @@ struct cx88_board cx88_boards[] = {
425 .radio_type = UNSET, 425 .radio_type = UNSET,
426 .tuner_addr = ADDR_UNSET, 426 .tuner_addr = ADDR_UNSET,
427 .radio_addr = ADDR_UNSET, 427 .radio_addr = ADDR_UNSET,
428 .input = {{ 428 .input = {{
429 .type = CX88_VMUX_TELEVISION, 429 .type = CX88_VMUX_TELEVISION,
430 .vmux = 0, 430 .vmux = 0,
431 .gpio0 = 0x07f8, 431 .gpio0 = 0x07f8,
432 },{ 432 },{
433 .type = CX88_VMUX_DEBUG, 433 .type = CX88_VMUX_DEBUG,
434 .vmux = 0, 434 .vmux = 0,
435 .gpio0 = 0x07f9, // mono from tuner chip 435 .gpio0 = 0x07f9, // mono from tuner chip
436 },{ 436 },{
437 .type = CX88_VMUX_COMPOSITE1, 437 .type = CX88_VMUX_COMPOSITE1,
438 .vmux = 1, 438 .vmux = 1,
439 .gpio0 = 0x000007fa, 439 .gpio0 = 0x000007fa,
440 },{ 440 },{
441 .type = CX88_VMUX_SVIDEO, 441 .type = CX88_VMUX_SVIDEO,
442 .vmux = 2, 442 .vmux = 2,
443 .gpio0 = 0x000007fa, 443 .gpio0 = 0x000007fa,
444 }}, 444 }},
445 .radio = { 445 .radio = {
446 .type = CX88_RADIO, 446 .type = CX88_RADIO,
447 .gpio0 = 0x000007f8, 447 .gpio0 = 0x000007f8,
448 }, 448 },
449 }, 449 },
450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { 450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
451 .name = "DViCO FusionHDTV 3 Gold-Q", 451 .name = "DViCO FusionHDTV 3 Gold-Q",
@@ -489,28 +489,28 @@ struct cx88_board cx88_boards[] = {
489 }}, 489 }},
490 .dvb = 1, 490 .dvb = 1,
491 }, 491 },
492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = { 492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
493 .name = "Hauppauge Nova-T DVB-T", 493 .name = "Hauppauge Nova-T DVB-T",
494 .tuner_type = TUNER_ABSENT, 494 .tuner_type = TUNER_ABSENT,
495 .radio_type = UNSET, 495 .radio_type = UNSET,
496 .tuner_addr = ADDR_UNSET, 496 .tuner_addr = ADDR_UNSET,
497 .radio_addr = ADDR_UNSET, 497 .radio_addr = ADDR_UNSET,
498 .input = {{ 498 .input = {{
499 .type = CX88_VMUX_DVB, 499 .type = CX88_VMUX_DVB,
500 .vmux = 0, 500 .vmux = 0,
501 }}, 501 }},
502 .dvb = 1, 502 .dvb = 1,
503 }, 503 },
504 [CX88_BOARD_CONEXANT_DVB_T1] = { 504 [CX88_BOARD_CONEXANT_DVB_T1] = {
505 .name = "Conexant DVB-T reference design", 505 .name = "Conexant DVB-T reference design",
506 .tuner_type = TUNER_ABSENT, 506 .tuner_type = TUNER_ABSENT,
507 .radio_type = UNSET, 507 .radio_type = UNSET,
508 .tuner_addr = ADDR_UNSET, 508 .tuner_addr = ADDR_UNSET,
509 .radio_addr = ADDR_UNSET, 509 .radio_addr = ADDR_UNSET,
510 .input = {{ 510 .input = {{
511 .type = CX88_VMUX_DVB, 511 .type = CX88_VMUX_DVB,
512 .vmux = 0, 512 .vmux = 0,
513 }}, 513 }},
514 .dvb = 1, 514 .dvb = 1,
515 }, 515 },
516 [CX88_BOARD_PROVIDEO_PV259] = { 516 [CX88_BOARD_PROVIDEO_PV259] = {
@@ -543,12 +543,12 @@ struct cx88_board cx88_boards[] = {
543 .dvb = 1, 543 .dvb = 1,
544 }, 544 },
545 [CX88_BOARD_DNTV_LIVE_DVB_T] = { 545 [CX88_BOARD_DNTV_LIVE_DVB_T] = {
546 .name = "digitalnow DNTV Live! DVB-T", 546 .name = "digitalnow DNTV Live! DVB-T",
547 .tuner_type = TUNER_ABSENT, 547 .tuner_type = TUNER_ABSENT,
548 .radio_type = UNSET, 548 .radio_type = UNSET,
549 .tuner_addr = ADDR_UNSET, 549 .tuner_addr = ADDR_UNSET,
550 .radio_addr = ADDR_UNSET, 550 .radio_addr = ADDR_UNSET,
551 .input = {{ 551 .input = {{
552 .type = CX88_VMUX_COMPOSITE1, 552 .type = CX88_VMUX_COMPOSITE1,
553 .vmux = 1, 553 .vmux = 1,
554 .gpio0 = 0x00000700, 554 .gpio0 = 0x00000700,
@@ -705,44 +705,44 @@ struct cx88_board cx88_boards[] = {
705 .gpio0 = 0xbf60, 705 .gpio0 = 0xbf60,
706 }, 706 },
707 }, 707 },
708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { 708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
709 .name = "DViCO FusionHDTV 3 Gold-T", 709 .name = "DViCO FusionHDTV 3 Gold-T",
710 .tuner_type = TUNER_THOMSON_DTT7611, 710 .tuner_type = TUNER_THOMSON_DTT7611,
711 .radio_type = UNSET, 711 .radio_type = UNSET,
712 .tuner_addr = ADDR_UNSET, 712 .tuner_addr = ADDR_UNSET,
713 .radio_addr = ADDR_UNSET, 713 .radio_addr = ADDR_UNSET,
714 .input = {{ 714 .input = {{
715 .type = CX88_VMUX_TELEVISION, 715 .type = CX88_VMUX_TELEVISION,
716 .vmux = 0, 716 .vmux = 0,
717 .gpio0 = 0x97ed, 717 .gpio0 = 0x97ed,
718 },{ 718 },{
719 .type = CX88_VMUX_COMPOSITE1, 719 .type = CX88_VMUX_COMPOSITE1,
720 .vmux = 1, 720 .vmux = 1,
721 .gpio0 = 0x97e9, 721 .gpio0 = 0x97e9,
722 },{ 722 },{
723 .type = CX88_VMUX_SVIDEO, 723 .type = CX88_VMUX_SVIDEO,
724 .vmux = 2, 724 .vmux = 2,
725 .gpio0 = 0x97e9, 725 .gpio0 = 0x97e9,
726 }}, 726 }},
727 .dvb = 1, 727 .dvb = 1,
728 }, 728 },
729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = { 729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
730 .name = "ADS Tech Instant TV DVB-T PCI", 730 .name = "ADS Tech Instant TV DVB-T PCI",
731 .tuner_type = TUNER_ABSENT, 731 .tuner_type = TUNER_ABSENT,
732 .radio_type = UNSET, 732 .radio_type = UNSET,
733 .tuner_addr = ADDR_UNSET, 733 .tuner_addr = ADDR_UNSET,
734 .radio_addr = ADDR_UNSET, 734 .radio_addr = ADDR_UNSET,
735 .input = {{ 735 .input = {{
736 .type = CX88_VMUX_COMPOSITE1, 736 .type = CX88_VMUX_COMPOSITE1,
737 .vmux = 1, 737 .vmux = 1,
738 .gpio0 = 0x0700, 738 .gpio0 = 0x0700,
739 .gpio2 = 0x0101, 739 .gpio2 = 0x0101,
740 },{ 740 },{
741 .type = CX88_VMUX_SVIDEO, 741 .type = CX88_VMUX_SVIDEO,
742 .vmux = 2, 742 .vmux = 2,
743 .gpio0 = 0x0700, 743 .gpio0 = 0x0700,
744 .gpio2 = 0x0101, 744 .gpio2 = 0x0101,
745 }}, 745 }},
746 .dvb = 1, 746 .dvb = 1,
747 }, 747 },
748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = { 748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
@@ -762,20 +762,139 @@ struct cx88_board cx88_boards[] = {
762 .radio_addr = ADDR_UNSET, 762 .radio_addr = ADDR_UNSET,
763 .tda9887_conf = TDA9887_PRESENT, 763 .tda9887_conf = TDA9887_PRESENT,
764 .input = {{ 764 .input = {{
765 .type = CX88_VMUX_TELEVISION, 765 .type = CX88_VMUX_TELEVISION,
766 .vmux = 0, 766 .vmux = 0,
767 .gpio0 = 0x87fd, 767 .gpio0 = 0x87fd,
768 },{ 768 },{
769 .type = CX88_VMUX_COMPOSITE1, 769 .type = CX88_VMUX_COMPOSITE1,
770 .vmux = 1, 770 .vmux = 1,
771 .gpio0 = 0x87f9, 771 .gpio0 = 0x87f9,
772 },{ 772 },{
773 .type = CX88_VMUX_SVIDEO, 773 .type = CX88_VMUX_SVIDEO,
774 .vmux = 2, 774 .vmux = 2,
775 .gpio0 = 0x87f9, 775 .gpio0 = 0x87f9,
776 }}, 776 }},
777 .dvb = 1,
778 },
779 [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
780 .name = "AverMedia UltraTV Media Center PCI 550",
781 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
782 .radio_type = UNSET,
783 .tuner_addr = ADDR_UNSET,
784 .radio_addr = ADDR_UNSET,
785 .tda9887_conf = TDA9887_PRESENT,
786 .blackbird = 1,
787 .input = {{
788 .type = CX88_VMUX_COMPOSITE1,
789 .vmux = 0,
790 .gpio0 = 0x0000cd73,
791 },{
792 .type = CX88_VMUX_SVIDEO,
793 .vmux = 1,
794 .gpio0 = 0x0000cd73,
795 },{
796 .type = CX88_VMUX_TELEVISION,
797 .vmux = 3,
798 .gpio0 = 0x0000cdb3,
799 }},
800 .radio = {
801 .type = CX88_RADIO,
802 .vmux = 2,
803 .gpio0 = 0x0000cdf3,
804 },
805 },
806 [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = {
807 /* Alexander Wold <awold@bigfoot.com> */
808 .name = "Kworld V-Stream Xpert DVD",
809 .tuner_type = UNSET,
810 .input = {{
811 .type = CX88_VMUX_COMPOSITE1,
812 .vmux = 1,
813 .gpio0 = 0x03000000,
814 .gpio1 = 0x01000000,
815 .gpio2 = 0x02000000,
816 .gpio3 = 0x00100000,
817 },{
818 .type = CX88_VMUX_SVIDEO,
819 .vmux = 2,
820 .gpio0 = 0x03000000,
821 .gpio1 = 0x01000000,
822 .gpio2 = 0x02000000,
823 .gpio3 = 0x00100000,
824 }},
825 },
826 [CX88_BOARD_ATI_HDTVWONDER] = {
827 .name = "ATI HDTV Wonder",
828 .tuner_type = TUNER_PHILIPS_TUV1236D,
829 .radio_type = UNSET,
830 .tuner_addr = ADDR_UNSET,
831 .radio_addr = ADDR_UNSET,
832 .input = {{
833 .type = CX88_VMUX_TELEVISION,
834 .vmux = 0,
835 .gpio0 = 0x00000ff7,
836 .gpio1 = 0x000000ff,
837 .gpio2 = 0x00000001,
838 .gpio3 = 0x00000000,
839 },{
840 .type = CX88_VMUX_COMPOSITE1,
841 .vmux = 1,
842 .gpio0 = 0x00000ffe,
843 .gpio1 = 0x000000ff,
844 .gpio2 = 0x00000001,
845 .gpio3 = 0x00000000,
846 },{
847 .type = CX88_VMUX_SVIDEO,
848 .vmux = 2,
849 .gpio0 = 0x00000ffe,
850 .gpio1 = 0x000000ff,
851 .gpio2 = 0x00000001,
852 .gpio3 = 0x00000000,
853 }},
777 .dvb = 1, 854 .dvb = 1,
778 }, 855 },
856 [CX88_BOARD_WINFAST_DTV1000] = {
857 .name = "WinFast DTV1000-T",
858 .tuner_type = TUNER_ABSENT,
859 .radio_type = UNSET,
860 .tuner_addr = ADDR_UNSET,
861 .radio_addr = ADDR_UNSET,
862 .input = {{
863 .type = CX88_VMUX_DVB,
864 .vmux = 0,
865 }},
866 .dvb = 1,
867 },
868 [CX88_BOARD_AVERTV_303] = {
869 .name = "AVerTV 303 (M126)",
870 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
871 .radio_type = UNSET,
872 .tuner_addr = ADDR_UNSET,
873 .radio_addr = ADDR_UNSET,
874 .tda9887_conf = TDA9887_PRESENT,
875 .input = {{
876 .type = CX88_VMUX_TELEVISION,
877 .vmux = 0,
878 .gpio0 = 0x00ff,
879 .gpio1 = 0xe09f,
880 .gpio2 = 0x0010,
881 .gpio3 = 0x0000,
882 },{
883 .type = CX88_VMUX_COMPOSITE1,
884 .vmux = 1,
885 .gpio0 = 0x00ff,
886 .gpio1 = 0xe05f,
887 .gpio2 = 0x0010,
888 .gpio3 = 0x0000,
889 },{
890 .type = CX88_VMUX_SVIDEO,
891 .vmux = 2,
892 .gpio0 = 0x00ff,
893 .gpio1 = 0xe05f,
894 .gpio2 = 0x0010,
895 .gpio3 = 0x0000,
896 }},
897 },
779}; 898};
780const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 899const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
781 900
@@ -804,41 +923,41 @@ struct cx88_subid cx88_subids[] = {
804 .subdevice = 0x00f8, 923 .subdevice = 0x00f8,
805 .card = CX88_BOARD_ATI_WONDER_PRO, 924 .card = CX88_BOARD_ATI_WONDER_PRO,
806 },{ 925 },{
807 .subvendor = 0x107d, 926 .subvendor = 0x107d,
808 .subdevice = 0x6611, 927 .subdevice = 0x6611,
809 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 928 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
929 },{
930 .subvendor = 0x107d,
931 .subdevice = 0x6613, /* NTSC */
932 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
810 },{ 933 },{
811 .subvendor = 0x107d, 934 .subvendor = 0x107d,
812 .subdevice = 0x6613, /* NTSC */ 935 .subdevice = 0x6620,
813 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 936 .card = CX88_BOARD_WINFAST_DV2000,
937 },{
938 .subvendor = 0x107d,
939 .subdevice = 0x663b,
940 .card = CX88_BOARD_LEADTEK_PVR2000,
814 },{ 941 },{
815 .subvendor = 0x107d, 942 .subvendor = 0x107d,
816 .subdevice = 0x6620, 943 .subdevice = 0x663C,
817 .card = CX88_BOARD_WINFAST_DV2000, 944 .card = CX88_BOARD_LEADTEK_PVR2000,
818 },{ 945 },{
819 .subvendor = 0x107d,
820 .subdevice = 0x663b,
821 .card = CX88_BOARD_LEADTEK_PVR2000,
822 },{
823 .subvendor = 0x107d,
824 .subdevice = 0x663C,
825 .card = CX88_BOARD_LEADTEK_PVR2000,
826 },{
827 .subvendor = 0x1461, 946 .subvendor = 0x1461,
828 .subdevice = 0x000b, 947 .subdevice = 0x000b,
829 .card = CX88_BOARD_AVERTV_303, 948 .card = CX88_BOARD_AVERTV_STUDIO_303,
830 },{ 949 },{
831 .subvendor = 0x1462, 950 .subvendor = 0x1462,
832 .subdevice = 0x8606, 951 .subdevice = 0x8606,
833 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER, 952 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
834 },{ 953 },{
835 .subvendor = 0x10fc, 954 .subvendor = 0x10fc,
836 .subdevice = 0xd003, 955 .subdevice = 0xd003,
837 .card = CX88_BOARD_IODATA_GVVCP3PCI, 956 .card = CX88_BOARD_IODATA_GVVCP3PCI,
838 },{ 957 },{
839 .subvendor = 0x1043, 958 .subvendor = 0x1043,
840 .subdevice = 0x4823, /* with mpeg encoder */ 959 .subdevice = 0x4823, /* with mpeg encoder */
841 .card = CX88_BOARD_ASUS_PVR_416, 960 .card = CX88_BOARD_ASUS_PVR_416,
842 },{ 961 },{
843 .subvendor = 0x17de, 962 .subvendor = 0x17de,
844 .subdevice = 0x08a6, 963 .subdevice = 0x08a6,
@@ -852,43 +971,43 @@ struct cx88_subid cx88_subids[] = {
852 .subdevice = 0xd820, 971 .subdevice = 0xd820,
853 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T, 972 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
854 },{ 973 },{
855 .subvendor = 0x18AC, 974 .subvendor = 0x18ac,
856 .subdevice = 0xDB00, 975 .subdevice = 0xdb00,
857 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, 976 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
858 },{ 977 },{
859 .subvendor = 0x0070, 978 .subvendor = 0x0070,
860 .subdevice = 0x9002, 979 .subdevice = 0x9002,
861 .card = CX88_BOARD_HAUPPAUGE_DVB_T1, 980 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
862 },{ 981 },{
863 .subvendor = 0x14f1, 982 .subvendor = 0x14f1,
864 .subdevice = 0x0187, 983 .subdevice = 0x0187,
865 .card = CX88_BOARD_CONEXANT_DVB_T1, 984 .card = CX88_BOARD_CONEXANT_DVB_T1,
866 },{ 985 },{
867 .subvendor = 0x1540, 986 .subvendor = 0x1540,
868 .subdevice = 0x2580, 987 .subdevice = 0x2580,
869 .card = CX88_BOARD_PROVIDEO_PV259, 988 .card = CX88_BOARD_PROVIDEO_PV259,
870 },{ 989 },{
871 .subvendor = 0x18AC, 990 .subvendor = 0x18ac,
872 .subdevice = 0xDB10, 991 .subdevice = 0xdb10,
873 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, 992 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
874 },{ 993 },{
875 .subvendor = 0x1554, 994 .subvendor = 0x1554,
876 .subdevice = 0x4811, 995 .subdevice = 0x4811,
877 .card = CX88_BOARD_PIXELVIEW, 996 .card = CX88_BOARD_PIXELVIEW,
878 },{ 997 },{
879 .subvendor = 0x7063, 998 .subvendor = 0x7063,
880 .subdevice = 0x3000, /* HD-3000 card */ 999 .subdevice = 0x3000, /* HD-3000 card */
881 .card = CX88_BOARD_PCHDTV_HD3000, 1000 .card = CX88_BOARD_PCHDTV_HD3000,
882 },{ 1001 },{
883 .subvendor = 0x17DE, 1002 .subvendor = 0x17de,
884 .subdevice = 0xA8A6, 1003 .subdevice = 0xa8a6,
885 .card = CX88_BOARD_DNTV_LIVE_DVB_T, 1004 .card = CX88_BOARD_DNTV_LIVE_DVB_T,
886 },{ 1005 },{
887 .subvendor = 0x0070, 1006 .subvendor = 0x0070,
888 .subdevice = 0x2801, 1007 .subdevice = 0x2801,
889 .card = CX88_BOARD_HAUPPAUGE_ROSLYN, 1008 .card = CX88_BOARD_HAUPPAUGE_ROSLYN,
890 },{ 1009 },{
891 .subvendor = 0x14F1, 1010 .subvendor = 0x14f1,
892 .subdevice = 0x0342, 1011 .subdevice = 0x0342,
893 .card = CX88_BOARD_DIGITALLOGIC_MEC, 1012 .card = CX88_BOARD_DIGITALLOGIC_MEC,
894 },{ 1013 },{
@@ -899,14 +1018,30 @@ struct cx88_subid cx88_subids[] = {
899 .subvendor = 0x1421, 1018 .subvendor = 0x1421,
900 .subdevice = 0x0334, 1019 .subdevice = 0x0334,
901 .card = CX88_BOARD_ADSTECH_DVB_T_PCI, 1020 .card = CX88_BOARD_ADSTECH_DVB_T_PCI,
902 },{ 1021 },{
903 .subvendor = 0x153b, 1022 .subvendor = 0x153b,
904 .subdevice = 0x1166, 1023 .subdevice = 0x1166,
905 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, 1024 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
906 },{ 1025 },{
907 .subvendor = 0x18ac, 1026 .subvendor = 0x18ac,
908 .subdevice = 0xd500, 1027 .subdevice = 0xd500,
909 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD, 1028 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
1029 },{
1030 .subvendor = 0x1461,
1031 .subdevice = 0x8011,
1032 .card = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
1033 },{
1034 .subvendor = PCI_VENDOR_ID_ATI,
1035 .subdevice = 0xa101,
1036 .card = CX88_BOARD_ATI_HDTVWONDER,
1037 },{
1038 .subvendor = 0x107d,
1039 .subdevice = 0x665f,
1040 .card = CX88_BOARD_WINFAST_DTV1000,
1041 },{
1042 .subvendor = 0x1461,
1043 .subdevice = 0x000a,
1044 .card = CX88_BOARD_AVERTV_303,
910 }, 1045 },
911}; 1046};
912const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1047const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1108,6 +1243,19 @@ void cx88_card_setup(struct cx88_core *core)
1108 cx_clear(MO_GP0_IO, 0x00000007); 1243 cx_clear(MO_GP0_IO, 0x00000007);
1109 cx_set(MO_GP2_IO, 0x00000101); 1244 cx_set(MO_GP2_IO, 0x00000101);
1110 break; 1245 break;
1246 case CX88_BOARD_ATI_HDTVWONDER:
1247 if (0 == core->i2c_rc) {
1248 /* enable tuner */
1249 int i;
1250 u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
1251 core->i2c_client.addr = 0x0a;
1252
1253 for (i = 0; i < 5; i++)
1254 if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2))
1255 printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
1256 core->name, i);
1257 }
1258 break;
1111 } 1259 }
1112 if (cx88_boards[core->board].radio.type == CX88_RADIO) 1260 if (cx88_boards[core->board].radio.type == CX88_RADIO)
1113 core->has_radio = 1; 1261 core->has_radio = 1;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index dc5c5c1f3461..eb806af17182 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -31,7 +31,7 @@
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/videodev.h> 34#include <linux/videodev2.h>
35 35
36#include "cx88.h" 36#include "cx88.h"
37 37
@@ -153,26 +153,26 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
153 } 153 }
154 if (bpl <= sg_dma_len(sg)-offset) { 154 if (bpl <= sg_dma_len(sg)-offset) {
155 /* fits into current chunk */ 155 /* fits into current chunk */
156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); 156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
158 offset+=bpl; 158 offset+=bpl;
159 } else { 159 } else {
160 /* scanline needs to be splitted */ 160 /* scanline needs to be splitted */
161 todo = bpl; 161 todo = bpl;
162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| 162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
163 (sg_dma_len(sg)-offset)); 163 (sg_dma_len(sg)-offset));
164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
165 todo -= (sg_dma_len(sg)-offset); 165 todo -= (sg_dma_len(sg)-offset);
166 offset = 0; 166 offset = 0;
167 sg++; 167 sg++;
168 while (todo > sg_dma_len(sg)) { 168 while (todo > sg_dma_len(sg)) {
169 *(rp++)=cpu_to_le32(RISC_WRITE| 169 *(rp++)=cpu_to_le32(RISC_WRITE|
170 sg_dma_len(sg)); 170 sg_dma_len(sg));
171 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 171 *(rp++)=cpu_to_le32(sg_dma_address(sg));
172 todo -= sg_dma_len(sg); 172 todo -= sg_dma_len(sg);
173 sg++; 173 sg++;
174 } 174 }
175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); 175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
176 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 176 *(rp++)=cpu_to_le32(sg_dma_address(sg));
177 offset += todo; 177 offset += todo;
178 } 178 }
@@ -309,7 +309,7 @@ struct sram_channel cx88_sram_channels[] = {
309 .name = "video y / packed", 309 .name = "video y / packed",
310 .cmds_start = 0x180040, 310 .cmds_start = 0x180040,
311 .ctrl_start = 0x180400, 311 .ctrl_start = 0x180400,
312 .cdt = 0x180400 + 64, 312 .cdt = 0x180400 + 64,
313 .fifo_start = 0x180c00, 313 .fifo_start = 0x180c00,
314 .fifo_size = 0x002800, 314 .fifo_size = 0x002800,
315 .ptr1_reg = MO_DMA21_PTR1, 315 .ptr1_reg = MO_DMA21_PTR1,
@@ -321,7 +321,7 @@ struct sram_channel cx88_sram_channels[] = {
321 .name = "video u", 321 .name = "video u",
322 .cmds_start = 0x180080, 322 .cmds_start = 0x180080,
323 .ctrl_start = 0x1804a0, 323 .ctrl_start = 0x1804a0,
324 .cdt = 0x1804a0 + 64, 324 .cdt = 0x1804a0 + 64,
325 .fifo_start = 0x183400, 325 .fifo_start = 0x183400,
326 .fifo_size = 0x000800, 326 .fifo_size = 0x000800,
327 .ptr1_reg = MO_DMA22_PTR1, 327 .ptr1_reg = MO_DMA22_PTR1,
@@ -333,7 +333,7 @@ struct sram_channel cx88_sram_channels[] = {
333 .name = "video v", 333 .name = "video v",
334 .cmds_start = 0x1800c0, 334 .cmds_start = 0x1800c0,
335 .ctrl_start = 0x180540, 335 .ctrl_start = 0x180540,
336 .cdt = 0x180540 + 64, 336 .cdt = 0x180540 + 64,
337 .fifo_start = 0x183c00, 337 .fifo_start = 0x183c00,
338 .fifo_size = 0x000800, 338 .fifo_size = 0x000800,
339 .ptr1_reg = MO_DMA23_PTR1, 339 .ptr1_reg = MO_DMA23_PTR1,
@@ -345,7 +345,7 @@ struct sram_channel cx88_sram_channels[] = {
345 .name = "vbi", 345 .name = "vbi",
346 .cmds_start = 0x180100, 346 .cmds_start = 0x180100,
347 .ctrl_start = 0x1805e0, 347 .ctrl_start = 0x1805e0,
348 .cdt = 0x1805e0 + 64, 348 .cdt = 0x1805e0 + 64,
349 .fifo_start = 0x184400, 349 .fifo_start = 0x184400,
350 .fifo_size = 0x001000, 350 .fifo_size = 0x001000,
351 .ptr1_reg = MO_DMA24_PTR1, 351 .ptr1_reg = MO_DMA24_PTR1,
@@ -357,7 +357,7 @@ struct sram_channel cx88_sram_channels[] = {
357 .name = "audio from", 357 .name = "audio from",
358 .cmds_start = 0x180140, 358 .cmds_start = 0x180140,
359 .ctrl_start = 0x180680, 359 .ctrl_start = 0x180680,
360 .cdt = 0x180680 + 64, 360 .cdt = 0x180680 + 64,
361 .fifo_start = 0x185400, 361 .fifo_start = 0x185400,
362 .fifo_size = 0x000200, 362 .fifo_size = 0x000200,
363 .ptr1_reg = MO_DMA25_PTR1, 363 .ptr1_reg = MO_DMA25_PTR1,
@@ -369,7 +369,7 @@ struct sram_channel cx88_sram_channels[] = {
369 .name = "audio to", 369 .name = "audio to",
370 .cmds_start = 0x180180, 370 .cmds_start = 0x180180,
371 .ctrl_start = 0x180720, 371 .ctrl_start = 0x180720,
372 .cdt = 0x180680 + 64, /* same as audio IN */ 372 .cdt = 0x180680 + 64, /* same as audio IN */
373 .fifo_start = 0x185400, /* same as audio IN */ 373 .fifo_start = 0x185400, /* same as audio IN */
374 .fifo_size = 0x000200, /* same as audio IN */ 374 .fifo_size = 0x000200, /* same as audio IN */
375 .ptr1_reg = MO_DMA26_PTR1, 375 .ptr1_reg = MO_DMA26_PTR1,
@@ -431,7 +431,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
431/* ------------------------------------------------------------------ */ 431/* ------------------------------------------------------------------ */
432/* debug helper code */ 432/* debug helper code */
433 433
434int cx88_risc_decode(u32 risc) 434static int cx88_risc_decode(u32 risc)
435{ 435{
436 static char *instr[16] = { 436 static char *instr[16] = {
437 [ RISC_SYNC >> 28 ] = "sync", 437 [ RISC_SYNC >> 28 ] = "sync",
@@ -845,19 +845,19 @@ static int set_tvaudio(struct cx88_core *core)
845 return 0; 845 return 0;
846 846
847 if (V4L2_STD_PAL_BG & norm->id) { 847 if (V4L2_STD_PAL_BG & norm->id) {
848 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG; 848 core->tvaudio = WW_BG;
849 849
850 } else if (V4L2_STD_PAL_DK & norm->id) { 850 } else if (V4L2_STD_PAL_DK & norm->id) {
851 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK; 851 core->tvaudio = WW_DK;
852 852
853 } else if (V4L2_STD_PAL_I & norm->id) { 853 } else if (V4L2_STD_PAL_I & norm->id) {
854 core->tvaudio = WW_NICAM_I; 854 core->tvaudio = WW_I;
855 855
856 } else if (V4L2_STD_SECAM_L & norm->id) { 856 } else if (V4L2_STD_SECAM_L & norm->id) {
857 core->tvaudio = WW_SYSTEM_L_AM; 857 core->tvaudio = WW_L;
858 858
859 } else if (V4L2_STD_SECAM_DK & norm->id) { 859 } else if (V4L2_STD_SECAM_DK & norm->id) {
860 core->tvaudio = WW_A2_DK; 860 core->tvaudio = WW_DK;
861 861
862 } else if ((V4L2_STD_NTSC_M & norm->id) || 862 } else if ((V4L2_STD_NTSC_M & norm->id) ||
863 (V4L2_STD_PAL_M & norm->id)) { 863 (V4L2_STD_PAL_M & norm->id)) {
@@ -1137,7 +1137,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1137 if (!core->radio_addr) 1137 if (!core->radio_addr)
1138 core->radio_addr = cx88_boards[core->board].radio_addr; 1138 core->radio_addr = cx88_boards[core->board].radio_addr;
1139 1139
1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", 1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1141 core->tuner_type, core->tuner_addr<<1, 1141 core->tuner_type, core->tuner_addr<<1,
1142 core->radio_type, core->radio_addr<<1); 1142 core->radio_type, core->radio_addr<<1);
1143 1143
@@ -1146,6 +1146,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1146 /* init hardware */ 1146 /* init hardware */
1147 cx88_reset(core); 1147 cx88_reset(core);
1148 cx88_i2c_init(core,pci); 1148 cx88_i2c_init(core,pci);
1149 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
1149 cx88_card_setup(core); 1150 cx88_card_setup(core);
1150 cx88_ir_init(core,pci); 1151 cx88_ir_init(core,pci);
1151 1152
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 4334744652de..9cce91ec334b 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/file.h> 29#include <linux/file.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "cx88.h" 32#include "cx88.h"
34#include "dvb-pll.h" 33#include "dvb-pll.h"
35 34
@@ -46,6 +45,9 @@
46#ifdef HAVE_LGDT330X 45#ifdef HAVE_LGDT330X
47# include "lgdt330x.h" 46# include "lgdt330x.h"
48#endif 47#endif
48#ifdef HAVE_NXT200X
49# include "nxt200x.h"
50#endif
49 51
50MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 52MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
51MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -78,7 +80,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
78 enum v4l2_field field) 80 enum v4l2_field field)
79{ 81{
80 struct cx8802_dev *dev = q->priv_data; 82 struct cx8802_dev *dev = q->priv_data;
81 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb); 83 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
82} 84}
83 85
84static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 86static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -129,7 +131,7 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
129 static u8 reset [] = { 0x50, 0x80 }; 131 static u8 reset [] = { 0x50, 0x80 };
130 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 132 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
131 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 133 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
132 0x00, 0xFF, 0x00, 0x40, 0x40 }; 134 0x00, 0xFF, 0x00, 0x40, 0x40 };
133 static u8 dntv_extra[] = { 0xB5, 0x7A }; 135 static u8 dntv_extra[] = { 0xB5, 0x7A };
134 static u8 capt_range_cfg[] = { 0x75, 0x32 }; 136 static u8 capt_range_cfg[] = { 0x75, 0x32 };
135 137
@@ -285,6 +287,33 @@ static struct lgdt330x_config fusionhdtv_5_gold = {
285}; 287};
286#endif 288#endif
287 289
290#ifdef HAVE_NXT200X
291static int nxt200x_set_ts_param(struct dvb_frontend* fe,
292 int is_punctured)
293{
294 struct cx8802_dev *dev= fe->dvb->priv;
295 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
296 return 0;
297}
298
299static int nxt200x_set_pll_input(u8* buf, int input)
300{
301 if (input)
302 buf[3] |= 0x08;
303 else
304 buf[3] &= ~0x08;
305 return 0;
306}
307
308static struct nxt200x_config ati_hdtvwonder = {
309 .demod_address = 0x0a,
310 .pll_address = 0x61,
311 .pll_desc = &dvb_pll_tuv1236d,
312 .set_pll_input = nxt200x_set_pll_input,
313 .set_ts_params = nxt200x_set_ts_param,
314};
315#endif
316
288static int dvb_register(struct cx8802_dev *dev) 317static int dvb_register(struct cx8802_dev *dev)
289{ 318{
290 /* init struct videobuf_dvb */ 319 /* init struct videobuf_dvb */
@@ -300,6 +329,7 @@ static int dvb_register(struct cx8802_dev *dev)
300 break; 329 break;
301 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 330 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
302 case CX88_BOARD_CONEXANT_DVB_T1: 331 case CX88_BOARD_CONEXANT_DVB_T1:
332 case CX88_BOARD_WINFAST_DTV1000:
303 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 333 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
304 &dev->core->i2c_adap); 334 &dev->core->i2c_adap);
305 break; 335 break;
@@ -385,6 +415,12 @@ static int dvb_register(struct cx8802_dev *dev)
385 } 415 }
386 break; 416 break;
387#endif 417#endif
418#ifdef HAVE_NXT200X
419 case CX88_BOARD_ATI_HDTVWONDER:
420 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
421 &dev->core->i2c_adap);
422 break;
423#endif
388 default: 424 default:
389 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 425 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
390 dev->core->name); 426 dev->core->name);
@@ -403,6 +439,9 @@ static int dvb_register(struct cx8802_dev *dev)
403 /* Put the analog decoder in standby to keep it quiet */ 439 /* Put the analog decoder in standby to keep it quiet */
404 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 440 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
405 441
442 /* Put the analog decoder in standby to keep it quiet */
443 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
444
406 /* register everything */ 445 /* register everything */
407 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); 446 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
408} 447}
@@ -461,7 +500,7 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
461 500
462static void __devexit dvb_remove(struct pci_dev *pci_dev) 501static void __devexit dvb_remove(struct pci_dev *pci_dev)
463{ 502{
464 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 503 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
465 504
466 /* dvb */ 505 /* dvb */
467 videobuf_dvb_unregister(&dev->dvb); 506 videobuf_dvb_unregister(&dev->dvb);
@@ -476,8 +515,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
476 { 515 {
477 .vendor = 0x14f1, 516 .vendor = 0x14f1,
478 .device = 0x8802, 517 .device = 0x8802,
479 .subvendor = PCI_ANY_ID, 518 .subvendor = PCI_ANY_ID,
480 .subdevice = PCI_ANY_ID, 519 .subdevice = PCI_ANY_ID,
481 },{ 520 },{
482 /* --- end of list --- */ 521 /* --- end of list --- */
483 } 522 }
@@ -485,10 +524,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
485MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 524MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
486 525
487static struct pci_driver dvb_pci_driver = { 526static struct pci_driver dvb_pci_driver = {
488 .name = "cx88-dvb", 527 .name = "cx88-dvb",
489 .id_table = cx8802_pci_tbl, 528 .id_table = cx8802_pci_tbl,
490 .probe = dvb_probe, 529 .probe = dvb_probe,
491 .remove = __devexit_p(dvb_remove), 530 .remove = __devexit_p(dvb_remove),
492 .suspend = cx8802_suspend_common, 531 .suspend = cx8802_suspend_common,
493 .resume = cx8802_resume_common, 532 .resume = cx8802_resume_common,
494}; 533};
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 761cebd40dbd..9790d412f192 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -3,7 +3,7 @@
3 cx88-i2c.c -- all the i2c code is here 3 cx88-i2c.c -- all the i2c code is here
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 & Marcus Metzler (mocm@thp.uni-koeln.de) 6 & Marcus Metzler (mocm@thp.uni-koeln.de)
7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net> 7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
9 9
@@ -90,7 +90,7 @@ static int cx8800_bit_getsda(void *data)
90 90
91static int attach_inform(struct i2c_client *client) 91static int attach_inform(struct i2c_client *client)
92{ 92{
93 struct tuner_setup tun_setup; 93 struct tuner_setup tun_setup;
94 struct cx88_core *core = i2c_get_adapdata(client->adapter); 94 struct cx88_core *core = i2c_get_adapdata(client->adapter);
95 95
96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", 96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
@@ -98,7 +98,7 @@ static int attach_inform(struct i2c_client *client)
98 if (!client->driver->command) 98 if (!client->driver->command)
99 return 0; 99 return 0;
100 100
101 if (core->radio_type != UNSET) { 101 if (core->radio_type != UNSET) {
102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) { 102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
103 tun_setup.mode_mask = T_RADIO; 103 tun_setup.mode_mask = T_RADIO;
104 tun_setup.type = core->radio_type; 104 tun_setup.type = core->radio_type;
@@ -106,8 +106,8 @@ static int attach_inform(struct i2c_client *client)
106 106
107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); 107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
108 } 108 }
109 } 109 }
110 if (core->tuner_type != UNSET) { 110 if (core->tuner_type != UNSET) {
111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) { 111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
112 112
113 tun_setup.mode_mask = T_ANALOG_TV; 113 tun_setup.mode_mask = T_ANALOG_TV;
@@ -116,7 +116,7 @@ static int attach_inform(struct i2c_client *client)
116 116
117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup); 117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
118 } 118 }
119 } 119 }
120 120
121 if (core->tda9887_conf) 121 if (core->tda9887_conf)
122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); 122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
@@ -159,7 +159,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = {
159}; 159};
160 160
161static struct i2c_client cx8800_i2c_client_template = { 161static struct i2c_client cx8800_i2c_client_template = {
162 .name = "cx88xx internal", 162 .name = "cx88xx internal",
163}; 163};
164 164
165static char *i2c_devs[128] = { 165static char *i2c_devs[128] = {
@@ -202,10 +202,10 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
202 202
203 core->i2c_adap.dev.parent = &pci->dev; 203 core->i2c_adap.dev.parent = &pci->dev;
204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); 204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
205 core->i2c_algo.data = core; 205 core->i2c_algo.data = core;
206 i2c_set_adapdata(&core->i2c_adap,core); 206 i2c_set_adapdata(&core->i2c_adap,core);
207 core->i2c_adap.algo_data = &core->i2c_algo; 207 core->i2c_adap.algo_data = &core->i2c_algo;
208 core->i2c_client.adapter = &core->i2c_adap; 208 core->i2c_client.adapter = &core->i2c_adap;
209 209
210 cx8800_bit_setscl(core,1); 210 cx8800_bit_setscl(core,1);
211 cx8800_bit_setsda(core,1); 211 cx8800_bit_setsda(core,1);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index c27fe4c36f69..38b12ebaa49e 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -553,7 +553,7 @@ void cx88_ir_irq(struct cx88_core *core)
553 553
554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ 554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
555 ir_dprintk("pulse distance decoded wrong address\n"); 555 ir_dprintk("pulse distance decoded wrong address\n");
556 break; 556 break;
557 } 557 }
558 558
559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */ 559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index ee2300e1ae0b..35e6d0c2b872 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
54{ 54{
55 struct cx88_core *core = dev->core; 55 struct cx88_core *core = dev->core;
56 56
57 dprintk(0, "cx8802_start_dma %d\n", buf->vb.width); 57 dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
58 58
59 /* setup fifo + format */ 59 /* setup fifo + format */
60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -158,7 +158,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
158 158
159/* ------------------------------------------------------------------ */ 159/* ------------------------------------------------------------------ */
160 160
161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) 161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
162 enum v4l2_field field)
162{ 163{
163 int size = dev->ts_packet_size * dev->ts_packet_count; 164 int size = dev->ts_packet_size * dev->ts_packet_count;
164 int rc; 165 int rc;
@@ -171,7 +172,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
171 buf->vb.width = dev->ts_packet_size; 172 buf->vb.width = dev->ts_packet_size;
172 buf->vb.height = dev->ts_packet_count; 173 buf->vb.height = dev->ts_packet_count;
173 buf->vb.size = size; 174 buf->vb.size = size;
174 buf->vb.field = V4L2_FIELD_TOP; 175 buf->vb.field = field /*V4L2_FIELD_TOP*/;
175 176
176 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) 177 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
177 goto fail; 178 goto fail;
@@ -315,14 +316,14 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
315 spin_unlock(&dev->slock); 316 spin_unlock(&dev->slock);
316 } 317 }
317 318
318 /* other general errors */ 319 /* other general errors */
319 if (status & 0x1f0100) { 320 if (status & 0x1f0100) {
320 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); 321 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
321 spin_lock(&dev->slock); 322 spin_lock(&dev->slock);
322 cx8802_stop_dma(dev); 323 cx8802_stop_dma(dev);
323 cx8802_restart_queue(dev,&dev->mpegq); 324 cx8802_restart_queue(dev,&dev->mpegq);
324 spin_unlock(&dev->slock); 325 spin_unlock(&dev->slock);
325 } 326 }
326} 327}
327 328
328#define MAX_IRQ_LOOP 10 329#define MAX_IRQ_LOOP 10
@@ -378,8 +379,8 @@ int cx8802_init_common(struct cx8802_dev *dev)
378 } 379 }
379 380
380 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); 381 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
381 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); 382 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
382 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " 383 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
383 "latency: %d, mmio: 0x%lx\n", dev->core->name, 384 "latency: %d, mmio: 0x%lx\n", dev->core->name,
384 pci_name(dev->pci), dev->pci_rev, dev->pci->irq, 385 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
385 dev->pci_lat,pci_resource_start(dev->pci,0)); 386 dev->pci_lat,pci_resource_start(dev->pci,0));
@@ -429,7 +430,7 @@ void cx8802_fini_common(struct cx8802_dev *dev)
429 430
430int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) 431int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
431{ 432{
432 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 433 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
433 struct cx88_core *core = dev->core; 434 struct cx88_core *core = dev->core;
434 435
435 /* stop mpeg dma */ 436 /* stop mpeg dma */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 0a3a62fc9bbb..d3bf5b17b1d4 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -3,9 +3,9 @@
3 cx88x-hw.h - CX2388x register offsets 3 cx88x-hw.h - CX2388x register offsets
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 2001 Michael Eskin 6 2001 Michael Eskin
7 2002 Yurij Sysoev <yurij@naturesoft.net> 7 2002 Yurij Sysoev <yurij@naturesoft.net>
8 2003 Gerd Knorr <kraxel@bytesex.org> 8 2003 Gerd Knorr <kraxel@bytesex.org>
9 9
10 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
@@ -728,13 +728,13 @@
728#define ColorFormatGamma 0x1000 728#define ColorFormatGamma 0x1000
729 729
730#define Interlaced 0x1 730#define Interlaced 0x1
731#define NonInterlaced 0x0 731#define NonInterlaced 0x0
732 732
733#define FieldEven 0x1 733#define FieldEven 0x1
734#define FieldOdd 0x0 734#define FieldOdd 0x0
735 735
736#define TGReadWriteMode 0x0 736#define TGReadWriteMode 0x0
737#define TGEnableMode 0x1 737#define TGEnableMode 0x1
738 738
739#define DV_CbAlign 0x0 739#define DV_CbAlign 0x0
740#define DV_Y0Align 0x1 740#define DV_Y0Align 0x1
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 2765acee0285..6d9bec1c583b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -57,39 +57,38 @@
57#include "cx88.h" 57#include "cx88.h"
58 58
59static unsigned int audio_debug = 0; 59static unsigned int audio_debug = 0;
60module_param(audio_debug,int,0644); 60module_param(audio_debug, int, 0644);
61MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]"); 61MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]");
62 62
63#define dprintk(fmt, arg...) if (audio_debug) \ 63#define dprintk(fmt, arg...) if (audio_debug) \
64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) 64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
65 65
66/* ----------------------------------------------------------- */ 66/* ----------------------------------------------------------- */
67 67
68static char *aud_ctl_names[64] = 68static char *aud_ctl_names[64] = {
69{ 69 [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO",
70 [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO", 70 [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO",
71 [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO", 71 [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP",
72 [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP", 72 [EN_BTSC_AUTO_STEREO] = "BTSC_AUTO_STEREO",
73 [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO", 73 [EN_BTSC_AUTO_SAP] = "BTSC_AUTO_SAP",
74 [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP", 74 [EN_A2_FORCE_MONO1] = "A2_FORCE_MONO1",
75 [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1", 75 [EN_A2_FORCE_MONO2] = "A2_FORCE_MONO2",
76 [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2", 76 [EN_A2_FORCE_STEREO] = "A2_FORCE_STEREO",
77 [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO", 77 [EN_A2_AUTO_MONO2] = "A2_AUTO_MONO2",
78 [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2", 78 [EN_A2_AUTO_STEREO] = "A2_AUTO_STEREO",
79 [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO", 79 [EN_EIAJ_FORCE_MONO1] = "EIAJ_FORCE_MONO1",
80 [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1", 80 [EN_EIAJ_FORCE_MONO2] = "EIAJ_FORCE_MONO2",
81 [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2", 81 [EN_EIAJ_FORCE_STEREO] = "EIAJ_FORCE_STEREO",
82 [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO", 82 [EN_EIAJ_AUTO_MONO2] = "EIAJ_AUTO_MONO2",
83 [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2", 83 [EN_EIAJ_AUTO_STEREO] = "EIAJ_AUTO_STEREO",
84 [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO", 84 [EN_NICAM_FORCE_MONO1] = "NICAM_FORCE_MONO1",
85 [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1", 85 [EN_NICAM_FORCE_MONO2] = "NICAM_FORCE_MONO2",
86 [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2", 86 [EN_NICAM_FORCE_STEREO] = "NICAM_FORCE_STEREO",
87 [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO", 87 [EN_NICAM_AUTO_MONO2] = "NICAM_AUTO_MONO2",
88 [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2", 88 [EN_NICAM_AUTO_STEREO] = "NICAM_AUTO_STEREO",
89 [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO", 89 [EN_FMRADIO_FORCE_MONO] = "FMRADIO_FORCE_MONO",
90 [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO", 90 [EN_FMRADIO_FORCE_STEREO] = "FMRADIO_FORCE_STEREO",
91 [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO", 91 [EN_FMRADIO_AUTO_STEREO] = "FMRADIO_AUTO_STEREO",
92 [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
93}; 92};
94 93
95struct rlist { 94struct rlist {
@@ -97,8 +96,7 @@ struct rlist {
97 u32 val; 96 u32 val;
98}; 97};
99 98
100static void set_audio_registers(struct cx88_core *core, 99static void set_audio_registers(struct cx88_core *core, const struct rlist *l)
101 const struct rlist *l)
102{ 100{
103 int i; 101 int i;
104 102
@@ -119,17 +117,18 @@ static void set_audio_registers(struct cx88_core *core,
119 } 117 }
120} 118}
121 119
122static void set_audio_start(struct cx88_core *core, 120static void set_audio_start(struct cx88_core *core, u32 mode)
123 u32 mode)
124{ 121{
125 // mute 122 // mute
126 cx_write(AUD_VOL_CTL, (1 << 6)); 123 cx_write(AUD_VOL_CTL, (1 << 6));
127 124
128 // start programming 125 // start programming
129 cx_write(AUD_CTL, 0x0000); 126 cx_write(MO_AUD_DMACNTRL, 0x0000);
130 cx_write(AUD_INIT, mode); 127 msleep(100);
131 cx_write(AUD_INIT_LD, 0x0001); 128 //cx_write(AUD_CTL, 0x0000);
132 cx_write(AUD_SOFT_RESET, 0x0001); 129 cx_write(AUD_INIT, mode);
130 cx_write(AUD_INIT_LD, 0x0001);
131 cx_write(AUD_SOFT_RESET, 0x0001);
133} 132}
134 133
135static void set_audio_finish(struct cx88_core *core, u32 ctl) 134static void set_audio_finish(struct cx88_core *core, u32 ctl)
@@ -148,12 +147,13 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
148 cx_write(AUD_I2SCNTL, 0); 147 cx_write(AUD_I2SCNTL, 0);
149 //cx_write(AUD_APB_IN_RATE_ADJ, 0); 148 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 } else { 149 } else {
151 ctl |= EN_DAC_ENABLE; 150 ctl |= EN_DAC_ENABLE;
152 cx_write(AUD_CTL, ctl); 151 cx_write(AUD_CTL, ctl);
153 } 152 }
154 153
155 /* finish programming */ 154 /* finish programming */
156 cx_write(AUD_SOFT_RESET, 0x0000); 155 cx_write(AUD_SOFT_RESET, 0x0000);
156 cx_write(MO_AUD_DMACNTRL, 0x0003);
157 157
158 /* unmute */ 158 /* unmute */
159 volume = cx_sread(SHADOW_AUD_VOL_CTL); 159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
@@ -162,486 +162,463 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
162 162
163/* ----------------------------------------------------------- */ 163/* ----------------------------------------------------------- */
164 164
165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode) 165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap,
166 u32 mode)
166{ 167{
167 static const struct rlist btsc[] = { 168 static const struct rlist btsc[] = {
168 { AUD_AFE_12DB_EN, 0x00000001 }, 169 {AUD_AFE_12DB_EN, 0x00000001},
169 { AUD_OUT1_SEL, 0x00000013 }, 170 {AUD_OUT1_SEL, 0x00000013},
170 { AUD_OUT1_SHIFT, 0x00000000 }, 171 {AUD_OUT1_SHIFT, 0x00000000},
171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, 172 {AUD_POLY0_DDS_CONSTANT, 0x0012010c},
172 { AUD_DMD_RA_DDS, 0x00c3e7aa }, 173 {AUD_DMD_RA_DDS, 0x00c3e7aa},
173 { AUD_DBX_IN_GAIN, 0x00004734 }, 174 {AUD_DBX_IN_GAIN, 0x00004734},
174 { AUD_DBX_WBE_GAIN, 0x00004640 }, 175 {AUD_DBX_WBE_GAIN, 0x00004640},
175 { AUD_DBX_SE_GAIN, 0x00008d31 }, 176 {AUD_DBX_SE_GAIN, 0x00008d31},
176 { AUD_DCOC_0_SRC, 0x0000001a }, 177 {AUD_DCOC_0_SRC, 0x0000001a},
177 { AUD_IIR1_4_SEL, 0x00000021 }, 178 {AUD_IIR1_4_SEL, 0x00000021},
178 { AUD_DCOC_PASS_IN, 0x00000003 }, 179 {AUD_DCOC_PASS_IN, 0x00000003},
179 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 180 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
180 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 181 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
181 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 182 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
182 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 183 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
183 { AUD_DN0_FREQ, 0x0000283b }, 184 {AUD_DN0_FREQ, 0x0000283b},
184 { AUD_DN2_SRC_SEL, 0x00000008 }, 185 {AUD_DN2_SRC_SEL, 0x00000008},
185 { AUD_DN2_FREQ, 0x00003000 }, 186 {AUD_DN2_FREQ, 0x00003000},
186 { AUD_DN2_AFC, 0x00000002 }, 187 {AUD_DN2_AFC, 0x00000002},
187 { AUD_DN2_SHFT, 0x00000000 }, 188 {AUD_DN2_SHFT, 0x00000000},
188 { AUD_IIR2_2_SEL, 0x00000020 }, 189 {AUD_IIR2_2_SEL, 0x00000020},
189 { AUD_IIR2_2_SHIFT, 0x00000000 }, 190 {AUD_IIR2_2_SHIFT, 0x00000000},
190 { AUD_IIR2_3_SEL, 0x0000001f }, 191 {AUD_IIR2_3_SEL, 0x0000001f},
191 { AUD_IIR2_3_SHIFT, 0x00000000 }, 192 {AUD_IIR2_3_SHIFT, 0x00000000},
192 { AUD_CRDC1_SRC_SEL, 0x000003ce }, 193 {AUD_CRDC1_SRC_SEL, 0x000003ce},
193 { AUD_CRDC1_SHIFT, 0x00000000 }, 194 {AUD_CRDC1_SHIFT, 0x00000000},
194 { AUD_CORDIC_SHIFT_1, 0x00000007 }, 195 {AUD_CORDIC_SHIFT_1, 0x00000007},
195 { AUD_DCOC_1_SRC, 0x0000001b }, 196 {AUD_DCOC_1_SRC, 0x0000001b},
196 { AUD_DCOC1_SHIFT, 0x00000000 }, 197 {AUD_DCOC1_SHIFT, 0x00000000},
197 { AUD_RDSI_SEL, 0x00000008 }, 198 {AUD_RDSI_SEL, 0x00000008},
198 { AUD_RDSQ_SEL, 0x00000008 }, 199 {AUD_RDSQ_SEL, 0x00000008},
199 { AUD_RDSI_SHIFT, 0x00000000 }, 200 {AUD_RDSI_SHIFT, 0x00000000},
200 { AUD_RDSQ_SHIFT, 0x00000000 }, 201 {AUD_RDSQ_SHIFT, 0x00000000},
201 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 202 {AUD_POLYPH80SCALEFAC, 0x00000003},
202 { /* end of list */ }, 203 { /* end of list */ },
203 }; 204 };
204 static const struct rlist btsc_sap[] = { 205 static const struct rlist btsc_sap[] = {
205 { AUD_AFE_12DB_EN, 0x00000001 }, 206 {AUD_AFE_12DB_EN, 0x00000001},
206 { AUD_DBX_IN_GAIN, 0x00007200 }, 207 {AUD_DBX_IN_GAIN, 0x00007200},
207 { AUD_DBX_WBE_GAIN, 0x00006200 }, 208 {AUD_DBX_WBE_GAIN, 0x00006200},
208 { AUD_DBX_SE_GAIN, 0x00006200 }, 209 {AUD_DBX_SE_GAIN, 0x00006200},
209 { AUD_IIR1_1_SEL, 0x00000000 }, 210 {AUD_IIR1_1_SEL, 0x00000000},
210 { AUD_IIR1_3_SEL, 0x00000001 }, 211 {AUD_IIR1_3_SEL, 0x00000001},
211 { AUD_DN1_SRC_SEL, 0x00000007 }, 212 {AUD_DN1_SRC_SEL, 0x00000007},
212 { AUD_IIR1_4_SHIFT, 0x00000006 }, 213 {AUD_IIR1_4_SHIFT, 0x00000006},
213 { AUD_IIR2_1_SHIFT, 0x00000000 }, 214 {AUD_IIR2_1_SHIFT, 0x00000000},
214 { AUD_IIR2_2_SHIFT, 0x00000000 }, 215 {AUD_IIR2_2_SHIFT, 0x00000000},
215 { AUD_IIR3_0_SHIFT, 0x00000000 }, 216 {AUD_IIR3_0_SHIFT, 0x00000000},
216 { AUD_IIR3_1_SHIFT, 0x00000000 }, 217 {AUD_IIR3_1_SHIFT, 0x00000000},
217 { AUD_IIR3_0_SEL, 0x0000000d }, 218 {AUD_IIR3_0_SEL, 0x0000000d},
218 { AUD_IIR3_1_SEL, 0x0000000e }, 219 {AUD_IIR3_1_SEL, 0x0000000e},
219 { AUD_DEEMPH1_SRC_SEL, 0x00000014 }, 220 {AUD_DEEMPH1_SRC_SEL, 0x00000014},
220 { AUD_DEEMPH1_SHIFT, 0x00000000 }, 221 {AUD_DEEMPH1_SHIFT, 0x00000000},
221 { AUD_DEEMPH1_G0, 0x00004000 }, 222 {AUD_DEEMPH1_G0, 0x00004000},
222 { AUD_DEEMPH1_A0, 0x00000000 }, 223 {AUD_DEEMPH1_A0, 0x00000000},
223 { AUD_DEEMPH1_B0, 0x00000000 }, 224 {AUD_DEEMPH1_B0, 0x00000000},
224 { AUD_DEEMPH1_A1, 0x00000000 }, 225 {AUD_DEEMPH1_A1, 0x00000000},
225 { AUD_DEEMPH1_B1, 0x00000000 }, 226 {AUD_DEEMPH1_B1, 0x00000000},
226 { AUD_OUT0_SEL, 0x0000003f }, 227 {AUD_OUT0_SEL, 0x0000003f},
227 { AUD_OUT1_SEL, 0x0000003f }, 228 {AUD_OUT1_SEL, 0x0000003f},
228 { AUD_DN1_AFC, 0x00000002 }, 229 {AUD_DN1_AFC, 0x00000002},
229 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 230 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
230 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 231 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
231 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 232 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
232 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 233 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
233 { AUD_IIR1_0_SEL, 0x0000001d }, 234 {AUD_IIR1_0_SEL, 0x0000001d},
234 { AUD_IIR1_2_SEL, 0x0000001e }, 235 {AUD_IIR1_2_SEL, 0x0000001e},
235 { AUD_IIR2_1_SEL, 0x00000002 }, 236 {AUD_IIR2_1_SEL, 0x00000002},
236 { AUD_IIR2_2_SEL, 0x00000004 }, 237 {AUD_IIR2_2_SEL, 0x00000004},
237 { AUD_IIR3_2_SEL, 0x0000000f }, 238 {AUD_IIR3_2_SEL, 0x0000000f},
238 { AUD_DCOC2_SHIFT, 0x00000001 }, 239 {AUD_DCOC2_SHIFT, 0x00000001},
239 { AUD_IIR3_2_SHIFT, 0x00000001 }, 240 {AUD_IIR3_2_SHIFT, 0x00000001},
240 { AUD_DEEMPH0_SRC_SEL, 0x00000014 }, 241 {AUD_DEEMPH0_SRC_SEL, 0x00000014},
241 { AUD_CORDIC_SHIFT_1, 0x00000006 }, 242 {AUD_CORDIC_SHIFT_1, 0x00000006},
242 { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 }, 243 {AUD_POLY0_DDS_CONSTANT, 0x000e4db2},
243 { AUD_DMD_RA_DDS, 0x00f696e6 }, 244 {AUD_DMD_RA_DDS, 0x00f696e6},
244 { AUD_IIR2_3_SEL, 0x00000025 }, 245 {AUD_IIR2_3_SEL, 0x00000025},
245 { AUD_IIR1_4_SEL, 0x00000021 }, 246 {AUD_IIR1_4_SEL, 0x00000021},
246 { AUD_DN1_FREQ, 0x0000c965 }, 247 {AUD_DN1_FREQ, 0x0000c965},
247 { AUD_DCOC_PASS_IN, 0x00000003 }, 248 {AUD_DCOC_PASS_IN, 0x00000003},
248 { AUD_DCOC_0_SRC, 0x0000001a }, 249 {AUD_DCOC_0_SRC, 0x0000001a},
249 { AUD_DCOC_1_SRC, 0x0000001b }, 250 {AUD_DCOC_1_SRC, 0x0000001b},
250 { AUD_DCOC1_SHIFT, 0x00000000 }, 251 {AUD_DCOC1_SHIFT, 0x00000000},
251 { AUD_RDSI_SEL, 0x00000009 }, 252 {AUD_RDSI_SEL, 0x00000009},
252 { AUD_RDSQ_SEL, 0x00000009 }, 253 {AUD_RDSQ_SEL, 0x00000009},
253 { AUD_RDSI_SHIFT, 0x00000000 }, 254 {AUD_RDSI_SHIFT, 0x00000000},
254 { AUD_RDSQ_SHIFT, 0x00000000 }, 255 {AUD_RDSQ_SHIFT, 0x00000000},
255 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 256 {AUD_POLYPH80SCALEFAC, 0x00000003},
256 { /* end of list */ }, 257 { /* end of list */ },
257 }; 258 };
258 259
259 mode |= EN_FMRADIO_EN_RDS; 260 mode |= EN_FMRADIO_EN_RDS;
260 261
261 if (sap) { 262 if (sap) {
262 dprintk("%s SAP (status: unknown)\n",__FUNCTION__); 263 dprintk("%s SAP (status: unknown)\n", __FUNCTION__);
263 set_audio_start(core, SEL_SAP); 264 set_audio_start(core, SEL_SAP);
264 set_audio_registers(core, btsc_sap); 265 set_audio_registers(core, btsc_sap);
265 set_audio_finish(core, mode); 266 set_audio_finish(core, mode);
266 } else { 267 } else {
267 dprintk("%s (status: known-good)\n",__FUNCTION__); 268 dprintk("%s (status: known-good)\n", __FUNCTION__);
268 set_audio_start(core, SEL_BTSC); 269 set_audio_start(core, SEL_BTSC);
269 set_audio_registers(core, btsc); 270 set_audio_registers(core, btsc);
270 set_audio_finish(core, mode); 271 set_audio_finish(core, mode);
271 } 272 }
272} 273}
273 274
274 275static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
275static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
276{ 276{
277 /* This is probably weird.. 277 static const struct rlist nicam_l[] = {
278 * Let's operate and find out. */ 278 {AUD_AFE_12DB_EN, 0x00000001},
279 279 {AUD_RATE_ADJ1, 0x00000060},
280 static const struct rlist nicam_l_mono[] = { 280 {AUD_RATE_ADJ2, 0x000000F9},
281 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 281 {AUD_RATE_ADJ3, 0x000001CC},
282 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 282 {AUD_RATE_ADJ4, 0x000002B3},
283 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 283 {AUD_RATE_ADJ5, 0x00000726},
284 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 284 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
285 285 {AUD_DEEMPHDENOM2_R, 0x00000000},
286 { AUD_PDF_DDS_CNST_BYTE2, 0x48 }, 286 {AUD_ERRLOGPERIOD_R, 0x00000064},
287 { AUD_PDF_DDS_CNST_BYTE1, 0x3D }, 287 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
288 { AUD_QAM_MODE, 0x00 }, 288 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
289 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 }, 289 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
290 { AUD_PHACC_FREQ_8MSB, 0x3a }, 290 {AUD_POLYPH80SCALEFAC, 0x00000003},
291 { AUD_PHACC_FREQ_8LSB, 0x4a }, 291 {AUD_DMD_RA_DDS, 0x00C00000},
292 292 {AUD_PLL_INT, 0x0000001E},
293 { AUD_DEEMPHGAIN_R, 0x6680 }, 293 {AUD_PLL_DDS, 0x00000000},
294 { AUD_DEEMPHNUMER1_R, 0x353DE }, 294 {AUD_PLL_FRAC, 0x0000E542},
295 { AUD_DEEMPHNUMER2_R, 0x1B1 }, 295 {AUD_START_TIMER, 0x00000000},
296 { AUD_DEEMPHDENOM1_R, 0x0F3D0 }, 296 {AUD_DEEMPHNUMER1_R, 0x000353DE},
297 { AUD_DEEMPHDENOM2_R, 0x0 }, 297 {AUD_DEEMPHNUMER2_R, 0x000001B1},
298 { AUD_FM_MODE_ENABLE, 0x7 }, 298 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
299 { AUD_POLYPH80SCALEFAC, 0x3 }, 299 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
300 { AUD_AFE_12DB_EN, 0x1 }, 300 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
301 { AAGC_GAIN, 0x0 }, 301 {AUD_QAM_MODE, 0x05},
302 { AAGC_HYST, 0x18 }, 302 {AUD_PHACC_FREQ_8MSB, 0x34},
303 { AAGC_DEF, 0x20 }, 303 {AUD_PHACC_FREQ_8LSB, 0x4C},
304 { AUD_DN0_FREQ, 0x0 }, 304 {AUD_DEEMPHGAIN_R, 0x00006680},
305 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 }, 305 {AUD_RATE_THRES_DMD, 0x000000C0},
306 { AUD_DCOC_0_SRC, 0x21 },
307 { AUD_IIR1_0_SEL, 0x0 },
308 { AUD_IIR1_0_SHIFT, 0x7 },
309 { AUD_IIR1_1_SEL, 0x2 },
310 { AUD_IIR1_1_SHIFT, 0x0 },
311 { AUD_DCOC_1_SRC, 0x3 },
312 { AUD_DCOC1_SHIFT, 0x0 },
313 { AUD_DCOC_PASS_IN, 0x0 },
314 { AUD_IIR1_2_SEL, 0x23 },
315 { AUD_IIR1_2_SHIFT, 0x0 },
316 { AUD_IIR1_3_SEL, 0x4 },
317 { AUD_IIR1_3_SHIFT, 0x7 },
318 { AUD_IIR1_4_SEL, 0x5 },
319 { AUD_IIR1_4_SHIFT, 0x7 },
320 { AUD_IIR3_0_SEL, 0x7 },
321 { AUD_IIR3_0_SHIFT, 0x0 },
322 { AUD_DEEMPH0_SRC_SEL, 0x11 },
323 { AUD_DEEMPH0_SHIFT, 0x0 },
324 { AUD_DEEMPH0_G0, 0x7000 },
325 { AUD_DEEMPH0_A0, 0x0 },
326 { AUD_DEEMPH0_B0, 0x0 },
327 { AUD_DEEMPH0_A1, 0x0 },
328 { AUD_DEEMPH0_B1, 0x0 },
329 { AUD_DEEMPH1_SRC_SEL, 0x11 },
330 { AUD_DEEMPH1_SHIFT, 0x0 },
331 { AUD_DEEMPH1_G0, 0x7000 },
332 { AUD_DEEMPH1_A0, 0x0 },
333 { AUD_DEEMPH1_B0, 0x0 },
334 { AUD_DEEMPH1_A1, 0x0 },
335 { AUD_DEEMPH1_B1, 0x0 },
336 { AUD_OUT0_SEL, 0x3F },
337 { AUD_OUT1_SEL, 0x3F },
338 { AUD_DMD_RA_DDS, 0x0F5C285 },
339 { AUD_PLL_INT, 0x1E },
340 { AUD_PLL_DDS, 0x0 },
341 { AUD_PLL_FRAC, 0x0E542 },
342
343 // setup QAM registers
344 { AUD_RATE_ADJ1, 0x00000100 },
345 { AUD_RATE_ADJ2, 0x00000200 },
346 { AUD_RATE_ADJ3, 0x00000300 },
347 { AUD_RATE_ADJ4, 0x00000400 },
348 { AUD_RATE_ADJ5, 0x00000500 },
349 { AUD_RATE_THRES_DMD, 0x000000C0 },
350 { /* end of list */ }, 306 { /* end of list */ },
351 }; 307 };
352 308
353 static const struct rlist nicam_l[] = { 309 static const struct rlist nicam_bgdki_common[] = {
354 // setup QAM registers 310 {AUD_AFE_12DB_EN, 0x00000001},
355 { AUD_RATE_ADJ1, 0x00000060 }, 311 {AUD_RATE_ADJ1, 0x00000010},
356 { AUD_RATE_ADJ2, 0x000000F9 }, 312 {AUD_RATE_ADJ2, 0x00000040},
357 { AUD_RATE_ADJ3, 0x000001CC }, 313 {AUD_RATE_ADJ3, 0x00000100},
358 { AUD_RATE_ADJ4, 0x000002B3 }, 314 {AUD_RATE_ADJ4, 0x00000400},
359 { AUD_RATE_ADJ5, 0x00000726 }, 315 {AUD_RATE_ADJ5, 0x00001000},
360 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 }, 316 //{ AUD_DMD_RA_DDS, 0x00c0d5ce },
361 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 317 {AUD_ERRLOGPERIOD_R, 0x00000fff},
362 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 318 {AUD_ERRINTRPTTHSHLD1_R, 0x000003ff},
363 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 319 {AUD_ERRINTRPTTHSHLD2_R, 0x000000ff},
364 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 320 {AUD_ERRINTRPTTHSHLD3_R, 0x0000003f},
365 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 321 {AUD_POLYPH80SCALEFAC, 0x00000003},
366 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 322 {AUD_DEEMPHGAIN_R, 0x000023c2},
367 { AUD_DMD_RA_DDS, 0x00C00000 }, 323 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
368 { AUD_PLL_INT, 0x0000001E }, 324 {AUD_DEEMPHNUMER2_R, 0x0003023e},
369 { AUD_PLL_DDS, 0x00000000 }, 325 {AUD_DEEMPHDENOM1_R, 0x0000f3d0},
370 { AUD_PLL_FRAC, 0x0000E542 }, 326 {AUD_DEEMPHDENOM2_R, 0x00000000},
371 { AUD_START_TIMER, 0x00000000 }, 327 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
372 { AUD_DEEMPHNUMER1_R, 0x000353DE }, 328 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
373 { AUD_DEEMPHNUMER2_R, 0x000001B1 }, 329 {AUD_QAM_MODE, 0x05},
374 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
375 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
376 { AUD_QAM_MODE, 0x05 },
377 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
378 { AUD_PHACC_FREQ_8MSB, 0x34 },
379 { AUD_PHACC_FREQ_8LSB, 0x4C },
380 { AUD_DEEMPHGAIN_R, 0x00006680 },
381 { AUD_RATE_THRES_DMD, 0x000000C0 },
382 { /* end of list */ }, 330 { /* end of list */ },
383 } ; 331 };
384 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
385
386 if (!stereo) {
387 /* AM Mono */
388 set_audio_start(core, SEL_A2);
389 set_audio_registers(core, nicam_l_mono);
390 set_audio_finish(core, EN_A2_FORCE_MONO1);
391 } else {
392 /* Nicam Stereo */
393 set_audio_start(core, SEL_NICAM);
394 set_audio_registers(core, nicam_l);
395 set_audio_finish(core, 0x1924); /* FIXME */
396 }
397}
398 332
399static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) 333 static const struct rlist nicam_i[] = {
400{ 334 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
401 static const struct rlist pal_i_fm_mono[] = { 335 {AUD_PHACC_FREQ_8MSB, 0x3a},
402 {AUD_ERRLOGPERIOD_R, 0x00000064}, 336 {AUD_PHACC_FREQ_8LSB, 0x93},
403 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 337 { /* end of list */ },
404 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
405 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
406 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
407 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
408 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
409 {AUD_QAM_MODE, 0x05},
410 {AUD_PHACC_FREQ_8MSB, 0x3a},
411 {AUD_PHACC_FREQ_8LSB, 0x93},
412 {AUD_DMD_RA_DDS, 0x002a4f2f},
413 {AUD_PLL_INT, 0x0000001e},
414 {AUD_PLL_DDS, 0x00000004},
415 {AUD_PLL_FRAC, 0x0000e542},
416 {AUD_RATE_ADJ1, 0x00000100},
417 {AUD_RATE_ADJ2, 0x00000200},
418 {AUD_RATE_ADJ3, 0x00000300},
419 {AUD_RATE_ADJ4, 0x00000400},
420 {AUD_RATE_ADJ5, 0x00000500},
421 {AUD_THR_FR, 0x00000000},
422 {AUD_PILOT_BQD_1_K0, 0x0000755b},
423 {AUD_PILOT_BQD_1_K1, 0x00551340},
424 {AUD_PILOT_BQD_1_K2, 0x006d30be},
425 {AUD_PILOT_BQD_1_K3, 0xffd394af},
426 {AUD_PILOT_BQD_1_K4, 0x00400000},
427 {AUD_PILOT_BQD_2_K0, 0x00040000},
428 {AUD_PILOT_BQD_2_K1, 0x002a4841},
429 {AUD_PILOT_BQD_2_K2, 0x00400000},
430 {AUD_PILOT_BQD_2_K3, 0x00000000},
431 {AUD_PILOT_BQD_2_K4, 0x00000000},
432 {AUD_MODE_CHG_TIMER, 0x00000060},
433 {AUD_AFE_12DB_EN, 0x00000001},
434 {AAGC_HYST, 0x0000000a},
435 {AUD_CORDIC_SHIFT_0, 0x00000007},
436 {AUD_CORDIC_SHIFT_1, 0x00000007},
437 {AUD_C1_UP_THR, 0x00007000},
438 {AUD_C1_LO_THR, 0x00005400},
439 {AUD_C2_UP_THR, 0x00005400},
440 {AUD_C2_LO_THR, 0x00003000},
441 {AUD_DCOC_0_SRC, 0x0000001a},
442 {AUD_DCOC0_SHIFT, 0x00000000},
443 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
444 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
445 {AUD_DCOC_PASS_IN, 0x00000003},
446 {AUD_IIR3_0_SEL, 0x00000021},
447 {AUD_DN2_AFC, 0x00000002},
448 {AUD_DCOC_1_SRC, 0x0000001b},
449 {AUD_DCOC1_SHIFT, 0x00000000},
450 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
451 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
452 {AUD_IIR3_1_SEL, 0x00000023},
453 {AUD_DN0_FREQ, 0x000035a3},
454 {AUD_DN2_FREQ, 0x000029c7},
455 {AUD_CRDC0_SRC_SEL, 0x00000511},
456 {AUD_IIR1_0_SEL, 0x00000001},
457 {AUD_IIR1_1_SEL, 0x00000000},
458 {AUD_IIR3_2_SEL, 0x00000003},
459 {AUD_IIR3_2_SHIFT, 0x00000000},
460 {AUD_IIR3_0_SEL, 0x00000002},
461 {AUD_IIR2_0_SEL, 0x00000021},
462 {AUD_IIR2_0_SHIFT, 0x00000002},
463 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
464 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
465 {AUD_POLYPH80SCALEFAC, 0x00000001},
466 {AUD_START_TIMER, 0x00000000},
467 { /* end of list */ },
468 };
469
470 static const struct rlist pal_i_nicam[] = {
471 { AUD_RATE_ADJ1, 0x00000010 },
472 { AUD_RATE_ADJ2, 0x00000040 },
473 { AUD_RATE_ADJ3, 0x00000100 },
474 { AUD_RATE_ADJ4, 0x00000400 },
475 { AUD_RATE_ADJ5, 0x00001000 },
476 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
477 { AUD_DEEMPHGAIN_R, 0x000023c2 },
478 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
479 { AUD_DEEMPHNUMER2_R, 0x0003023e },
480 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
481 { AUD_DEEMPHDENOM2_R, 0x00000000 },
482 { AUD_DEEMPHDENOM2_R, 0x00000000 },
483 { AUD_ERRLOGPERIOD_R, 0x00000fff },
484 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
485 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
486 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
487 { AUD_POLYPH80SCALEFAC, 0x00000003 },
488 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
489 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
490 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
491 { AUD_QAM_MODE, 0x05 },
492 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
493 { AUD_PHACC_FREQ_8MSB, 0x3a },
494 { AUD_PHACC_FREQ_8LSB, 0x93 },
495 { /* end of list */ },
496 }; 338 };
497 339
498 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); 340 static const struct rlist nicam_default[] = {
341 {AUD_PDF_DDS_CNST_BYTE0, 0x16},
342 {AUD_PHACC_FREQ_8MSB, 0x34},
343 {AUD_PHACC_FREQ_8LSB, 0x4c},
344 { /* end of list */ },
345 };
499 346
500 if (!stereo) { 347 set_audio_start(core,SEL_NICAM);
501 /* FM Mono */ 348 switch (core->tvaudio) {
502 set_audio_start(core, SEL_A2); 349 case WW_L:
503 set_audio_registers(core, pal_i_fm_mono); 350 dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__);
504 set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1); 351 set_audio_registers(core, nicam_l);
505 } else { 352 break;
506 /* Nicam Stereo */ 353 case WW_I:
507 set_audio_start(core, SEL_NICAM); 354 dprintk("%s PAL-I NICAM (status: devel)\n", __FUNCTION__);
508 set_audio_registers(core, pal_i_nicam); 355 set_audio_registers(core, nicam_bgdki_common);
509 set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); 356 set_audio_registers(core, nicam_i);
510 } 357 break;
358 default:
359 dprintk("%s PAL-BGDK NICAM (status: unknown)\n", __FUNCTION__);
360 set_audio_registers(core, nicam_bgdki_common);
361 set_audio_registers(core, nicam_default);
362 break;
363 };
364
365 mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS;
366 set_audio_finish(core, mode);
511} 367}
512 368
513static void set_audio_standard_A2(struct cx88_core *core, u32 mode) 369static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
514{ 370{
515 static const struct rlist a2_common[] = { 371 static const struct rlist a2_bgdk_common[] = {
516 {AUD_ERRLOGPERIOD_R, 0x00000064}, 372 {AUD_ERRLOGPERIOD_R, 0x00000064},
517 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 373 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
518 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, 374 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
519 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, 375 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
520 {AUD_PDF_DDS_CNST_BYTE2, 0x06}, 376 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
521 {AUD_PDF_DDS_CNST_BYTE1, 0x82}, 377 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
522 {AUD_PDF_DDS_CNST_BYTE0, 0x12}, 378 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
523 {AUD_QAM_MODE, 0x05}, 379 {AUD_QAM_MODE, 0x05},
524 {AUD_PHACC_FREQ_8MSB, 0x34}, 380 {AUD_PHACC_FREQ_8MSB, 0x34},
525 {AUD_PHACC_FREQ_8LSB, 0x4c}, 381 {AUD_PHACC_FREQ_8LSB, 0x4c},
526 {AUD_RATE_ADJ1, 0x00000100}, 382 {AUD_RATE_ADJ1, 0x00000100},
527 {AUD_RATE_ADJ2, 0x00000200}, 383 {AUD_RATE_ADJ2, 0x00000200},
528 {AUD_RATE_ADJ3, 0x00000300}, 384 {AUD_RATE_ADJ3, 0x00000300},
529 {AUD_RATE_ADJ4, 0x00000400}, 385 {AUD_RATE_ADJ4, 0x00000400},
530 {AUD_RATE_ADJ5, 0x00000500}, 386 {AUD_RATE_ADJ5, 0x00000500},
531 {AUD_THR_FR, 0x00000000}, 387 {AUD_THR_FR, 0x00000000},
532 {AAGC_HYST, 0x0000001a}, 388 {AAGC_HYST, 0x0000001a},
533 {AUD_PILOT_BQD_1_K0, 0x0000755b}, 389 {AUD_PILOT_BQD_1_K0, 0x0000755b},
534 {AUD_PILOT_BQD_1_K1, 0x00551340}, 390 {AUD_PILOT_BQD_1_K1, 0x00551340},
535 {AUD_PILOT_BQD_1_K2, 0x006d30be}, 391 {AUD_PILOT_BQD_1_K2, 0x006d30be},
536 {AUD_PILOT_BQD_1_K3, 0xffd394af}, 392 {AUD_PILOT_BQD_1_K3, 0xffd394af},
537 {AUD_PILOT_BQD_1_K4, 0x00400000}, 393 {AUD_PILOT_BQD_1_K4, 0x00400000},
538 {AUD_PILOT_BQD_2_K0, 0x00040000}, 394 {AUD_PILOT_BQD_2_K0, 0x00040000},
539 {AUD_PILOT_BQD_2_K1, 0x002a4841}, 395 {AUD_PILOT_BQD_2_K1, 0x002a4841},
540 {AUD_PILOT_BQD_2_K2, 0x00400000}, 396 {AUD_PILOT_BQD_2_K2, 0x00400000},
541 {AUD_PILOT_BQD_2_K3, 0x00000000}, 397 {AUD_PILOT_BQD_2_K3, 0x00000000},
542 {AUD_PILOT_BQD_2_K4, 0x00000000}, 398 {AUD_PILOT_BQD_2_K4, 0x00000000},
543 {AUD_MODE_CHG_TIMER, 0x00000040}, 399 {AUD_MODE_CHG_TIMER, 0x00000040},
544 {AUD_AFE_12DB_EN, 0x00000001}, 400 {AUD_AFE_12DB_EN, 0x00000001},
545 {AUD_CORDIC_SHIFT_0, 0x00000007}, 401 {AUD_CORDIC_SHIFT_0, 0x00000007},
546 {AUD_CORDIC_SHIFT_1, 0x00000007}, 402 {AUD_CORDIC_SHIFT_1, 0x00000007},
547 {AUD_DEEMPH0_G0, 0x00000380}, 403 {AUD_DEEMPH0_G0, 0x00000380},
548 {AUD_DEEMPH1_G0, 0x00000380}, 404 {AUD_DEEMPH1_G0, 0x00000380},
549 {AUD_DCOC_0_SRC, 0x0000001a}, 405 {AUD_DCOC_0_SRC, 0x0000001a},
550 {AUD_DCOC0_SHIFT, 0x00000000}, 406 {AUD_DCOC0_SHIFT, 0x00000000},
551 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, 407 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
552 {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, 408 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
553 {AUD_DCOC_PASS_IN, 0x00000003}, 409 {AUD_DCOC_PASS_IN, 0x00000003},
554 {AUD_IIR3_0_SEL, 0x00000021}, 410 {AUD_IIR3_0_SEL, 0x00000021},
555 {AUD_DN2_AFC, 0x00000002}, 411 {AUD_DN2_AFC, 0x00000002},
556 {AUD_DCOC_1_SRC, 0x0000001b}, 412 {AUD_DCOC_1_SRC, 0x0000001b},
557 {AUD_DCOC1_SHIFT, 0x00000000}, 413 {AUD_DCOC1_SHIFT, 0x00000000},
558 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, 414 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
559 {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, 415 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
560 {AUD_IIR3_1_SEL, 0x00000023}, 416 {AUD_IIR3_1_SEL, 0x00000023},
561 {AUD_RDSI_SEL, 0x00000017}, 417 {AUD_RDSI_SEL, 0x00000017},
562 {AUD_RDSI_SHIFT, 0x00000000}, 418 {AUD_RDSI_SHIFT, 0x00000000},
563 {AUD_RDSQ_SEL, 0x00000017}, 419 {AUD_RDSQ_SEL, 0x00000017},
564 {AUD_RDSQ_SHIFT, 0x00000000}, 420 {AUD_RDSQ_SHIFT, 0x00000000},
565 {AUD_PLL_INT, 0x0000001e}, 421 {AUD_PLL_INT, 0x0000001e},
566 {AUD_PLL_DDS, 0x00000000}, 422 {AUD_PLL_DDS, 0x00000000},
567 {AUD_PLL_FRAC, 0x0000e542}, 423 {AUD_PLL_FRAC, 0x0000e542},
568 {AUD_POLYPH80SCALEFAC, 0x00000001}, 424 {AUD_POLYPH80SCALEFAC, 0x00000001},
569 {AUD_START_TIMER, 0x00000000}, 425 {AUD_START_TIMER, 0x00000000},
570 { /* end of list */ }, 426 { /* end of list */ },
571 }; 427 };
572 428
573 static const struct rlist a2_bg[] = { 429 static const struct rlist a2_bg[] = {
574 {AUD_DMD_RA_DDS, 0x002a4f2f}, 430 {AUD_DMD_RA_DDS, 0x002a4f2f},
575 {AUD_C1_UP_THR, 0x00007000}, 431 {AUD_C1_UP_THR, 0x00007000},
576 {AUD_C1_LO_THR, 0x00005400}, 432 {AUD_C1_LO_THR, 0x00005400},
577 {AUD_C2_UP_THR, 0x00005400}, 433 {AUD_C2_UP_THR, 0x00005400},
578 {AUD_C2_LO_THR, 0x00003000}, 434 {AUD_C2_LO_THR, 0x00003000},
579 { /* end of list */ }, 435 { /* end of list */ },
580 }; 436 };
581 437
582 static const struct rlist a2_dk[] = { 438 static const struct rlist a2_dk[] = {
583 {AUD_DMD_RA_DDS, 0x002a4f2f}, 439 {AUD_DMD_RA_DDS, 0x002a4f2f},
584 {AUD_C1_UP_THR, 0x00007000}, 440 {AUD_C1_UP_THR, 0x00007000},
585 {AUD_C1_LO_THR, 0x00005400}, 441 {AUD_C1_LO_THR, 0x00005400},
586 {AUD_C2_UP_THR, 0x00005400}, 442 {AUD_C2_UP_THR, 0x00005400},
587 {AUD_C2_LO_THR, 0x00003000}, 443 {AUD_C2_LO_THR, 0x00003000},
588 {AUD_DN0_FREQ, 0x00003a1c}, 444 {AUD_DN0_FREQ, 0x00003a1c},
589 {AUD_DN2_FREQ, 0x0000d2e0}, 445 {AUD_DN2_FREQ, 0x0000d2e0},
590 { /* end of list */ }, 446 { /* end of list */ },
591 }; 447 };
592/* unknown, probably NTSC-M */ 448
593 static const struct rlist a2_m[] = { 449 static const struct rlist a1_i[] = {
594 {AUD_DMD_RA_DDS, 0x002a0425}, 450 {AUD_ERRLOGPERIOD_R, 0x00000064},
595 {AUD_C1_UP_THR, 0x00003c00}, 451 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
596 {AUD_C1_LO_THR, 0x00003000}, 452 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
597 {AUD_C2_UP_THR, 0x00006000}, 453 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
598 {AUD_C2_LO_THR, 0x00003c00}, 454 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
599 {AUD_DEEMPH0_A0, 0x00007a80}, 455 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
600 {AUD_DEEMPH1_A0, 0x00007a80}, 456 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
601 {AUD_DEEMPH0_G0, 0x00001200}, 457 {AUD_QAM_MODE, 0x05},
602 {AUD_DEEMPH1_G0, 0x00001200}, 458 {AUD_PHACC_FREQ_8MSB, 0x3a},
603 {AUD_DN0_FREQ, 0x0000283b}, 459 {AUD_PHACC_FREQ_8LSB, 0x93},
604 {AUD_DN1_FREQ, 0x00003418}, 460 {AUD_DMD_RA_DDS, 0x002a4f2f},
605 {AUD_DN2_FREQ, 0x000029c7}, 461 {AUD_PLL_INT, 0x0000001e},
606 {AUD_POLY0_DDS_CONSTANT, 0x000a7540}, 462 {AUD_PLL_DDS, 0x00000004},
463 {AUD_PLL_FRAC, 0x0000e542},
464 {AUD_RATE_ADJ1, 0x00000100},
465 {AUD_RATE_ADJ2, 0x00000200},
466 {AUD_RATE_ADJ3, 0x00000300},
467 {AUD_RATE_ADJ4, 0x00000400},
468 {AUD_RATE_ADJ5, 0x00000500},
469 {AUD_THR_FR, 0x00000000},
470 {AUD_PILOT_BQD_1_K0, 0x0000755b},
471 {AUD_PILOT_BQD_1_K1, 0x00551340},
472 {AUD_PILOT_BQD_1_K2, 0x006d30be},
473 {AUD_PILOT_BQD_1_K3, 0xffd394af},
474 {AUD_PILOT_BQD_1_K4, 0x00400000},
475 {AUD_PILOT_BQD_2_K0, 0x00040000},
476 {AUD_PILOT_BQD_2_K1, 0x002a4841},
477 {AUD_PILOT_BQD_2_K2, 0x00400000},
478 {AUD_PILOT_BQD_2_K3, 0x00000000},
479 {AUD_PILOT_BQD_2_K4, 0x00000000},
480 {AUD_MODE_CHG_TIMER, 0x00000060},
481 {AUD_AFE_12DB_EN, 0x00000001},
482 {AAGC_HYST, 0x0000000a},
483 {AUD_CORDIC_SHIFT_0, 0x00000007},
484 {AUD_CORDIC_SHIFT_1, 0x00000007},
485 {AUD_C1_UP_THR, 0x00007000},
486 {AUD_C1_LO_THR, 0x00005400},
487 {AUD_C2_UP_THR, 0x00005400},
488 {AUD_C2_LO_THR, 0x00003000},
489 {AUD_DCOC_0_SRC, 0x0000001a},
490 {AUD_DCOC0_SHIFT, 0x00000000},
491 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
492 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
493 {AUD_DCOC_PASS_IN, 0x00000003},
494 {AUD_IIR3_0_SEL, 0x00000021},
495 {AUD_DN2_AFC, 0x00000002},
496 {AUD_DCOC_1_SRC, 0x0000001b},
497 {AUD_DCOC1_SHIFT, 0x00000000},
498 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
499 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
500 {AUD_IIR3_1_SEL, 0x00000023},
501 {AUD_DN0_FREQ, 0x000035a3},
502 {AUD_DN2_FREQ, 0x000029c7},
503 {AUD_CRDC0_SRC_SEL, 0x00000511},
504 {AUD_IIR1_0_SEL, 0x00000001},
505 {AUD_IIR1_1_SEL, 0x00000000},
506 {AUD_IIR3_2_SEL, 0x00000003},
507 {AUD_IIR3_2_SHIFT, 0x00000000},
508 {AUD_IIR3_0_SEL, 0x00000002},
509 {AUD_IIR2_0_SEL, 0x00000021},
510 {AUD_IIR2_0_SHIFT, 0x00000002},
511 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
512 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
513 {AUD_POLYPH80SCALEFAC, 0x00000001},
514 {AUD_START_TIMER, 0x00000000},
607 { /* end of list */ }, 515 { /* end of list */ },
608 }; 516 };
609 517
610 static const struct rlist a2_deemph50[] = { 518 static const struct rlist am_l[] = {
611 {AUD_DEEMPH0_G0, 0x00000380}, 519 {AUD_ERRLOGPERIOD_R, 0x00000064},
612 {AUD_DEEMPH1_G0, 0x00000380}, 520 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
613 {AUD_DEEMPHGAIN_R, 0x000011e1}, 521 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
614 {AUD_DEEMPHNUMER1_R, 0x0002a7bc}, 522 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
615 {AUD_DEEMPHNUMER2_R, 0x0003023c}, 523 {AUD_PDF_DDS_CNST_BYTE2, 0x48},
616 { /* end of list */ }, 524 {AUD_PDF_DDS_CNST_BYTE1, 0x3D},
525 {AUD_QAM_MODE, 0x00},
526 {AUD_PDF_DDS_CNST_BYTE0, 0xf5},
527 {AUD_PHACC_FREQ_8MSB, 0x3a},
528 {AUD_PHACC_FREQ_8LSB, 0x4a},
529 {AUD_DEEMPHGAIN_R, 0x00006680},
530 {AUD_DEEMPHNUMER1_R, 0x000353DE},
531 {AUD_DEEMPHNUMER2_R, 0x000001B1},
532 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
533 {AUD_DEEMPHDENOM2_R, 0x00000000},
534 {AUD_FM_MODE_ENABLE, 0x00000007},
535 {AUD_POLYPH80SCALEFAC, 0x00000003},
536 {AUD_AFE_12DB_EN, 0x00000001},
537 {AAGC_GAIN, 0x00000000},
538 {AAGC_HYST, 0x00000018},
539 {AAGC_DEF, 0x00000020},
540 {AUD_DN0_FREQ, 0x00000000},
541 {AUD_POLY0_DDS_CONSTANT, 0x000E4DB2},
542 {AUD_DCOC_0_SRC, 0x00000021},
543 {AUD_IIR1_0_SEL, 0x00000000},
544 {AUD_IIR1_0_SHIFT, 0x00000007},
545 {AUD_IIR1_1_SEL, 0x00000002},
546 {AUD_IIR1_1_SHIFT, 0x00000000},
547 {AUD_DCOC_1_SRC, 0x00000003},
548 {AUD_DCOC1_SHIFT, 0x00000000},
549 {AUD_DCOC_PASS_IN, 0x00000000},
550 {AUD_IIR1_2_SEL, 0x00000023},
551 {AUD_IIR1_2_SHIFT, 0x00000000},
552 {AUD_IIR1_3_SEL, 0x00000004},
553 {AUD_IIR1_3_SHIFT, 0x00000007},
554 {AUD_IIR1_4_SEL, 0x00000005},
555 {AUD_IIR1_4_SHIFT, 0x00000007},
556 {AUD_IIR3_0_SEL, 0x00000007},
557 {AUD_IIR3_0_SHIFT, 0x00000000},
558 {AUD_DEEMPH0_SRC_SEL, 0x00000011},
559 {AUD_DEEMPH0_SHIFT, 0x00000000},
560 {AUD_DEEMPH0_G0, 0x00007000},
561 {AUD_DEEMPH0_A0, 0x00000000},
562 {AUD_DEEMPH0_B0, 0x00000000},
563 {AUD_DEEMPH0_A1, 0x00000000},
564 {AUD_DEEMPH0_B1, 0x00000000},
565 {AUD_DEEMPH1_SRC_SEL, 0x00000011},
566 {AUD_DEEMPH1_SHIFT, 0x00000000},
567 {AUD_DEEMPH1_G0, 0x00007000},
568 {AUD_DEEMPH1_A0, 0x00000000},
569 {AUD_DEEMPH1_B0, 0x00000000},
570 {AUD_DEEMPH1_A1, 0x00000000},
571 {AUD_DEEMPH1_B1, 0x00000000},
572 {AUD_OUT0_SEL, 0x0000003F},
573 {AUD_OUT1_SEL, 0x0000003F},
574 {AUD_DMD_RA_DDS, 0x00F5C285},
575 {AUD_PLL_INT, 0x0000001E},
576 {AUD_PLL_DDS, 0x00000000},
577 {AUD_PLL_FRAC, 0x0000E542},
578 {AUD_RATE_ADJ1, 0x00000100},
579 {AUD_RATE_ADJ2, 0x00000200},
580 {AUD_RATE_ADJ3, 0x00000300},
581 {AUD_RATE_ADJ4, 0x00000400},
582 {AUD_RATE_ADJ5, 0x00000500},
583 {AUD_RATE_THRES_DMD, 0x000000C0},
584 { /* end of list */ },
617 }; 585 };
618 586
619 static const struct rlist a2_deemph75[] = { 587 static const struct rlist a2_deemph50[] = {
620 {AUD_DEEMPH0_G0, 0x00000480}, 588 {AUD_DEEMPH0_G0, 0x00000380},
621 {AUD_DEEMPH1_G0, 0x00000480}, 589 {AUD_DEEMPH1_G0, 0x00000380},
622 {AUD_DEEMPHGAIN_R, 0x00009000}, 590 {AUD_DEEMPHGAIN_R, 0x000011e1},
623 {AUD_DEEMPHNUMER1_R, 0x000353de}, 591 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
624 {AUD_DEEMPHNUMER2_R, 0x000001b1}, 592 {AUD_DEEMPHNUMER2_R, 0x0003023c},
625 { /* end of list */ }, 593 { /* end of list */ },
626 }; 594 };
627 595
628 set_audio_start(core, SEL_A2); 596 set_audio_start(core, SEL_A2);
629 set_audio_registers(core, a2_common);
630 switch (core->tvaudio) { 597 switch (core->tvaudio) {
631 case WW_A2_BG: 598 case WW_BG:
632 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); 599 dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__);
633 set_audio_registers(core, a2_bg); 600 set_audio_registers(core, a2_bgdk_common);
634 set_audio_registers(core, a2_deemph50); 601 set_audio_registers(core, a2_bg);
602 set_audio_registers(core, a2_deemph50);
635 break; 603 break;
636 case WW_A2_DK: 604 case WW_DK:
637 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); 605 dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__);
638 set_audio_registers(core, a2_dk); 606 set_audio_registers(core, a2_bgdk_common);
639 set_audio_registers(core, a2_deemph50); 607 set_audio_registers(core, a2_dk);
608 set_audio_registers(core, a2_deemph50);
640 break; 609 break;
641 case WW_A2_M: 610 case WW_I:
642 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); 611 dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__);
643 set_audio_registers(core, a2_m); 612 set_audio_registers(core, a1_i);
644 set_audio_registers(core, a2_deemph75); 613 set_audio_registers(core, a2_deemph50);
614 break;
615 case WW_L:
616 dprintk("%s AM-L (status: devel)\n", __FUNCTION__);
617 set_audio_registers(core, am_l);
618 break;
619 default:
620 dprintk("%s Warning: wrong value\n", __FUNCTION__);
621 return;
645 break; 622 break;
646 }; 623 };
647 624
@@ -656,71 +633,71 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
656 633
657 { /* end of list */ }, 634 { /* end of list */ },
658 }; 635 };
659 dprintk("%s (status: unknown)\n",__FUNCTION__); 636 dprintk("%s (status: unknown)\n", __FUNCTION__);
660 637
661 set_audio_start(core, SEL_EIAJ); 638 set_audio_start(core, SEL_EIAJ);
662 set_audio_registers(core, eiaj); 639 set_audio_registers(core, eiaj);
663 set_audio_finish(core, EN_EIAJ_AUTO_STEREO); 640 set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
664} 641}
665 642
666static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) 643static void set_audio_standard_FM(struct cx88_core *core,
644 enum cx88_deemph_type deemph)
667{ 645{
668 static const struct rlist fm_deemph_50[] = { 646 static const struct rlist fm_deemph_50[] = {
669 { AUD_DEEMPH0_G0, 0x0C45 }, 647 {AUD_DEEMPH0_G0, 0x0C45},
670 { AUD_DEEMPH0_A0, 0x6262 }, 648 {AUD_DEEMPH0_A0, 0x6262},
671 { AUD_DEEMPH0_B0, 0x1C29 }, 649 {AUD_DEEMPH0_B0, 0x1C29},
672 { AUD_DEEMPH0_A1, 0x3FC66}, 650 {AUD_DEEMPH0_A1, 0x3FC66},
673 { AUD_DEEMPH0_B1, 0x399A }, 651 {AUD_DEEMPH0_B1, 0x399A},
674 652
675 { AUD_DEEMPH1_G0, 0x0D80 }, 653 {AUD_DEEMPH1_G0, 0x0D80},
676 { AUD_DEEMPH1_A0, 0x6262 }, 654 {AUD_DEEMPH1_A0, 0x6262},
677 { AUD_DEEMPH1_B0, 0x1C29 }, 655 {AUD_DEEMPH1_B0, 0x1C29},
678 { AUD_DEEMPH1_A1, 0x3FC66}, 656 {AUD_DEEMPH1_A1, 0x3FC66},
679 { AUD_DEEMPH1_B1, 0x399A}, 657 {AUD_DEEMPH1_B1, 0x399A},
680 658
681 { AUD_POLYPH80SCALEFAC, 0x0003}, 659 {AUD_POLYPH80SCALEFAC, 0x0003},
682 { /* end of list */ }, 660 { /* end of list */ },
683 }; 661 };
684 static const struct rlist fm_deemph_75[] = { 662 static const struct rlist fm_deemph_75[] = {
685 { AUD_DEEMPH0_G0, 0x091B }, 663 {AUD_DEEMPH0_G0, 0x091B},
686 { AUD_DEEMPH0_A0, 0x6B68 }, 664 {AUD_DEEMPH0_A0, 0x6B68},
687 { AUD_DEEMPH0_B0, 0x11EC }, 665 {AUD_DEEMPH0_B0, 0x11EC},
688 { AUD_DEEMPH0_A1, 0x3FC66}, 666 {AUD_DEEMPH0_A1, 0x3FC66},
689 { AUD_DEEMPH0_B1, 0x399A }, 667 {AUD_DEEMPH0_B1, 0x399A},
690 668
691 { AUD_DEEMPH1_G0, 0x0AA0 }, 669 {AUD_DEEMPH1_G0, 0x0AA0},
692 { AUD_DEEMPH1_A0, 0x6B68 }, 670 {AUD_DEEMPH1_A0, 0x6B68},
693 { AUD_DEEMPH1_B0, 0x11EC }, 671 {AUD_DEEMPH1_B0, 0x11EC},
694 { AUD_DEEMPH1_A1, 0x3FC66}, 672 {AUD_DEEMPH1_A1, 0x3FC66},
695 { AUD_DEEMPH1_B1, 0x399A}, 673 {AUD_DEEMPH1_B1, 0x399A},
696 674
697 { AUD_POLYPH80SCALEFAC, 0x0003}, 675 {AUD_POLYPH80SCALEFAC, 0x0003},
698 { /* end of list */ }, 676 { /* end of list */ },
699 }; 677 };
700 678
701 /* It is enough to leave default values? */ 679 /* It is enough to leave default values? */
702 static const struct rlist fm_no_deemph[] = { 680 static const struct rlist fm_no_deemph[] = {
703 681
704 { AUD_POLYPH80SCALEFAC, 0x0003}, 682 {AUD_POLYPH80SCALEFAC, 0x0003},
705 { /* end of list */ }, 683 { /* end of list */ },
706 }; 684 };
707 685
708 dprintk("%s (status: unknown)\n",__FUNCTION__); 686 dprintk("%s (status: unknown)\n", __FUNCTION__);
709 set_audio_start(core, SEL_FMRADIO); 687 set_audio_start(core, SEL_FMRADIO);
710 688
711 switch (deemph) 689 switch (deemph) {
712 { 690 case FM_NO_DEEMPH:
713 case FM_NO_DEEMPH: 691 set_audio_registers(core, fm_no_deemph);
714 set_audio_registers(core, fm_no_deemph); 692 break;
715 break;
716 693
717 case FM_DEEMPH_50: 694 case FM_DEEMPH_50:
718 set_audio_registers(core, fm_deemph_50); 695 set_audio_registers(core, fm_deemph_50);
719 break; 696 break;
720 697
721 case FM_DEEMPH_75: 698 case FM_DEEMPH_75:
722 set_audio_registers(core, fm_deemph_75); 699 set_audio_registers(core, fm_deemph_75);
723 break; 700 break;
724 } 701 }
725 702
726 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO); 703 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
@@ -728,36 +705,64 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
728 705
729/* ----------------------------------------------------------- */ 706/* ----------------------------------------------------------- */
730 707
708int cx88_detect_nicam(struct cx88_core *core)
709{
710 int i, j = 0;
711
712 dprintk("start nicam autodetect.\n");
713
714 for (i = 0; i < 6; i++) {
715 /* if bit1=1 then nicam is detected */
716 j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1);
717
718 /* 3x detected: absolutly sure now */
719 if (j == 3) {
720 dprintk("nicam is detected.\n");
721 return 1;
722 }
723
724 /* wait a little bit for next reading status */
725 msleep(10);
726 }
727
728 dprintk("nicam is not detected.\n");
729 return 0;
730}
731
731void cx88_set_tvaudio(struct cx88_core *core) 732void cx88_set_tvaudio(struct cx88_core *core)
732{ 733{
733 switch (core->tvaudio) { 734 switch (core->tvaudio) {
734 case WW_BTSC: 735 case WW_BTSC:
735 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO); 736 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
736 break; 737 break;
737 case WW_NICAM_BGDKL: 738 case WW_BG:
738 set_audio_standard_NICAM_L(core,0); 739 case WW_DK:
739 break; 740 case WW_I:
740 case WW_NICAM_I: 741 case WW_L:
741 set_audio_standard_PAL_I(core,0); 742 /* prepare all dsp registers */
742 break; 743 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
743 case WW_A2_BG: 744
744 case WW_A2_DK: 745 /* set nicam mode - otherwise
745 case WW_A2_M: 746 AUD_NICAM_STATUS2 contains wrong values */
746 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 747 set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO);
748 if (0 == cx88_detect_nicam(core)) {
749 /* fall back to fm / am mono */
750 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
751 core->use_nicam = 0;
752 } else {
753 core->use_nicam = 1;
754 }
747 break; 755 break;
748 case WW_EIAJ: 756 case WW_EIAJ:
749 set_audio_standard_EIAJ(core); 757 set_audio_standard_EIAJ(core);
750 break; 758 break;
751 case WW_FM: 759 case WW_FM:
752 set_audio_standard_FM(core,FM_NO_DEEMPH); 760 set_audio_standard_FM(core, FM_NO_DEEMPH);
753 break;
754 case WW_SYSTEM_L_AM:
755 set_audio_standard_NICAM_L(core, 1);
756 break; 761 break;
757 case WW_NONE: 762 case WW_NONE:
758 default: 763 default:
759 printk("%s/0: unknown tv audio mode [%d]\n", 764 printk("%s/0: unknown tv audio mode [%d]\n",
760 core->name, core->tvaudio); 765 core->name, core->tvaudio);
761 break; 766 break;
762 } 767 }
763 return; 768 return;
@@ -766,24 +771,16 @@ void cx88_set_tvaudio(struct cx88_core *core)
766void cx88_newstation(struct cx88_core *core) 771void cx88_newstation(struct cx88_core *core)
767{ 772{
768 core->audiomode_manual = UNSET; 773 core->audiomode_manual = UNSET;
769
770 switch (core->tvaudio) {
771 case WW_SYSTEM_L_AM:
772 /* try nicam ... */
773 core->audiomode_current = V4L2_TUNER_MODE_STEREO;
774 set_audio_standard_NICAM_L(core, 1);
775 break;
776 }
777} 774}
778 775
779void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) 776void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
780{ 777{
781 static char *m[] = {"stereo", "dual mono", "mono", "sap"}; 778 static char *m[] = { "stereo", "dual mono", "mono", "sap" };
782 static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"}; 779 static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
783 u32 reg,mode,pilot; 780 u32 reg, mode, pilot;
784 781
785 reg = cx_read(AUD_STATUS); 782 reg = cx_read(AUD_STATUS);
786 mode = reg & 0x03; 783 mode = reg & 0x03;
787 pilot = (reg >> 2) & 0x03; 784 pilot = (reg >> 2) & 0x03;
788 785
789 if (core->astat != reg) 786 if (core->astat != reg)
@@ -800,14 +797,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
800 797
801# if 0 798# if 0
802 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | 799 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
803 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 800 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
804 t->rxsubchans = V4L2_TUNER_SUB_MONO; 801 t->rxsubchans = V4L2_TUNER_SUB_MONO;
805 t->audmode = V4L2_TUNER_MODE_MONO; 802 t->audmode = V4L2_TUNER_MODE_MONO;
806 803
807 switch (core->tvaudio) { 804 switch (core->tvaudio) {
808 case WW_BTSC: 805 case WW_BTSC:
809 t->capability = V4L2_TUNER_CAP_STEREO | 806 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP;
810 V4L2_TUNER_CAP_SAP;
811 t->rxsubchans = V4L2_TUNER_SUB_STEREO; 807 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
812 if (1 == pilot) { 808 if (1 == pilot) {
813 /* SAP */ 809 /* SAP */
@@ -819,13 +815,15 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
819 case WW_A2_M: 815 case WW_A2_M:
820 if (1 == pilot) { 816 if (1 == pilot) {
821 /* stereo */ 817 /* stereo */
822 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 818 t->rxsubchans =
819 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
823 if (0 == mode) 820 if (0 == mode)
824 t->audmode = V4L2_TUNER_MODE_STEREO; 821 t->audmode = V4L2_TUNER_MODE_STEREO;
825 } 822 }
826 if (2 == pilot) { 823 if (2 == pilot) {
827 /* dual language -- FIXME */ 824 /* dual language -- FIXME */
828 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 825 t->rxsubchans =
826 V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
829 t->audmode = V4L2_TUNER_MODE_LANG1; 827 t->audmode = V4L2_TUNER_MODE_LANG1;
830 } 828 }
831 break; 829 break;
@@ -840,7 +838,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
840 t->audmode = V4L2_TUNER_MODE_STEREO; 838 t->audmode = V4L2_TUNER_MODE_STEREO;
841 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 839 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
842 } 840 }
843 break ; 841 break;
844 default: 842 default:
845 /* nothing */ 843 /* nothing */
846 break; 844 break;
@@ -851,7 +849,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
851 849
852void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) 850void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
853{ 851{
854 u32 ctl = UNSET; 852 u32 ctl = UNSET;
855 u32 mask = UNSET; 853 u32 mask = UNSET;
856 854
857 if (manual) { 855 if (manual) {
@@ -879,68 +877,58 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
879 break; 877 break;
880 } 878 }
881 break; 879 break;
882 case WW_A2_BG: 880 case WW_BG:
883 case WW_A2_DK: 881 case WW_DK:
884 case WW_A2_M: 882 case WW_I:
885 switch (mode) { 883 case WW_L:
886 case V4L2_TUNER_MODE_MONO: 884 if (1 == core->use_nicam) {
887 case V4L2_TUNER_MODE_LANG1: 885 switch (mode) {
888 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 886 case V4L2_TUNER_MODE_MONO:
889 break; 887 case V4L2_TUNER_MODE_LANG1:
890 case V4L2_TUNER_MODE_LANG2: 888 set_audio_standard_NICAM(core,
891 set_audio_standard_A2(core, EN_A2_FORCE_MONO2); 889 EN_NICAM_FORCE_MONO1);
892 break; 890 break;
893 case V4L2_TUNER_MODE_STEREO: 891 case V4L2_TUNER_MODE_LANG2:
894 set_audio_standard_A2(core, EN_A2_FORCE_STEREO); 892 set_audio_standard_NICAM(core,
895 break; 893 EN_NICAM_FORCE_MONO2);
896 } 894 break;
897 break; 895 case V4L2_TUNER_MODE_STEREO:
898 case WW_NICAM_BGDKL: 896 set_audio_standard_NICAM(core,
899 switch (mode) { 897 EN_NICAM_FORCE_STEREO);
900 case V4L2_TUNER_MODE_MONO: 898 break;
901 ctl = EN_NICAM_FORCE_MONO1; 899 }
902 mask = 0x3f; 900 } else {
903 break; 901 if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) {
904 case V4L2_TUNER_MODE_LANG1: 902 /* fall back to fm / am mono */
905 ctl = EN_NICAM_AUTO_MONO2; 903 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
906 mask = 0x3f; 904 } else {
907 break; 905 /* TODO: Add A2 autodection */
908 case V4L2_TUNER_MODE_STEREO: 906 switch (mode) {
909 ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR; 907 case V4L2_TUNER_MODE_MONO:
910 mask = 0x93f; 908 case V4L2_TUNER_MODE_LANG1:
911 break; 909 set_audio_standard_A2(core,
912 } 910 EN_A2_FORCE_MONO1);
913 break; 911 break;
914 case WW_SYSTEM_L_AM: 912 case V4L2_TUNER_MODE_LANG2:
915 switch (mode) { 913 set_audio_standard_A2(core,
916 case V4L2_TUNER_MODE_MONO: 914 EN_A2_FORCE_MONO2);
917 case V4L2_TUNER_MODE_LANG1: /* FIXME */ 915 break;
918 set_audio_standard_NICAM_L(core, 0); 916 case V4L2_TUNER_MODE_STEREO:
919 break; 917 set_audio_standard_A2(core,
920 case V4L2_TUNER_MODE_STEREO: 918 EN_A2_FORCE_STEREO);
921 set_audio_standard_NICAM_L(core, 1); 919 break;
922 break; 920 }
923 } 921 }
924 break;
925 case WW_NICAM_I:
926 switch (mode) {
927 case V4L2_TUNER_MODE_MONO:
928 case V4L2_TUNER_MODE_LANG1:
929 set_audio_standard_PAL_I(core, 0);
930 break;
931 case V4L2_TUNER_MODE_STEREO:
932 set_audio_standard_PAL_I(core, 1);
933 break;
934 } 922 }
935 break; 923 break;
936 case WW_FM: 924 case WW_FM:
937 switch (mode) { 925 switch (mode) {
938 case V4L2_TUNER_MODE_MONO: 926 case V4L2_TUNER_MODE_MONO:
939 ctl = EN_FMRADIO_FORCE_MONO; 927 ctl = EN_FMRADIO_FORCE_MONO;
940 mask = 0x3f; 928 mask = 0x3f;
941 break; 929 break;
942 case V4L2_TUNER_MODE_STEREO: 930 case V4L2_TUNER_MODE_STEREO:
943 ctl = EN_FMRADIO_AUTO_STEREO; 931 ctl = EN_FMRADIO_AUTO_STEREO;
944 mask = 0x3f; 932 mask = 0x3f;
945 break; 933 break;
946 } 934 }
@@ -970,8 +958,8 @@ int cx88_audio_thread(void *data)
970 break; 958 break;
971 959
972 /* just monitor the audio status for now ... */ 960 /* just monitor the audio status for now ... */
973 memset(&t,0,sizeof(t)); 961 memset(&t, 0, sizeof(t));
974 cx88_get_stereo(core,&t); 962 cx88_get_stereo(core, &t);
975 963
976 if (UNSET != core->audiomode_manual) 964 if (UNSET != core->audiomode_manual)
977 /* manually set, don't do anything. */ 965 /* manually set, don't do anything. */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 3dbc074fb515..24a48f8a48c1 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -34,6 +34,9 @@
34 34
35#include "cx88.h" 35#include "cx88.h"
36 36
37/* Include V4L1 specific functions. Should be removed soon */
38#include <linux/videodev.h>
39
37MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 40MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 41MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
@@ -100,7 +103,7 @@ static struct cx88_tvnorm tvnorms[] = {
100 .id = V4L2_STD_PAL_I, 103 .id = V4L2_STD_PAL_I,
101 .cxiformat = VideoFormatPAL, 104 .cxiformat = VideoFormatPAL,
102 .cxoformat = 0x181f0008, 105 .cxoformat = 0x181f0008,
103 },{ 106 },{
104 .name = "PAL-M", 107 .name = "PAL-M",
105 .id = V4L2_STD_PAL_M, 108 .id = V4L2_STD_PAL_M,
106 .cxiformat = VideoFormatPALM, 109 .cxiformat = VideoFormatPALM,
@@ -470,7 +473,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
470 struct list_head *item; 473 struct list_head *item;
471 474
472 if (!list_empty(&q->active)) { 475 if (!list_empty(&q->active)) {
473 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); 476 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
474 dprintk(2,"restart_queue [%p/%d]: restart dma\n", 477 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
475 buf, buf->vb.i); 478 buf, buf->vb.i);
476 start_video_dma(dev, q, buf); 479 start_video_dma(dev, q, buf);
@@ -486,7 +489,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
486 for (;;) { 489 for (;;) {
487 if (list_empty(&q->queued)) 490 if (list_empty(&q->queued))
488 return 0; 491 return 0;
489 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); 492 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
490 if (NULL == prev) { 493 if (NULL == prev) {
491 list_del(&buf->vb.queue); 494 list_del(&buf->vb.queue);
492 list_add_tail(&buf->vb.queue,&q->active); 495 list_add_tail(&buf->vb.queue,&q->active);
@@ -783,11 +786,11 @@ static int video_open(struct inode *inode, struct file *file)
783 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); 786 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
784 } 787 }
785 788
786 return 0; 789 return 0;
787} 790}
788 791
789static ssize_t 792static ssize_t
790video_read(struct file *file, char *data, size_t count, loff_t *ppos) 793video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
791{ 794{
792 struct cx8800_fh *fh = file->private_data; 795 struct cx8800_fh *fh = file->private_data;
793 796
@@ -922,7 +925,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
922{ 925{
923 /* struct cx88_core *core = dev->core; */ 926 /* struct cx88_core *core = dev->core; */
924 struct cx88_ctrl *c = NULL; 927 struct cx88_ctrl *c = NULL;
925 u32 v_sat_value; 928 u32 v_sat_value;
926 u32 value; 929 u32 value;
927 int i; 930 int i;
928 931
@@ -1187,7 +1190,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1187 struct v4l2_format *f = arg; 1190 struct v4l2_format *f = arg;
1188 return cx8800_try_fmt(dev,fh,f); 1191 return cx8800_try_fmt(dev,fh,f);
1189 } 1192 }
1190 1193#ifdef HAVE_V4L1
1191 /* --- streaming capture ------------------------------------- */ 1194 /* --- streaming capture ------------------------------------- */
1192 case VIDIOCGMBUF: 1195 case VIDIOCGMBUF:
1193 { 1196 {
@@ -1213,6 +1216,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1213 } 1216 }
1214 return 0; 1217 return 0;
1215 } 1218 }
1219#endif
1216 case VIDIOC_REQBUFS: 1220 case VIDIOC_REQBUFS:
1217 return videobuf_reqbufs(get_queue(fh), arg); 1221 return videobuf_reqbufs(get_queue(fh), arg);
1218 1222
@@ -1244,7 +1248,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1244 res_free(dev,fh,res); 1248 res_free(dev,fh,res);
1245 return 0; 1249 return 0;
1246 } 1250 }
1247
1248 default: 1251 default:
1249 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); 1252 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
1250 } 1253 }
@@ -1252,15 +1255,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1252} 1255}
1253 1256
1254int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, 1257int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1255 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) 1258 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
1256{ 1259{
1257 int err; 1260 int err;
1258 1261
1262 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1259 if (video_debug > 1) 1263 if (video_debug > 1)
1260 cx88_print_ioctl(core->name,cmd); 1264 cx88_print_ioctl(core->name,cmd);
1261 printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd );
1262 cx88_print_ioctl(core->name,cmd);
1263 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1264 1265
1265 switch (cmd) { 1266 switch (cmd) {
1266 /* ---------- tv norms ---------- */ 1267 /* ---------- tv norms ---------- */
@@ -1401,7 +1402,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1401 1402
1402 cx88_get_stereo(core ,t); 1403 cx88_get_stereo(core ,t);
1403 reg = cx_read(MO_DEVICE_STATUS); 1404 reg = cx_read(MO_DEVICE_STATUS);
1404 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; 1405 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
1405 return 0; 1406 return 0;
1406 } 1407 }
1407 case VIDIOC_S_TUNER: 1408 case VIDIOC_S_TUNER:
@@ -1488,7 +1489,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1488 struct v4l2_capability *cap = arg; 1489 struct v4l2_capability *cap = arg;
1489 1490
1490 memset(cap,0,sizeof(*cap)); 1491 memset(cap,0,sizeof(*cap));
1491 strcpy(cap->driver, "cx8800"); 1492 strcpy(cap->driver, "cx8800");
1492 strlcpy(cap->card, cx88_boards[core->board].name, 1493 strlcpy(cap->card, cx88_boards[core->board].name,
1493 sizeof(cap->card)); 1494 sizeof(cap->card));
1494 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); 1495 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
@@ -1505,6 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1505 1506
1506 memset(t,0,sizeof(*t)); 1507 memset(t,0,sizeof(*t));
1507 strcpy(t->name, "Radio"); 1508 strcpy(t->name, "Radio");
1509 t->type = V4L2_TUNER_RADIO;
1508 1510
1509 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); 1511 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
1510 return 0; 1512 return 0;
@@ -1539,6 +1541,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1539 *id = 0; 1541 *id = 0;
1540 return 0; 1542 return 0;
1541 } 1543 }
1544#ifdef HAVE_V4L1
1542 case VIDIOCSTUNER: 1545 case VIDIOCSTUNER:
1543 { 1546 {
1544 struct video_tuner *v = arg; 1547 struct video_tuner *v = arg;
@@ -1549,6 +1552,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1549 cx88_call_i2c_clients(core,VIDIOCSTUNER,v); 1552 cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
1550 return 0; 1553 return 0;
1551 } 1554 }
1555#endif
1552 case VIDIOC_S_TUNER: 1556 case VIDIOC_S_TUNER:
1553 { 1557 {
1554 struct v4l2_tuner *t = arg; 1558 struct v4l2_tuner *t = arg;
@@ -1829,8 +1833,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1829 1833
1830 /* print pci info */ 1834 /* print pci info */
1831 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1835 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1832 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1836 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1833 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1837 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1834 "latency: %d, mmio: 0x%lx\n", core->name, 1838 "latency: %d, mmio: 0x%lx\n", core->name,
1835 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 1839 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1836 dev->pci_lat,pci_resource_start(pci_dev,0)); 1840 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -1946,7 +1950,7 @@ fail_free:
1946 1950
1947static void __devexit cx8800_finidev(struct pci_dev *pci_dev) 1951static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1948{ 1952{
1949 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 1953 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
1950 struct cx88_core *core = dev->core; 1954 struct cx88_core *core = dev->core;
1951 1955
1952 /* stop thread */ 1956 /* stop thread */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f48dd4353568..b19d3a9e2298 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -22,7 +22,7 @@
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/i2c-algo-bit.h> 24#include <linux/i2c-algo-bit.h>
25#include <linux/videodev.h> 25#include <linux/videodev2.h>
26#include <linux/kdev_t.h> 26#include <linux/kdev_t.h>
27 27
28#include <media/tuner.h> 28#include <media/tuner.h>
@@ -148,7 +148,7 @@ extern struct sram_channel cx88_sram_channels[];
148#define CX88_BOARD_PIXELVIEW 3 148#define CX88_BOARD_PIXELVIEW 3
149#define CX88_BOARD_ATI_WONDER_PRO 4 149#define CX88_BOARD_ATI_WONDER_PRO 4
150#define CX88_BOARD_WINFAST2000XP_EXPERT 5 150#define CX88_BOARD_WINFAST2000XP_EXPERT 5
151#define CX88_BOARD_AVERTV_303 6 151#define CX88_BOARD_AVERTV_STUDIO_303 6
152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
153#define CX88_BOARD_WINFAST_DV2000 8 153#define CX88_BOARD_WINFAST_DV2000 8
154#define CX88_BOARD_LEADTEK_PVR2000 9 154#define CX88_BOARD_LEADTEK_PVR2000 9
@@ -174,6 +174,11 @@ extern struct sram_channel cx88_sram_channels[];
174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29 174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31
177#define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32
178#define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33
179#define CX88_BOARD_ATI_HDTVWONDER 34
180#define CX88_BOARD_WINFAST_DTV1000 35
181#define CX88_BOARD_AVERTV_303 36
177 182
178enum cx88_itype { 183enum cx88_itype {
179 CX88_VMUX_COMPOSITE1 = 1, 184 CX88_VMUX_COMPOSITE1 = 1,
@@ -203,8 +208,8 @@ struct cx88_board {
203 int tda9887_conf; 208 int tda9887_conf;
204 struct cx88_input input[MAX_CX88_INPUT]; 209 struct cx88_input input[MAX_CX88_INPUT];
205 struct cx88_input radio; 210 struct cx88_input radio;
206 int blackbird:1; 211 unsigned int blackbird:1;
207 int dvb:1; 212 unsigned int dvb:1;
208}; 213};
209 214
210struct cx88_subid { 215struct cx88_subid {
@@ -255,8 +260,8 @@ struct cx88_core {
255 /* pci stuff */ 260 /* pci stuff */
256 int pci_bus; 261 int pci_bus;
257 int pci_slot; 262 int pci_slot;
258 u32 __iomem *lmmio; 263 u32 __iomem *lmmio;
259 u8 __iomem *bmmio; 264 u8 __iomem *bmmio;
260 u32 shadow[SHADOW_MAX]; 265 u32 shadow[SHADOW_MAX];
261 int pci_irqmask; 266 int pci_irqmask;
262 267
@@ -287,6 +292,7 @@ struct cx88_core {
287 u32 audiomode_current; 292 u32 audiomode_current;
288 u32 input; 293 u32 input;
289 u32 astat; 294 u32 astat;
295 u32 use_nicam;
290 296
291 /* IR remote control state */ 297 /* IR remote control state */
292 struct cx88_IR *ir; 298 struct cx88_IR *ir;
@@ -370,6 +376,14 @@ struct cx8802_suspend_state {
370 int disabled; 376 int disabled;
371}; 377};
372 378
379/* TODO: move this to struct v4l2_mpeg_compression ? */
380struct blackbird_dnr {
381 u32 mode;
382 u32 type;
383 u32 spatial;
384 u32 temporal;
385};
386
373struct cx8802_dev { 387struct cx8802_dev {
374 struct cx88_core *core; 388 struct cx88_core *core;
375 spinlock_t slock; 389 spinlock_t slock;
@@ -400,6 +414,10 @@ struct cx8802_dev {
400 414
401 /* for switching modulation types */ 415 /* for switching modulation types */
402 unsigned char ts_gen_cntrl; 416 unsigned char ts_gen_cntrl;
417
418 /* mpeg params */
419 struct v4l2_mpeg_compression params;
420 struct blackbird_dnr dnr_params;
403}; 421};
404 422
405/* ----------------------------------------------------------- */ 423/* ----------------------------------------------------------- */
@@ -514,22 +532,20 @@ extern void cx88_card_setup(struct cx88_core *core);
514 532
515#define WW_NONE 1 533#define WW_NONE 1
516#define WW_BTSC 2 534#define WW_BTSC 2
517#define WW_NICAM_I 3 535#define WW_BG 3
518#define WW_NICAM_BGDKL 4 536#define WW_DK 4
519#define WW_A1 5 537#define WW_I 5
520#define WW_A2_BG 6 538#define WW_L 6
521#define WW_A2_DK 7 539#define WW_EIAJ 7
522#define WW_A2_M 8 540#define WW_I2SPT 8
523#define WW_EIAJ 9 541#define WW_FM 9
524#define WW_SYSTEM_L_AM 10
525#define WW_I2SPT 11
526#define WW_FM 12
527 542
528void cx88_set_tvaudio(struct cx88_core *core); 543void cx88_set_tvaudio(struct cx88_core *core);
529void cx88_newstation(struct cx88_core *core); 544void cx88_newstation(struct cx88_core *core);
530void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); 545void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
531void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); 546void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
532int cx88_audio_thread(void *data); 547int cx88_audio_thread(void *data);
548int cx88_detect_nicam(struct cx88_core *core);
533 549
534/* ----------------------------------------------------------- */ 550/* ----------------------------------------------------------- */
535/* cx88-input.c */ 551/* cx88-input.c */
@@ -541,7 +557,8 @@ void cx88_ir_irq(struct cx88_core *core);
541/* ----------------------------------------------------------- */ 557/* ----------------------------------------------------------- */
542/* cx88-mpeg.c */ 558/* cx88-mpeg.c */
543 559
544int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf); 560int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
561 enum v4l2_field field);
545void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); 562void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
546void cx8802_cancel_buffers(struct cx8802_dev *dev); 563void cx8802_cancel_buffers(struct cx8802_dev *dev);
547 564
@@ -562,6 +579,10 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
562extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, 579extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
563 unsigned int cmd, void *arg); 580 unsigned int cmd, void *arg);
564extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); 581extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
582void blackbird_set_params(struct cx8802_dev *dev,
583 struct v4l2_mpeg_compression *params);
584void blackbird_set_dnr_params(struct cx8802_dev *dev,
585 struct blackbird_dnr* dnr_params);
565 586
566/* 587/*
567 * Local variables: 588 * Local variables:
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
new file mode 100644
index 000000000000..885fd0170086
--- /dev/null
+++ b/drivers/media/video/em28xx/Kconfig
@@ -0,0 +1,12 @@
1config VIDEO_EM28XX
2 tristate "Empia EM2800/2820/2840 USB video capture support"
3 depends on VIDEO_DEV && USB && I2C
4 select VIDEO_BUF
5 select VIDEO_TUNER
6 select VIDEO_TVEEPROM
7 select VIDEO_IR
8 ---help---
9 This is a video4linux driver for Empia 28xx based TV cards.
10
11 To compile this driver as a module, choose M here: the
12 module will be called em28xx
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
new file mode 100644
index 000000000000..da457a05b0dd
--- /dev/null
+++ b/drivers/media/video/em28xx/Makefile
@@ -0,0 +1,6 @@
1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
2 em28xx-input.o
3
4obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
5
6EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
new file mode 100644
index 000000000000..57779e63f35d
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -0,0 +1,292 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <linux/i2c.h>
29#include <linux/usb.h>
30#include <media/tuner.h>
31#include <media/audiochip.h>
32#include <media/tveeprom.h>
33#include "msp3400.h"
34
35#include "em28xx.h"
36
37struct em28xx_board em28xx_boards[] = {
38 [EM2800_BOARD_UNKNOWN] = {
39 .name = "Unknown EM2800 video grabber",
40 .is_em2800 = 1,
41 .vchannels = 2,
42 .norm = VIDEO_MODE_PAL,
43 .tda9887_conf = TDA9887_PRESENT,
44 .has_tuner = 1,
45 .decoder = EM28XX_SAA7113,
46 .input = {{
47 .type = EM28XX_VMUX_COMPOSITE1,
48 .vmux = 0,
49 .amux = 1,
50 },{
51 .type = EM28XX_VMUX_SVIDEO,
52 .vmux = 9,
53 .amux = 1,
54 }},
55 },
56 [EM2820_BOARD_UNKNOWN] = {
57 .name = "Unknown EM2820/2840 video grabber",
58 .is_em2800 = 0,
59 .vchannels = 2,
60 .norm = VIDEO_MODE_PAL,
61 .tda9887_conf = TDA9887_PRESENT,
62 .has_tuner = 1,
63 .decoder = EM28XX_SAA7113,
64 .input = {{
65 .type = EM28XX_VMUX_COMPOSITE1,
66 .vmux = 0,
67 .amux = 1,
68 },{
69 .type = EM28XX_VMUX_SVIDEO,
70 .vmux = 9,
71 .amux = 1,
72 }},
73 },
74 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
75 .name = "Terratec Cinergy 250 USB",
76 .vchannels = 3,
77 .norm = VIDEO_MODE_PAL,
78 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
79 .tda9887_conf = TDA9887_PRESENT,
80 .has_tuner = 1,
81 .decoder = EM28XX_SAA7113,
82 .input = {{
83 .type = EM28XX_VMUX_TELEVISION,
84 .vmux = 2,
85 .amux = 0,
86 },{
87 .type = EM28XX_VMUX_COMPOSITE1,
88 .vmux = 0,
89 .amux = 1,
90 },{
91 .type = EM28XX_VMUX_SVIDEO,
92 .vmux = 9,
93 .amux = 1,
94 }},
95 },
96 [EM2820_BOARD_PINNACLE_USB_2] = {
97 .name = "Pinnacle PCTV USB 2",
98 .vchannels = 3,
99 .norm = VIDEO_MODE_PAL,
100 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
101 .tda9887_conf = TDA9887_PRESENT,
102 .has_tuner = 1,
103 .decoder = EM28XX_SAA7113,
104 .input = {{
105 .type = EM28XX_VMUX_TELEVISION,
106 .vmux = 2,
107 .amux = 0,
108 },{
109 .type = EM28XX_VMUX_COMPOSITE1,
110 .vmux = 0,
111 .amux = 1,
112 },{
113 .type = EM28XX_VMUX_SVIDEO,
114 .vmux = 9,
115 .amux = 1,
116 }},
117 },
118 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
119 .name = "Hauppauge WinTV USB 2",
120 .vchannels = 3,
121 .norm = VIDEO_MODE_NTSC,
122 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
123 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
124 .has_tuner = 1,
125 .decoder = EM28XX_TVP5150,
126 .has_msp34xx = 1,
127 /*FIXME: S-Video not tested */
128 .input = {{
129 .type = EM28XX_VMUX_TELEVISION,
130 .vmux = 0,
131 .amux = 6,
132 },{
133 .type = EM28XX_VMUX_SVIDEO,
134 .vmux = 2,
135 .amux = 1,
136 }},
137 },
138 [EM2820_BOARD_MSI_VOX_USB_2] = {
139 .name = "MSI VOX USB 2.0",
140 .vchannels = 3,
141 .norm = VIDEO_MODE_PAL,
142 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
143 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
144 .has_tuner = 1,
145 .decoder = EM28XX_SAA7114,
146 .input = {{
147 .type = EM28XX_VMUX_TELEVISION,
148 .vmux = 4,
149 .amux = 0,
150 },{
151 .type = EM28XX_VMUX_COMPOSITE1,
152 .vmux = 0,
153 .amux = 1,
154 },{
155 .type = EM28XX_VMUX_SVIDEO,
156 .vmux = 9,
157 .amux = 1,
158 }},
159 },
160 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
161 .name = "Terratec Cinergy 200 USB",
162 .is_em2800 = 1,
163 .vchannels = 3,
164 .norm = VIDEO_MODE_PAL,
165 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
166 .tda9887_conf = TDA9887_PRESENT,
167 .has_tuner = 1,
168 .decoder = EM28XX_SAA7113,
169 .input = {{
170 .type = EM28XX_VMUX_TELEVISION,
171 .vmux = 2,
172 .amux = 0,
173 },{
174 .type = EM28XX_VMUX_COMPOSITE1,
175 .vmux = 0,
176 .amux = 1,
177 },{
178 .type = EM28XX_VMUX_SVIDEO,
179 .vmux = 9,
180 .amux = 1,
181 }},
182 },
183 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
184 .name = "Leadtek Winfast USB II",
185 .is_em2800 = 1,
186 .vchannels = 3,
187 .norm = VIDEO_MODE_PAL,
188 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
189 .tda9887_conf = TDA9887_PRESENT,
190 .has_tuner = 1,
191 .decoder = EM28XX_SAA7113,
192 .input = {{
193 .type = EM28XX_VMUX_TELEVISION,
194 .vmux = 2,
195 .amux = 0,
196 },{
197 .type = EM28XX_VMUX_COMPOSITE1,
198 .vmux = 0,
199 .amux = 1,
200 },{
201 .type = EM28XX_VMUX_SVIDEO,
202 .vmux = 9,
203 .amux = 1,
204 }},
205 },
206 [EM2800_BOARD_KWORLD_USB2800] = {
207 .name = "Kworld USB2800",
208 .is_em2800 = 1,
209 .vchannels = 3,
210 .norm = VIDEO_MODE_PAL,
211 .tuner_type = TUNER_PHILIPS_ATSC,
212 .tda9887_conf = TDA9887_PRESENT,
213 .has_tuner = 1,
214 .decoder = EM28XX_SAA7113,
215 .input = {{
216 .type = EM28XX_VMUX_TELEVISION,
217 .vmux = 2,
218 .amux = 0,
219 },{
220 .type = EM28XX_VMUX_COMPOSITE1,
221 .vmux = 0,
222 .amux = 1,
223 },{
224 .type = EM28XX_VMUX_SVIDEO,
225 .vmux = 9,
226 .amux = 1,
227 }},
228 },
229 [EM2820_BOARD_PINNACLE_DVC_90] = {
230 .name = "Pinnacle Dazzle DVC 90",
231 .vchannels = 3,
232 .norm = VIDEO_MODE_PAL,
233 .has_tuner = 0,
234 .decoder = EM28XX_SAA7113,
235 .input = {{
236 .type = EM28XX_VMUX_COMPOSITE1,
237 .vmux = 0,
238 .amux = 1,
239 },{
240 .type = EM28XX_VMUX_SVIDEO,
241 .vmux = 9,
242 .amux = 1,
243 }},
244 },
245};
246const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
247
248/* table of devices that work with this driver */
249struct usb_device_id em28xx_id_table [] = {
250 { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN },
251 { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 },
252 { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
253 { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
254 { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
255 { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
256 { },
257};
258
259void em28xx_card_setup(struct em28xx *dev)
260{
261 /* request some modules */
262 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
263 struct tveeprom tv;
264 struct v4l2_audioout ao;
265#ifdef CONFIG_MODULES
266 request_module("tveeprom");
267 request_module("ir-kbd-i2c");
268 request_module("msp3400");
269#endif
270 /* Call first TVeeprom */
271
272 dev->i2c_client.addr = 0xa0 >> 1;
273 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
274
275 dev->tuner_type= tv.tuner_type;
276 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
277 dev->has_msp34xx=1;
278 memset (&ao,0,sizeof(ao));
279
280 ao.index=2;
281 ao.mode=V4L2_AUDMODE_32BITS;
282 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
283 } else
284 dev->has_msp34xx=0;
285 }
286}
287
288EXPORT_SYMBOL(em28xx_boards);
289EXPORT_SYMBOL(em28xx_bcount);
290EXPORT_SYMBOL(em28xx_id_table);
291
292MODULE_DEVICE_TABLE (usb, em28xx_id_table);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
new file mode 100644
index 000000000000..d54bc0127484
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -0,0 +1,817 @@
1/*
2 em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/usb.h>
29#include <linux/vmalloc.h>
30
31#include "em28xx.h"
32
33/* #define ENABLE_DEBUG_ISOC_FRAMES */
34
35unsigned int core_debug;
36module_param(core_debug,int,0644);
37MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
38
39#define em28xx_coredbg(fmt, arg...) do {\
40 if (core_debug) \
41 printk(KERN_INFO "%s %s :"fmt, \
42 dev->name, __FUNCTION__ , ##arg); } while (0)
43
44unsigned int reg_debug;
45module_param(reg_debug,int,0644);
46MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
47
48#define em28xx_regdbg(fmt, arg...) do {\
49 if (reg_debug) \
50 printk(KERN_INFO "%s %s :"fmt, \
51 dev->name, __FUNCTION__ , ##arg); } while (0)
52
53unsigned int isoc_debug;
54module_param(isoc_debug,int,0644);
55MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
56
57#define em28xx_isocdbg(fmt, arg...) do {\
58 if (isoc_debug) \
59 printk(KERN_INFO "%s %s :"fmt, \
60 dev->name, __FUNCTION__ , ##arg); } while (0)
61
62static int alt = EM28XX_PINOUT;
63module_param(alt, int, 0644);
64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
65
66/* ------------------------------------------------------------------ */
67/* debug help functions */
68
69static const char *v4l1_ioctls[] = {
70 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
71 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
72 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
73 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
74 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
75#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
76
77static const char *v4l2_ioctls[] = {
78 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
79 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
80 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
81 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
82 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
83 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
84 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
85 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
86 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
87 "S_MODULATOR"
88};
89#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
90
91void em28xx_print_ioctl(char *name, unsigned int cmd)
92{
93 char *dir;
94
95 switch (_IOC_DIR(cmd)) {
96 case _IOC_NONE: dir = "--"; break;
97 case _IOC_READ: dir = "r-"; break;
98 case _IOC_WRITE: dir = "-w"; break;
99 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
100 default: dir = "??"; break;
101 }
102 switch (_IOC_TYPE(cmd)) {
103 case 'v':
104 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
105 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
106 v4l1_ioctls[_IOC_NR(cmd)] : "???");
107 break;
108 case 'V':
109 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
110 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
111 v4l2_ioctls[_IOC_NR(cmd)] : "???");
112 break;
113 default:
114 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
115 name, cmd, dir, _IOC_NR(cmd));
116 }
117}
118
119static void *rvmalloc(size_t size)
120{
121 void *mem;
122 unsigned long adr;
123
124 size = PAGE_ALIGN(size);
125
126 mem = vmalloc_32((unsigned long)size);
127 if (!mem)
128 return NULL;
129
130 memset(mem, 0, size);
131
132 adr = (unsigned long)mem;
133 while (size > 0) {
134 SetPageReserved(vmalloc_to_page((void *)adr));
135 adr += PAGE_SIZE;
136 size -= PAGE_SIZE;
137 }
138
139 return mem;
140}
141
142static void rvfree(void *mem, size_t size)
143{
144 unsigned long adr;
145
146 if (!mem)
147 return;
148
149 size = PAGE_ALIGN(size);
150
151 adr = (unsigned long)mem;
152 while (size > 0) {
153 ClearPageReserved(vmalloc_to_page((void *)adr));
154 adr += PAGE_SIZE;
155 size -= PAGE_SIZE;
156 }
157
158 vfree(mem);
159}
160
161/*
162 * em28xx_request_buffers()
163 * allocate a number of buffers
164 */
165u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
166{
167 const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
168 void *buff = NULL;
169 u32 i;
170 em28xx_coredbg("requested %i buffers with size %i", count, imagesize);
171 if (count > EM28XX_NUM_FRAMES)
172 count = EM28XX_NUM_FRAMES;
173
174 dev->num_frames = count;
175 while (dev->num_frames > 0) {
176 if ((buff = rvmalloc(dev->num_frames * imagesize)))
177 break;
178 dev->num_frames--;
179 }
180
181 for (i = 0; i < dev->num_frames; i++) {
182 dev->frame[i].bufmem = buff + i * imagesize;
183 dev->frame[i].buf.index = i;
184 dev->frame[i].buf.m.offset = i * imagesize;
185 dev->frame[i].buf.length = dev->frame_size;
186 dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
187 dev->frame[i].buf.sequence = 0;
188 dev->frame[i].buf.field = V4L2_FIELD_NONE;
189 dev->frame[i].buf.memory = V4L2_MEMORY_MMAP;
190 dev->frame[i].buf.flags = 0;
191 }
192 return dev->num_frames;
193}
194
195/*
196 * em28xx_queue_unusedframes()
197 * add all frames that are not currently in use to the inbuffer queue
198 */
199void em28xx_queue_unusedframes(struct em28xx *dev)
200{
201 unsigned long lock_flags;
202 u32 i;
203
204 for (i = 0; i < dev->num_frames; i++)
205 if (dev->frame[i].state == F_UNUSED) {
206 dev->frame[i].state = F_QUEUED;
207 spin_lock_irqsave(&dev->queue_lock, lock_flags);
208 list_add_tail(&dev->frame[i].frame, &dev->inqueue);
209 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
210 }
211}
212
213/*
214 * em28xx_release_buffers()
215 * free frame buffers
216 */
217void em28xx_release_buffers(struct em28xx *dev)
218{
219 if (dev->num_frames) {
220 rvfree(dev->frame[0].bufmem,
221 dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length));
222 dev->num_frames = 0;
223 }
224}
225
226/*
227 * em28xx_read_reg_req()
228 * reads data from the usb device specifying bRequest
229 */
230int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
231 char *buf, int len)
232{
233 int ret, byte;
234
235 em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
236
237 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
238 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
239 0x0000, reg, buf, len, HZ);
240
241 if (reg_debug){
242 printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
243 for (byte = 0; byte < len; byte++) {
244 printk(" %02x", buf[byte]);
245 }
246 printk("\n");
247 }
248
249 return ret;
250}
251
252/*
253 * em28xx_read_reg_req()
254 * reads data from the usb device specifying bRequest
255 */
256int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
257{
258 u8 val;
259 int ret;
260
261 em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
262
263 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
264 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
265 0x0000, reg, &val, 1, HZ);
266
267 if (reg_debug)
268 printk(ret < 0 ? " failed!\n" : "%02x\n", val);
269
270 if (ret < 0)
271 return ret;
272
273 return val;
274}
275
276int em28xx_read_reg(struct em28xx *dev, u16 reg)
277{
278 return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
279}
280
281/*
282 * em28xx_write_regs_req()
283 * sends data to the usb device, specifying bRequest
284 */
285int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
286 int len)
287{
288 int ret;
289
290 /*usb_control_msg seems to expect a kmalloced buffer */
291 unsigned char *bufs = kmalloc(len, GFP_KERNEL);
292
293 em28xx_regdbg("req=%02x reg=%02x:", req, reg);
294
295 if (reg_debug) {
296 int i;
297 for (i = 0; i < len; ++i)
298 printk (" %02x", (unsigned char)buf[i]);
299 printk ("\n");
300 }
301
302 if (!bufs)
303 return -ENOMEM;
304 memcpy(bufs, buf, len);
305 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
306 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
307 0x0000, reg, bufs, len, HZ);
308 mdelay(5); /* FIXME: magic number */
309 kfree(bufs);
310 return ret;
311}
312
313int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
314{
315 return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
316}
317
318/*
319 * em28xx_write_reg_bits()
320 * sets only some bits (specified by bitmask) of a register, by first reading
321 * the actual value
322 */
323int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
324 u8 bitmask)
325{
326 int oldval;
327 u8 newval;
328 if ((oldval = em28xx_read_reg(dev, reg)) < 0)
329 return oldval;
330 newval = (((u8) oldval) & ~bitmask) | (val & bitmask);
331 return em28xx_write_regs(dev, reg, &newval, 1);
332}
333
334/*
335 * em28xx_write_ac97()
336 * write a 16 bit value to the specified AC97 address (LSB first!)
337 */
338int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
339{
340 int ret;
341 u8 addr = reg & 0x7f;
342 if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
343 return ret;
344 if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
345 return ret;
346 if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
347 return ret;
348 else if (((u8) ret) & 0x01) {
349 em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
350 }
351 return 0;
352}
353
354int em28xx_audio_analog_set(struct em28xx *dev)
355{
356 char s[2] = { 0x00, 0x00 };
357 s[0] |= 0x1f - dev->volume;
358 s[1] |= 0x1f - dev->volume;
359 if (dev->mute)
360 s[1] |= 0x80;
361 return em28xx_write_ac97(dev, MASTER_AC97, s);
362}
363
364
365int em28xx_colorlevels_set_default(struct em28xx *dev)
366{
367 em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */
368 em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */
369 em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */
370 em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1);
371 em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1);
372 em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1);
373
374 em28xx_write_regs(dev, GAMMA_REG, "\x20", 1);
375 em28xx_write_regs(dev, RGAIN_REG, "\x20", 1);
376 em28xx_write_regs(dev, GGAIN_REG, "\x20", 1);
377 em28xx_write_regs(dev, BGAIN_REG, "\x20", 1);
378 em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1);
379 em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1);
380 return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1);
381}
382
383int em28xx_capture_start(struct em28xx *dev, int start)
384{
385 int ret;
386 /* FIXME: which is the best order? */
387 /* video registers are sampled by VREF */
388 if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00,
389 0x10)) < 0)
390 return ret;
391 /* enable video capture */
392 return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1);
393}
394
395int em28xx_outfmt_set_yuv422(struct em28xx *dev)
396{
397 em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1);
398 em28xx_write_regs(dev, VINMODE_REG, "\x10", 1);
399 return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1);
400}
401
402int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
403 u8 ymax)
404{
405 em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax);
406
407 em28xx_write_regs(dev, XMIN_REG, &xmin, 1);
408 em28xx_write_regs(dev, XMAX_REG, &xmax, 1);
409 em28xx_write_regs(dev, YMIN_REG, &ymin, 1);
410 return em28xx_write_regs(dev, YMAX_REG, &ymax, 1);
411}
412
413int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
414 u16 width, u16 height)
415{
416 u8 cwidth = width;
417 u8 cheight = height;
418 u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01);
419
420 em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7),
421 (height | (overflow & 1) << 8));
422
423 em28xx_write_regs(dev, HSTART_REG, &hstart, 1);
424 em28xx_write_regs(dev, VSTART_REG, &vstart, 1);
425 em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1);
426 em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1);
427 return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1);
428}
429
430int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
431{
432 u8 mode;
433 /* the em2800 scaler only supports scaling down to 50% */
434 if(dev->is_em2800)
435 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
436 else {
437 u8 buf[2];
438 buf[0] = h;
439 buf[1] = h >> 8;
440 em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2);
441 buf[0] = v;
442 buf[1] = v >> 8;
443 em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2);
444 /* it seems that both H and V scalers must be active to work correctly */
445 mode = (h || v)? 0x30: 0x00;
446 }
447 return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30);
448}
449
450/* FIXME: this only function read values from dev */
451int em28xx_resolution_set(struct em28xx *dev)
452{
453 int width, height;
454 width = norm_maxw(dev);
455 height = norm_maxh(dev) >> 1;
456
457 em28xx_outfmt_set_yuv422(dev);
458 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
459 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
460 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
461}
462
463
464/******************* isoc transfer handling ****************************/
465
466#ifdef ENABLE_DEBUG_ISOC_FRAMES
467static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs)
468{
469 int len = 0;
470 int ntrans = 0;
471 int i;
472
473 printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n",
474 urb->start_frame, urb->number_of_packets,
475 urb->error_count);
476 for (i = 0; i < urb->number_of_packets; i++) {
477 unsigned char *buf =
478 urb->transfer_buffer +
479 urb->iso_frame_desc[i].offset;
480 int alen = urb->iso_frame_desc[i].actual_length;
481 if (alen > 0) {
482 if (buf[0] == 0x88) {
483 ntrans++;
484 len += alen;
485 } else if (buf[0] == 0x22) {
486 printk(KERN_DEBUG
487 "= l=%d nt=%d bpp=%d\n",
488 len - 4 * ntrans, ntrans,
489 ntrans == 0 ? 0 : len / ntrans);
490 ntrans = 1;
491 len = alen;
492 } else
493 printk(KERN_DEBUG "!\n");
494 }
495 printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i,
496 urb->iso_frame_desc[i].status,
497 urb->iso_frame_desc[i].actual_length,
498 (unsigned int)
499 *((unsigned char *)(urb->transfer_buffer +
500 urb->iso_frame_desc[i].
501 offset)));
502 }
503}
504#endif
505
506static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f,
507 unsigned long *lock_flags, unsigned char buf)
508{
509 if (!(buf & 0x01)) {
510 if ((*f)->state == F_GRABBING) {
511 /*previous frame is incomplete */
512 if ((*f)->fieldbytesused < dev->field_size) {
513 (*f)->state = F_ERROR;
514 em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)",
515 dev->field_size-(*f)->fieldbytesused);
516 } else {
517 (*f)->state = F_DONE;
518 (*f)->buf.bytesused = dev->frame_size;
519 }
520 }
521 if ((*f)->state == F_DONE || (*f)->state == F_ERROR) {
522 /* move current frame to outqueue and get next free buffer from inqueue */
523 spin_lock_irqsave(&dev-> queue_lock, *lock_flags);
524 list_move_tail(&(*f)->frame, &dev->outqueue);
525 if (!list_empty(&dev->inqueue))
526 (*f) = list_entry(dev-> inqueue.next,
527 struct em28xx_frame_t,frame);
528 else
529 (*f) = NULL;
530 spin_unlock_irqrestore(&dev->queue_lock,*lock_flags);
531 }
532 if (!(*f)) {
533 em28xx_isocdbg ("new frame but no buffer is free");
534 return -1;
535 }
536 do_gettimeofday(&(*f)->buf.timestamp);
537 (*f)->buf.sequence = ++dev->frame_count;
538 (*f)->buf.field = V4L2_FIELD_INTERLACED;
539 (*f)->state = F_GRABBING;
540 (*f)->buf.bytesused = 0;
541 (*f)->top_field = 1;
542 (*f)->fieldbytesused = 0;
543 } else {
544 /* acquiring bottom field */
545 if ((*f)->state == F_GRABBING) {
546 if (!(*f)->top_field) {
547 (*f)->state = F_ERROR;
548 em28xx_isocdbg ("unexpected begin of bottom field; discarding it");
549 } else if ((*f)-> fieldbytesused < dev->field_size - 172) {
550 (*f)->state = F_ERROR;
551 em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)",
552 dev->field_size-(*f)->fieldbytesused);
553 } else {
554 (*f)->top_field = 0;
555 (*f)->fieldbytesused = 0;
556 }
557 }
558 }
559 return (0);
560}
561
562static inline void em28xx_isoc_video_copy(struct em28xx *dev,
563 struct em28xx_frame_t **f, unsigned char *buf, int len)
564{
565 void *fieldstart, *startwrite, *startread;
566 int linesdone, currlinedone, offset, lencopy,remain;
567
568 if(dev->frame_size != (*f)->buf.length){
569 em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length);
570 return;
571 }
572
573 if ((*f)->fieldbytesused + len > dev->field_size)
574 len =dev->field_size - (*f)->fieldbytesused;
575
576 if (buf[0] != 0x88 && buf[0] != 0x22) {
577 em28xx_isocdbg("frame is not complete\n");
578 startread = buf;
579 len+=4;
580 } else
581 startread = buf + 4;
582
583 remain = len;
584
585 if ((*f)->top_field)
586 fieldstart = (*f)->bufmem;
587 else
588 fieldstart = (*f)->bufmem + dev->bytesperline;
589
590 linesdone = (*f)->fieldbytesused / dev->bytesperline;
591 currlinedone = (*f)->fieldbytesused % dev->bytesperline;
592 offset = linesdone * dev->bytesperline * 2 + currlinedone;
593 startwrite = fieldstart + offset;
594 lencopy = dev->bytesperline - currlinedone;
595 lencopy = lencopy > remain ? remain : lencopy;
596
597 memcpy(startwrite, startread, lencopy);
598 remain -= lencopy;
599
600 while (remain > 0) {
601 startwrite += lencopy + dev->bytesperline;
602 startread += lencopy;
603 if (dev->bytesperline > remain)
604 lencopy = remain;
605 else
606 lencopy = dev->bytesperline;
607
608 memcpy(startwrite, startread, lencopy);
609 remain -= lencopy;
610 }
611
612 (*f)->fieldbytesused += len;
613}
614
615/*
616 * em28xx_isoIrq()
617 * handles the incoming isoc urbs and fills the frames from our inqueue
618 */
619void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
620{
621 struct em28xx *dev = urb->context;
622 int i, status;
623 struct em28xx_frame_t **f;
624 unsigned long lock_flags;
625
626 if (!dev)
627 return;
628#ifdef ENABLE_DEBUG_ISOC_FRAMES
629 if (isoc_debug>1)
630 em28xx_isoc_dump(urb, regs);
631#endif
632
633 if (urb->status == -ENOENT)
634 return;
635
636 f = &dev->frame_current;
637
638 if (dev->stream == STREAM_INTERRUPT) {
639 dev->stream = STREAM_OFF;
640 if ((*f))
641 (*f)->state = F_QUEUED;
642 em28xx_isocdbg("stream interrupted");
643 wake_up_interruptible(&dev->wait_stream);
644 }
645
646 if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
647 return;
648
649 if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) {
650 if (!(*f))
651 (*f) = list_entry(dev->inqueue.next,
652 struct em28xx_frame_t, frame);
653
654 for (i = 0; i < urb->number_of_packets; i++) {
655 unsigned char *buf = urb->transfer_buffer +
656 urb->iso_frame_desc[i].offset;
657 int len = urb->iso_frame_desc[i].actual_length - 4;
658
659 if (urb->iso_frame_desc[i].status) {
660 em28xx_isocdbg("data error: [%d] len=%d, status=%d", i,
661 urb->iso_frame_desc[i].actual_length,
662 urb->iso_frame_desc[i].status);
663 if (urb->iso_frame_desc[i].status != -EPROTO)
664 continue;
665 }
666 if (urb->iso_frame_desc[i].actual_length <= 0) {
667 em28xx_isocdbg("packet %d is empty",i);
668 continue;
669 }
670 if (urb->iso_frame_desc[i].actual_length >
671 dev->max_pkt_size) {
672 em28xx_isocdbg("packet bigger than packet size");
673 continue;
674 }
675 /*new frame */
676 if (buf[0] == 0x22 && buf[1] == 0x5a) {
677 em28xx_isocdbg("Video frame, length=%i!",len);
678
679 if (em28xx_isoc_video(dev,f,&lock_flags,buf[2]))
680 break;
681 } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) {
682 em28xx_isocdbg("VBI HEADER!!!");
683 }
684
685 /* actual copying */
686 if ((*f)->state == F_GRABBING) {
687 em28xx_isoc_video_copy(dev,f,buf, len);
688 }
689 }
690 }
691
692 for (i = 0; i < urb->number_of_packets; i++) {
693 urb->iso_frame_desc[i].status = 0;
694 urb->iso_frame_desc[i].actual_length = 0;
695 }
696
697 urb->status = 0;
698 if ((status = usb_submit_urb(urb, GFP_ATOMIC))) {
699 em28xx_errdev("resubmit of urb failed (error=%i)\n", status);
700 dev->state |= DEV_MISCONFIGURED;
701 }
702 wake_up_interruptible(&dev->wait_frame);
703 return;
704}
705
706/*
707 * em28xx_uninit_isoc()
708 * deallocates the buffers and urbs allocated during em28xx_init_iosc()
709 */
710void em28xx_uninit_isoc(struct em28xx *dev)
711{
712 int i;
713
714 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
715 if (dev->urb[i]) {
716 usb_kill_urb(dev->urb[i]);
717 if (dev->transfer_buffer[i]){
718 usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
719 }
720 usb_free_urb(dev->urb[i]);
721 }
722 dev->urb[i] = NULL;
723 dev->transfer_buffer[i] = NULL;
724 }
725 em28xx_capture_start(dev, 0);
726}
727
728/*
729 * em28xx_init_isoc()
730 * allocates transfer buffers and submits the urbs for isoc transfer
731 */
732int em28xx_init_isoc(struct em28xx *dev)
733{
734 /* change interface to 3 which allowes the biggest packet sizes */
735 int i, errCode;
736 const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
737
738 /* reset streaming vars */
739 dev->frame_current = NULL;
740 dev->frame_count = 0;
741
742 /* allocate urbs */
743 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
744 struct urb *urb;
745 int j, k;
746 /* allocate transfer buffer */
747 urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
748 if (!urb){
749 em28xx_errdev("cannot alloc urb %i\n", i);
750 em28xx_uninit_isoc(dev);
751 return -ENOMEM;
752 }
753 dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
754 if (!dev->transfer_buffer[i]) {
755 em28xx_errdev
756 ("unable to allocate %i bytes for transfer buffer %i\n",
757 sb_size, i);
758 em28xx_uninit_isoc(dev);
759 return -ENOMEM;
760 }
761 memset(dev->transfer_buffer[i], 0, sb_size);
762 urb->dev = dev->udev;
763 urb->context = dev;
764 urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
765 urb->transfer_flags = URB_ISO_ASAP;
766 urb->interval = 1;
767 urb->transfer_buffer = dev->transfer_buffer[i];
768 urb->complete = em28xx_isocIrq;
769 urb->number_of_packets = EM28XX_NUM_PACKETS;
770 urb->transfer_buffer_length = sb_size;
771 for (j = k = 0; j < EM28XX_NUM_PACKETS;
772 j++, k += dev->max_pkt_size) {
773 urb->iso_frame_desc[j].offset = k;
774 urb->iso_frame_desc[j].length =
775 dev->max_pkt_size;
776 }
777 dev->urb[i] = urb;
778 }
779
780 /* submit urbs */
781 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
782 errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
783 if (errCode) {
784 em28xx_errdev("submit of urb %i failed (error=%i)\n", i,
785 errCode);
786 em28xx_uninit_isoc(dev);
787 return errCode;
788 }
789 }
790
791 return 0;
792}
793
794int em28xx_set_alternate(struct em28xx *dev)
795{
796 int errCode, prev_alt = dev->alt;
797 dev->alt = alt;
798 if (dev->alt == 0) {
799 int i;
800 for(i=0;i< dev->num_alt; i++)
801 if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
802 dev->alt=i;
803 }
804
805 if (dev->alt != prev_alt) {
806 dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
807 em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
808 dev->max_pkt_size);
809 errCode = usb_set_interface(dev->udev, 0, dev->alt);
810 if (errCode < 0) {
811 em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
812 dev->alt, errCode);
813 return errCode;
814 }
815 }
816 return 0;
817}
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
new file mode 100644
index 000000000000..b32d9852f34c
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -0,0 +1,586 @@
1/*
2 em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/usb.h>
27#include <linux/i2c.h>
28#include <linux/video_decoder.h>
29
30#include "em28xx.h"
31#include <media/tuner.h>
32
33/* ----------------------------------------------------------- */
34
35static unsigned int i2c_scan = 0;
36module_param(i2c_scan, int, 0444);
37MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
38
39static unsigned int i2c_debug = 0;
40module_param(i2c_debug, int, 0644);
41MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
42
43#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\
44 printk(fmt , ##args); } while (0)
45#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
46 printk(KERN_DEBUG "%s at %s: " fmt, \
47 dev->name, __FUNCTION__ , ##args); } while (0)
48
49/*
50 * em2800_i2c_send_max4()
51 * send up to 4 bytes to the i2c device
52 */
53static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
54 char *buf, int len)
55{
56 int ret;
57 int write_timeout;
58 unsigned char b2[6];
59 BUG_ON(len < 1 || len > 4);
60 b2[5] = 0x80 + len - 1;
61 b2[4] = addr;
62 b2[3] = buf[0];
63 if (len > 1)
64 b2[2] = buf[1];
65 if (len > 2)
66 b2[1] = buf[2];
67 if (len > 3)
68 b2[0] = buf[3];
69
70 ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
71 if (ret != 2 + len) {
72 em28xx_warn("writting to i2c device failed (error=%i)\n", ret);
73 return -EIO;
74 }
75 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
76 write_timeout -= 5) {
77 ret = dev->em28xx_read_reg(dev, 0x05);
78 if (ret == 0x80 + len - 1)
79 return len;
80 mdelay(5);
81 }
82 em28xx_warn("i2c write timed out\n");
83 return -EIO;
84}
85
86/*
87 * em2800_i2c_send_bytes()
88 */
89static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,
90 short len)
91{
92 char *bufPtr = buf;
93 int ret;
94 int wrcount = 0;
95 int count;
96 int maxLen = 4;
97 struct em28xx *dev = (struct em28xx *)data;
98 while (len > 0) {
99 count = (len > maxLen) ? maxLen : len;
100 ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);
101 if (ret > 0) {
102 len -= count;
103 bufPtr += count;
104 wrcount += count;
105 } else
106 return (ret < 0) ? ret : -EFAULT;
107 }
108 return wrcount;
109}
110
111/*
112 * em2800_i2c_check_for_device()
113 * check if there is a i2c_device at the supplied address
114 */
115static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
116{
117 char msg;
118 int ret;
119 int write_timeout;
120 msg = addr;
121 ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1);
122 if (ret < 0) {
123 em28xx_warn("setting i2c device address failed (error=%i)\n",
124 ret);
125 return ret;
126 }
127 msg = 0x84;
128 ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1);
129 if (ret < 0) {
130 em28xx_warn("preparing i2c read failed (error=%i)\n", ret);
131 return ret;
132 }
133 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
134 write_timeout -= 5) {
135 unsigned msg = dev->em28xx_read_reg(dev, 0x5);
136 if (msg == 0x94)
137 return -ENODEV;
138 else if (msg == 0x84)
139 return 0;
140 mdelay(5);
141 }
142 return -ENODEV;
143}
144
145/*
146 * em2800_i2c_recv_bytes()
147 * read from the i2c device
148 */
149static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
150 char *buf, int len)
151{
152 int ret;
153 /* check for the device and set i2c read address */
154 ret = em2800_i2c_check_for_device(dev, addr);
155 if (ret) {
156 em28xx_warn
157 ("preparing read at i2c address 0x%x failed (error=%i)\n",
158 addr, ret);
159 return ret;
160 }
161 ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len);
162 if (ret < 0) {
163 em28xx_warn("reading from i2c device at 0x%x failed (error=%i)",
164 addr, ret);
165 return ret;
166 }
167 return ret;
168}
169
170/*
171 * em28xx_i2c_send_bytes()
172 * untested for more than 4 bytes
173 */
174static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf,
175 short len, int stop)
176{
177 int wrcount = 0;
178 struct em28xx *dev = (struct em28xx *)data;
179
180 wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
181
182 return wrcount;
183}
184
185/*
186 * em28xx_i2c_recv_bytes()
187 * read a byte from the i2c device
188 */
189static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
190 char *buf, int len)
191{
192 int ret;
193 ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
194 if (ret < 0) {
195 em28xx_warn("reading i2c device failed (error=%i)\n", ret);
196 return ret;
197 }
198 if (dev->em28xx_read_reg(dev, 0x5) != 0)
199 return -ENODEV;
200 return ret;
201}
202
203/*
204 * em28xx_i2c_check_for_device()
205 * check if there is a i2c_device at the supplied address
206 */
207static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
208{
209 char msg;
210 int ret;
211 msg = addr;
212
213 ret = dev->em28xx_read_reg_req(dev, 2, addr);
214 if (ret < 0) {
215 em28xx_warn("reading from i2c device failed (error=%i)\n", ret);
216 return ret;
217 }
218 if (dev->em28xx_read_reg(dev, 0x5) != 0)
219 return -ENODEV;
220 return 0;
221}
222
223/*
224 * em28xx_i2c_xfer()
225 * the main i2c transfer function
226 */
227static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
228 struct i2c_msg msgs[], int num)
229{
230 struct em28xx *dev = i2c_adap->algo_data;
231 int addr, rc, i, byte;
232
233 if (num <= 0)
234 return 0;
235 for (i = 0; i < num; i++) {
236 addr = msgs[i].addr << 1;
237 dprintk2(2,"%s %s addr=%x len=%d:",
238 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
239 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
240 if (!msgs[i].len) { /* no len: check only for device presence */
241 if (dev->is_em2800)
242 rc = em2800_i2c_check_for_device(dev, addr);
243 else
244 rc = em28xx_i2c_check_for_device(dev, addr);
245 if (rc < 0) {
246 dprintk2(2," no device\n");
247 return rc;
248 }
249
250 } else if (msgs[i].flags & I2C_M_RD) {
251 /* read bytes */
252 if (dev->is_em2800)
253 rc = em2800_i2c_recv_bytes(dev, addr,
254 msgs[i].buf,
255 msgs[i].len);
256 else
257 rc = em28xx_i2c_recv_bytes(dev, addr,
258 msgs[i].buf,
259 msgs[i].len);
260 if (i2c_debug>=2) {
261 for (byte = 0; byte < msgs[i].len; byte++) {
262 printk(" %02x", msgs[i].buf[byte]);
263 }
264 }
265 } else {
266 /* write bytes */
267 if (i2c_debug>=2) {
268 for (byte = 0; byte < msgs[i].len; byte++)
269 printk(" %02x", msgs[i].buf[byte]);
270 }
271 if (dev->is_em2800)
272 rc = em2800_i2c_send_bytes(dev, addr,
273 msgs[i].buf,
274 msgs[i].len);
275 else
276 rc = em28xx_i2c_send_bytes(dev, addr,
277 msgs[i].buf,
278 msgs[i].len,
279 i == num - 1);
280 if (rc < 0)
281 goto err;
282 }
283 if (i2c_debug>=2)
284 printk("\n");
285 }
286
287 return num;
288 err:
289 dprintk2(2," ERROR: %i\n", rc);
290 return rc;
291}
292
293static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
294{
295 unsigned char buf, *p = eedata;
296 struct em28xx_eeprom *em_eeprom = (void *)eedata;
297 int i, err, size = len, block;
298
299 dev->i2c_client.addr = 0xa0 >> 1;
300
301 /* Check if board has eeprom */
302 err = i2c_master_recv(&dev->i2c_client, &buf, 0);
303 if (err < 0)
304 return -1;
305
306 buf = 0;
307 if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) {
308 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
309 dev->name, err);
310 return -1;
311 }
312 while (size > 0) {
313 if (size > 16)
314 block = 16;
315 else
316 block = size;
317
318 if (block !=
319 (err = i2c_master_recv(&dev->i2c_client, p, block))) {
320 printk(KERN_WARNING
321 "%s: i2c eeprom read error (err=%d)\n",
322 dev->name, err);
323 return -1;
324 }
325 size -= block;
326 p += block;
327 }
328 for (i = 0; i < len; i++) {
329 if (0 == (i % 16))
330 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
331 printk(" %02x", eedata[i]);
332 if (15 == (i % 16))
333 printk("\n");
334 }
335
336 printk(KERN_INFO "EEPROM ID= 0x%08x\n", em_eeprom->id);
337 printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID,
338 em_eeprom->product_ID);
339
340 switch (em_eeprom->chip_conf >> 4 & 0x3) {
341 case 0:
342 printk(KERN_INFO "No audio on board.\n");
343 break;
344 case 1:
345 printk(KERN_INFO "AC97 audio (5 sample rates)\n");
346 break;
347 case 2:
348 printk(KERN_INFO "I2S audio, sample rate=32k\n");
349 break;
350 case 3:
351 printk(KERN_INFO "I2S audio, 3 sample rates\n");
352 break;
353 }
354
355 if (em_eeprom->chip_conf & 1 << 3)
356 printk(KERN_INFO "USB Remote wakeup capable\n");
357
358 if (em_eeprom->chip_conf & 1 << 2)
359 printk(KERN_INFO "USB Self power capable\n");
360
361 switch (em_eeprom->chip_conf & 0x3) {
362 case 0:
363 printk(KERN_INFO "500mA max power\n");
364 break;
365 case 1:
366 printk(KERN_INFO "400mA max power\n");
367 break;
368 case 2:
369 printk(KERN_INFO "300mA max power\n");
370 break;
371 case 3:
372 printk(KERN_INFO "200mA max power\n");
373 break;
374 }
375 printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
376 em_eeprom->string_idx_table,em_eeprom->string1,
377 em_eeprom->string2,em_eeprom->string3);
378
379 return 0;
380}
381
382/* ----------------------------------------------------------- */
383
384/*
385 * algo_control()
386 */
387static int algo_control(struct i2c_adapter *adapter,
388 unsigned int cmd, unsigned long arg)
389{
390 return 0;
391}
392
393/*
394 * functionality()
395 */
396static u32 functionality(struct i2c_adapter *adap)
397{
398 return I2C_FUNC_SMBUS_EMUL;
399}
400
401#ifndef I2C_PEC
402static void inc_use(struct i2c_adapter *adap)
403{
404 MOD_INC_USE_COUNT;
405}
406
407static void dec_use(struct i2c_adapter *adap)
408{
409 MOD_DEC_USE_COUNT;
410}
411#endif
412
413static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
414{
415 struct em28xx *dev = client->adapter->algo_data;
416 struct tuner_setup tun_setup;
417
418 if (dev->has_tuner) {
419 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
420 tun_setup.type = dev->tuner_type;
421 tun_setup.addr = dev->tuner_addr;
422
423 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
424 }
425
426 return (0);
427}
428
429/*
430 * attach_inform()
431 * gets called when a device attaches to the i2c bus
432 * does some basic configuration
433 */
434static int attach_inform(struct i2c_client *client)
435{
436 struct em28xx *dev = client->adapter->algo_data;
437
438 switch (client->addr << 1) {
439 case 0x86:
440 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
441 break;
442 case 0x42:
443 dprintk1(1,"attach_inform: saa7114 detected.\n");
444 break;
445 case 0x4a:
446 dprintk1(1,"attach_inform: saa7113 detected.\n");
447 break;
448 case 0xa0:
449 dprintk1(1,"attach_inform: eeprom detected.\n");
450 break;
451 case 0x60:
452 case 0x8e:
453 {
454 struct IR_i2c *ir = i2c_get_clientdata(client);
455 dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys);
456 em28xx_set_ir(dev,ir);
457 break;
458 }
459 case 0x80:
460 case 0x88:
461 dprintk1(1,"attach_inform: msp34xx detected.\n");
462 break;
463 case 0xb8:
464 case 0xba:
465 dprintk1(1,"attach_inform: tvp5150 detected.\n");
466 break;
467 default:
468 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
469 dev->tuner_addr = client->addr;
470 em28xx_set_tuner(-1, client);
471 }
472
473 return 0;
474}
475
476static struct i2c_algorithm em28xx_algo = {
477 .master_xfer = em28xx_i2c_xfer,
478 .algo_control = algo_control,
479 .functionality = functionality,
480};
481
482static struct i2c_adapter em28xx_adap_template = {
483#ifdef I2C_PEC
484 .owner = THIS_MODULE,
485#else
486 .inc_use = inc_use,
487 .dec_use = dec_use,
488#endif
489#ifdef I2C_CLASS_TV_ANALOG
490 .class = I2C_CLASS_TV_ANALOG,
491#endif
492 .name = "em28xx",
493 .id = I2C_HW_B_EM28XX,
494 .algo = &em28xx_algo,
495 .client_register = attach_inform,
496};
497
498static struct i2c_client em28xx_client_template = {
499 .name = "em28xx internal",
500 .flags = I2C_CLIENT_ALLOW_USE,
501};
502
503/* ----------------------------------------------------------- */
504
505/*
506 * i2c_devs
507 * incomplete list of known devices
508 */
509static char *i2c_devs[128] = {
510 [0x4a >> 1] = "saa7113h",
511 [0x60 >> 1] = "remote IR sensor",
512 [0x8e >> 1] = "remote IR sensor",
513 [0x86 >> 1] = "tda9887",
514 [0x80 >> 1] = "msp34xx",
515 [0x88 >> 1] = "msp34xx",
516 [0xa0 >> 1] = "eeprom",
517 [0xb8 >> 1] = "tvp5150a",
518 [0xba >> 1] = "tvp5150a",
519 [0xc0 >> 1] = "tuner (analog)",
520 [0xc2 >> 1] = "tuner (analog)",
521 [0xc4 >> 1] = "tuner (analog)",
522 [0xc6 >> 1] = "tuner (analog)",
523};
524
525/*
526 * do_i2c_scan()
527 * check i2c address range for devices
528 */
529static void do_i2c_scan(char *name, struct i2c_client *c)
530{
531 unsigned char buf;
532 int i, rc;
533
534 for (i = 0; i < 128; i++) {
535 c->addr = i;
536 rc = i2c_master_recv(c, &buf, 0);
537 if (rc < 0)
538 continue;
539 printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name,
540 i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
541 }
542}
543
544/*
545 * em28xx_i2c_call_clients()
546 * send commands to all attached i2c devices
547 */
548void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
549{
550 BUG_ON(NULL == dev->i2c_adap.algo_data);
551 i2c_clients_command(&dev->i2c_adap, cmd, arg);
552}
553
554/*
555 * em28xx_i2c_register()
556 * register i2c bus
557 */
558int em28xx_i2c_register(struct em28xx *dev)
559{
560 BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);
561 BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);
562 dev->i2c_adap = em28xx_adap_template;
563 dev->i2c_adap.dev.parent = &dev->udev->dev;
564 strcpy(dev->i2c_adap.name, dev->name);
565 dev->i2c_adap.algo_data = dev;
566 i2c_add_adapter(&dev->i2c_adap);
567
568 dev->i2c_client = em28xx_client_template;
569 dev->i2c_client.adapter = &dev->i2c_adap;
570
571 em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
572
573 if (i2c_scan)
574 do_i2c_scan(dev->name, &dev->i2c_client);
575 return 0;
576}
577
578/*
579 * em28xx_i2c_unregister()
580 * unregister i2c_bus
581 */
582int em28xx_i2c_unregister(struct em28xx *dev)
583{
584 i2c_del_adapter(&dev->i2c_adap);
585 return 0;
586}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
new file mode 100644
index 000000000000..32c49df58adc
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -0,0 +1,184 @@
1/*
2 handle em28xx IR remotes via linux kernel input layer.
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/sched.h>
29#include <linux/interrupt.h>
30#include <linux/input.h>
31#include <linux/usb.h>
32
33#include "em28xx.h"
34
35static unsigned int disable_ir = 0;
36module_param(disable_ir, int, 0444);
37MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
38
39static unsigned int ir_debug = 0;
40module_param(ir_debug, int, 0644);
41MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
42
43#define dprintk(fmt, arg...) if (ir_debug) \
44 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
45
46/* ---------------------------------------------------------------------- */
47
48static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
49 [ 0x01 ] = KEY_CHANNEL,
50 [ 0x02 ] = KEY_SELECT,
51 [ 0x03 ] = KEY_MUTE,
52 [ 0x04 ] = KEY_POWER,
53 [ 0x05 ] = KEY_KP1,
54 [ 0x06 ] = KEY_KP2,
55 [ 0x07 ] = KEY_KP3,
56 [ 0x08 ] = KEY_CHANNELUP,
57 [ 0x09 ] = KEY_KP4,
58 [ 0x0a ] = KEY_KP5,
59 [ 0x0b ] = KEY_KP6,
60 [ 0x0c ] = KEY_CHANNELDOWN,
61 [ 0x0d ] = KEY_KP7,
62 [ 0x0e ] = KEY_KP8,
63 [ 0x0f ] = KEY_KP9,
64 [ 0x10 ] = KEY_VOLUMEUP,
65 [ 0x11 ] = KEY_KP0,
66 [ 0x12 ] = KEY_MENU,
67 [ 0x13 ] = KEY_PRINT,
68 [ 0x14 ] = KEY_VOLUMEDOWN,
69 [ 0x16 ] = KEY_PAUSE,
70 [ 0x18 ] = KEY_RECORD,
71 [ 0x19 ] = KEY_REWIND,
72 [ 0x1a ] = KEY_PLAY,
73 [ 0x1b ] = KEY_FORWARD,
74 [ 0x1c ] = KEY_BACKSPACE,
75 [ 0x1e ] = KEY_STOP,
76 [ 0x40 ] = KEY_ZOOM,
77};
78
79/* ----------------------------------------------------------------------- */
80
81static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
82{
83 unsigned char b;
84
85 /* poll IR chip */
86 if (1 != i2c_master_recv(&ir->c,&b,1)) {
87 dprintk("read error\n");
88 return -EIO;
89 }
90
91 /* it seems that 0xFE indicates that a button is still hold
92 down, while 0xff indicates that no button is hold
93 down. 0xfe sequences are sometimes interrupted by 0xFF */
94
95 dprintk("key %02x\n", b);
96
97 if (b == 0xff)
98 return 0;
99
100 if (b == 0xfe)
101 /* keep old data */
102 return 1;
103
104 *ir_key = b;
105 *ir_raw = b;
106 return 1;
107}
108
109
110static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
111{
112 unsigned char buf[2];
113 unsigned char code;
114
115 /* poll IR chip */
116 if (2 != i2c_master_recv(&ir->c,buf,2))
117 return -EIO;
118
119 /* Does eliminate repeated parity code */
120 if (buf[1]==0xff)
121 return 0;
122
123 /* avoid fast reapeating */
124 if (buf[1]==ir->old)
125 return 0;
126 ir->old=buf[1];
127
128 /* Rearranges bits to the right order */
129 code= ((buf[0]&0x01)<<5) | /* 0010 0000 */
130 ((buf[0]&0x02)<<3) | /* 0001 0000 */
131 ((buf[0]&0x04)<<1) | /* 0000 1000 */
132 ((buf[0]&0x08)>>1) | /* 0000 0100 */
133 ((buf[0]&0x10)>>3) | /* 0000 0010 */
134 ((buf[0]&0x20)>>5); /* 0000 0001 */
135
136 dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]);
137
138 /* return key */
139 *ir_key = code;
140 *ir_raw = code;
141 return 1;
142}
143
144/* ----------------------------------------------------------------------- */
145void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir)
146{
147 if (disable_ir) {
148 ir->get_key=NULL;
149 return ;
150 }
151
152 /* detect & configure */
153 switch (dev->model) {
154 case (EM2800_BOARD_UNKNOWN):
155 break;
156 case (EM2820_BOARD_UNKNOWN):
157 break;
158 case (EM2800_BOARD_TERRATEC_CINERGY_200):
159 case (EM2820_BOARD_TERRATEC_CINERGY_250):
160 ir->ir_codes = ir_codes_em_terratec;
161 ir->get_key = get_key_terratec;
162 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)");
163 break;
164 case (EM2820_BOARD_PINNACLE_USB_2):
165 break;
166 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
167 ir->ir_codes = ir_codes_hauppauge_new;
168 ir->get_key = get_key_em_haup;
169 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)");
170 break;
171 case (EM2820_BOARD_MSI_VOX_USB_2):
172 break;
173 case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
174 break;
175 case (EM2800_BOARD_KWORLD_USB2800):
176 break;
177 }
178}
179
180/* ----------------------------------------------------------------------
181 * Local variables:
182 * c-basic-offset: 8
183 * End:
184 */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
new file mode 100644
index 000000000000..57c1826b928e
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -0,0 +1,1933 @@
1/*
2 em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/usb.h>
29#include <linux/i2c.h>
30#include <linux/version.h>
31#include <linux/video_decoder.h>
32
33#include "em28xx.h"
34#include <media/tuner.h>
35
36#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
37 "Markus Rechberger <mrechberger@gmail.com>, " \
38 "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \
39 "Sascha Sommer <saschasommer@freenet.de>"
40
41#define DRIVER_NAME "em28xx"
42#define DRIVER_DESC "Empia em28xx based USB video device driver"
43#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 0, 1)
44
45#define em28xx_videodbg(fmt, arg...) do {\
46 if (video_debug) \
47 printk(KERN_INFO "%s %s :"fmt, \
48 dev->name, __FUNCTION__ , ##arg); } while (0)
49
50MODULE_AUTHOR(DRIVER_AUTHOR);
51MODULE_DESCRIPTION(DRIVER_DESC);
52MODULE_LICENSE("GPL");
53
54static LIST_HEAD(em28xx_devlist);
55
56static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
57module_param_array(card, int, NULL, 0444);
58MODULE_PARM_DESC(card,"card type");
59
60static int tuner = -1;
61module_param(tuner, int, 0444);
62MODULE_PARM_DESC(tuner, "tuner type");
63
64static unsigned int video_debug = 0;
65module_param(video_debug,int,0644);
66MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
67
68/* supported tv norms */
69static struct em28xx_tvnorm tvnorms[] = {
70 {
71 .name = "PAL",
72 .id = V4L2_STD_PAL,
73 .mode = VIDEO_MODE_PAL,
74 }, {
75 .name = "NTSC",
76 .id = V4L2_STD_NTSC,
77 .mode = VIDEO_MODE_NTSC,
78 }, {
79 .name = "SECAM",
80 .id = V4L2_STD_SECAM,
81 .mode = VIDEO_MODE_SECAM,
82 }, {
83 .name = "PAL-M",
84 .id = V4L2_STD_PAL_M,
85 .mode = VIDEO_MODE_PAL,
86 }
87};
88
89static const unsigned char saa7114_i2c_init[] = {
90 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0,
91 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a,
92 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42,
93 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff,
94 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff,
95 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff,
96 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00,
97 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00,
98 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0,
99 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06,
100 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67,
101 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd,
102 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00,
103 0xbe,0x00,0xbf,0x00
104};
105
106#define TVNORMS ARRAY_SIZE(tvnorms)
107
108/* supported controls */
109static struct v4l2_queryctrl em28xx_qctrl[] = {
110 {
111 .id = V4L2_CID_BRIGHTNESS,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Brightness",
114 .minimum = -128,
115 .maximum = 127,
116 .step = 1,
117 .default_value = 0,
118 .flags = 0,
119 },{
120 .id = V4L2_CID_CONTRAST,
121 .type = V4L2_CTRL_TYPE_INTEGER,
122 .name = "Contrast",
123 .minimum = 0x0,
124 .maximum = 0x1f,
125 .step = 0x1,
126 .default_value = 0x10,
127 .flags = 0,
128 },{
129 .id = V4L2_CID_SATURATION,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Saturation",
132 .minimum = 0x0,
133 .maximum = 0x1f,
134 .step = 0x1,
135 .default_value = 0x10,
136 .flags = 0,
137 },{
138 .id = V4L2_CID_AUDIO_VOLUME,
139 .type = V4L2_CTRL_TYPE_INTEGER,
140 .name = "Volume",
141 .minimum = 0x0,
142 .maximum = 0x1f,
143 .step = 0x1,
144 .default_value = 0x1f,
145 .flags = 0,
146 },{
147 .id = V4L2_CID_AUDIO_MUTE,
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .name = "Mute",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153 .default_value = 1,
154 .flags = 0,
155 },{
156 .id = V4L2_CID_RED_BALANCE,
157 .type = V4L2_CTRL_TYPE_INTEGER,
158 .name = "Red chroma balance",
159 .minimum = -128,
160 .maximum = 127,
161 .step = 1,
162 .default_value = 0,
163 .flags = 0,
164 },{
165 .id = V4L2_CID_BLUE_BALANCE,
166 .type = V4L2_CTRL_TYPE_INTEGER,
167 .name = "Blue chroma balance",
168 .minimum = -128,
169 .maximum = 127,
170 .step = 1,
171 .default_value = 0,
172 .flags = 0,
173 },{
174 .id = V4L2_CID_GAMMA,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "Gamma",
177 .minimum = 0x0,
178 .maximum = 0x3f,
179 .step = 0x1,
180 .default_value = 0x20,
181 .flags = 0,
182 }
183};
184
185static struct usb_driver em28xx_usb_driver;
186
187static DECLARE_MUTEX(em28xx_sysfs_lock);
188static DECLARE_RWSEM(em28xx_disconnect);
189
190/********************* v4l2 interface ******************************************/
191
192static inline unsigned long kvirt_to_pa(unsigned long adr)
193{
194 unsigned long kva, ret;
195
196 kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
197 kva |= adr & (PAGE_SIZE - 1);
198 ret = __pa(kva);
199 return ret;
200}
201
202/*
203 * em28xx_config()
204 * inits registers with sane defaults
205 */
206static int em28xx_config(struct em28xx *dev)
207{
208
209 /* Sets I2C speed to 100 KHz */
210 em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
211
212 /* enable vbi capturing */
213 em28xx_audio_usb_mute(dev, 1);
214 dev->mute = 1; /* maybe not the right place... */
215 dev->volume = 0x1f;
216 em28xx_audio_analog_set(dev);
217 em28xx_audio_analog_setup(dev);
218 em28xx_outfmt_set_yuv422(dev);
219 em28xx_colorlevels_set_default(dev);
220 em28xx_compression_disable(dev);
221
222 return 0;
223}
224
225/*
226 * em28xx_config_i2c()
227 * configure i2c attached devices
228 */
229void em28xx_config_i2c(struct em28xx *dev)
230{
231 struct v4l2_frequency f;
232 struct video_decoder_init em28xx_vdi = {.data = NULL };
233
234
235 /* configure decoder */
236 if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){
237 em28xx_vdi.data=saa7114_i2c_init;
238 em28xx_vdi.len=sizeof(saa7114_i2c_init);
239 }
240
241
242 em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi);
243 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input);
244/* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */
245/* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */
246/* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */
247/* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */
248
249 /* configure tuner */
250 f.tuner = 0;
251 f.type = V4L2_TUNER_ANALOG_TV;
252 f.frequency = 9076; /* FIXME:remove magic number */
253 dev->ctl_freq = f.frequency;
254 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
255
256 /* configure tda9887 */
257
258
259/* em28xx_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */
260}
261
262/*
263 * em28xx_empty_framequeues()
264 * prepare queues for incoming and outgoing frames
265 */
266static void em28xx_empty_framequeues(struct em28xx *dev)
267{
268 u32 i;
269
270 INIT_LIST_HEAD(&dev->inqueue);
271 INIT_LIST_HEAD(&dev->outqueue);
272
273 for (i = 0; i < EM28XX_NUM_FRAMES; i++) {
274 dev->frame[i].state = F_UNUSED;
275 dev->frame[i].buf.bytesused = 0;
276 }
277}
278
279static void video_mux(struct em28xx *dev, int index)
280{
281 int input, ainput;
282
283 input = INPUT(index)->vmux;
284 dev->ctl_input = index;
285 dev->ctl_ainput = INPUT(index)->amux;
286
287 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
288
289
290 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
291
292 if (dev->has_msp34xx) {
293 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
294 ainput = EM28XX_AUDIO_SRC_TUNER;
295 em28xx_audio_source(dev, ainput);
296 } else {
297 switch (dev->ctl_ainput) {
298 case 0:
299 ainput = EM28XX_AUDIO_SRC_TUNER;
300 break;
301 default:
302 ainput = EM28XX_AUDIO_SRC_LINE;
303 }
304 em28xx_audio_source(dev, ainput);
305 }
306}
307
308/*
309 * em28xx_v4l2_open()
310 * inits the device and starts isoc transfer
311 */
312static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
313{
314 int minor = iminor(inode);
315 int errCode = 0;
316 struct em28xx *h,*dev = NULL;
317 struct list_head *list;
318
319 list_for_each(list,&em28xx_devlist) {
320 h = list_entry(list, struct em28xx, devlist);
321 if (h->vdev->minor == minor) {
322 dev = h;
323 }
324 }
325
326 filp->private_data=dev;
327
328
329 em28xx_videodbg("users=%d\n", dev->users);
330
331 if (!down_read_trylock(&em28xx_disconnect))
332 return -ERESTARTSYS;
333
334 if (dev->users) {
335 em28xx_warn("this driver can be opened only once\n");
336 up_read(&em28xx_disconnect);
337 return -EBUSY;
338 }
339
340/* if(dev->vbi_dev->minor == minor){
341 dev->type=V4L2_BUF_TYPE_VBI_CAPTURE;
342 }*/
343 if (dev->vdev->minor == minor) {
344 dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
345 }
346
347 init_MUTEX(&dev->fileop_lock); /* to 1 == available */
348 spin_lock_init(&dev->queue_lock);
349 init_waitqueue_head(&dev->wait_frame);
350 init_waitqueue_head(&dev->wait_stream);
351
352 down(&dev->lock);
353
354 em28xx_set_alternate(dev);
355
356 dev->width = norm_maxw(dev);
357 dev->height = norm_maxh(dev);
358 dev->frame_size = dev->width * dev->height * 2;
359 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
360 dev->bytesperline = dev->width * 2;
361 dev->hscale = 0;
362 dev->vscale = 0;
363
364 em28xx_capture_start(dev, 1);
365 em28xx_resolution_set(dev);
366
367 /* start the transfer */
368 errCode = em28xx_init_isoc(dev);
369 if (errCode)
370 goto err;
371
372 dev->users++;
373 filp->private_data = dev;
374 dev->io = IO_NONE;
375 dev->stream = STREAM_OFF;
376 dev->num_frames = 0;
377
378 /* prepare queues */
379 em28xx_empty_framequeues(dev);
380
381 dev->state |= DEV_INITIALIZED;
382
383 video_mux(dev, 0);
384
385 err:
386 up(&dev->lock);
387 up_read(&em28xx_disconnect);
388 return errCode;
389}
390
391/*
392 * em28xx_realease_resources()
393 * unregisters the v4l2,i2c and usb devices
394 * called when the device gets disconected or at module unload
395*/
396static void em28xx_release_resources(struct em28xx *dev)
397{
398 down(&em28xx_sysfs_lock);
399
400 em28xx_info("V4L2 device /dev/video%d deregistered\n",
401 dev->vdev->minor);
402 list_del(&dev->devlist);
403 video_unregister_device(dev->vdev);
404/* video_unregister_device(dev->vbi_dev); */
405 em28xx_i2c_unregister(dev);
406 usb_put_dev(dev->udev);
407 up(&em28xx_sysfs_lock);
408}
409
410/*
411 * em28xx_v4l2_close()
412 * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls
413 */
414static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
415{
416 int errCode;
417 struct em28xx *dev=filp->private_data;
418
419 em28xx_videodbg("users=%d\n", dev->users);
420
421 down(&dev->lock);
422
423 em28xx_uninit_isoc(dev);
424
425 em28xx_release_buffers(dev);
426
427 /* the device is already disconnect, free the remaining resources */
428 if (dev->state & DEV_DISCONNECTED) {
429 em28xx_release_resources(dev);
430 up(&dev->lock);
431 kfree(dev);
432 return 0;
433 }
434
435 /* set alternate 0 */
436 dev->alt = 0;
437 em28xx_videodbg("setting alternate 0\n");
438 errCode = usb_set_interface(dev->udev, 0, 0);
439 if (errCode < 0) {
440 em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
441 errCode);
442 }
443
444 dev->users--;
445 wake_up_interruptible_nr(&dev->open, 1);
446 up(&dev->lock);
447 return 0;
448}
449
450/*
451 * em28xx_v4l2_read()
452 * will allocate buffers when called for the first time
453 */
454static ssize_t
455em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
456 loff_t * f_pos)
457{
458 struct em28xx_frame_t *f, *i;
459 unsigned long lock_flags;
460 int ret = 0;
461 struct em28xx *dev = filp->private_data;
462
463 if (down_interruptible(&dev->fileop_lock))
464 return -ERESTARTSYS;
465
466 if (dev->state & DEV_DISCONNECTED) {
467 em28xx_videodbg("device not present\n");
468 up(&dev->fileop_lock);
469 return -ENODEV;
470 }
471
472 if (dev->state & DEV_MISCONFIGURED) {
473 em28xx_videodbg("device misconfigured; close and open it again\n");
474 up(&dev->fileop_lock);
475 return -EIO;
476 }
477
478 if (dev->io == IO_MMAP) {
479 em28xx_videodbg ("IO method is set to mmap; close and open"
480 " the device again to choose the read method\n");
481 up(&dev->fileop_lock);
482 return -EINVAL;
483 }
484
485 if (dev->io == IO_NONE) {
486 if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
487 em28xx_errdev("read failed, not enough memory\n");
488 up(&dev->fileop_lock);
489 return -ENOMEM;
490 }
491 dev->io = IO_READ;
492 dev->stream = STREAM_ON;
493 em28xx_queue_unusedframes(dev);
494 }
495
496 if (!count) {
497 up(&dev->fileop_lock);
498 return 0;
499 }
500
501 if (list_empty(&dev->outqueue)) {
502 if (filp->f_flags & O_NONBLOCK) {
503 up(&dev->fileop_lock);
504 return -EAGAIN;
505 }
506 ret = wait_event_interruptible
507 (dev->wait_frame,
508 (!list_empty(&dev->outqueue)) ||
509 (dev->state & DEV_DISCONNECTED));
510 if (ret) {
511 up(&dev->fileop_lock);
512 return ret;
513 }
514 if (dev->state & DEV_DISCONNECTED) {
515 up(&dev->fileop_lock);
516 return -ENODEV;
517 }
518 }
519
520 f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame);
521
522 spin_lock_irqsave(&dev->queue_lock, lock_flags);
523 list_for_each_entry(i, &dev->outqueue, frame)
524 i->state = F_UNUSED;
525 INIT_LIST_HEAD(&dev->outqueue);
526 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
527
528 em28xx_queue_unusedframes(dev);
529
530 if (count > f->buf.length)
531 count = f->buf.length;
532
533 if (copy_to_user(buf, f->bufmem, count)) {
534 up(&dev->fileop_lock);
535 return -EFAULT;
536 }
537 *f_pos += count;
538
539 up(&dev->fileop_lock);
540
541 return count;
542}
543
544/*
545 * em28xx_v4l2_poll()
546 * will allocate buffers when called for the first time
547 */
548static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
549{
550 unsigned int mask = 0;
551 struct em28xx *dev = filp->private_data;
552
553 if (down_interruptible(&dev->fileop_lock))
554 return POLLERR;
555
556 if (dev->state & DEV_DISCONNECTED) {
557 em28xx_videodbg("device not present\n");
558 } else if (dev->state & DEV_MISCONFIGURED) {
559 em28xx_videodbg("device is misconfigured; close and open it again\n");
560 } else {
561 if (dev->io == IO_NONE) {
562 if (!em28xx_request_buffers
563 (dev, EM28XX_NUM_READ_FRAMES)) {
564 em28xx_warn
565 ("poll() failed, not enough memory\n");
566 } else {
567 dev->io = IO_READ;
568 dev->stream = STREAM_ON;
569 }
570 }
571
572 if (dev->io == IO_READ) {
573 em28xx_queue_unusedframes(dev);
574 poll_wait(filp, &dev->wait_frame, wait);
575
576 if (!list_empty(&dev->outqueue))
577 mask |= POLLIN | POLLRDNORM;
578
579 up(&dev->fileop_lock);
580
581 return mask;
582 }
583 }
584
585 up(&dev->fileop_lock);
586 return POLLERR;
587}
588
589/*
590 * em28xx_vm_open()
591 */
592static void em28xx_vm_open(struct vm_area_struct *vma)
593{
594 struct em28xx_frame_t *f = vma->vm_private_data;
595 f->vma_use_count++;
596}
597
598/*
599 * em28xx_vm_close()
600 */
601static void em28xx_vm_close(struct vm_area_struct *vma)
602{
603 /* NOTE: buffers are not freed here */
604 struct em28xx_frame_t *f = vma->vm_private_data;
605 f->vma_use_count--;
606}
607
608static struct vm_operations_struct em28xx_vm_ops = {
609 .open = em28xx_vm_open,
610 .close = em28xx_vm_close,
611};
612
613/*
614 * em28xx_v4l2_mmap()
615 */
616static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
617{
618 unsigned long size = vma->vm_end - vma->vm_start,
619 start = vma->vm_start, pos, page;
620 u32 i;
621
622 struct em28xx *dev = filp->private_data;
623
624 if (down_interruptible(&dev->fileop_lock))
625 return -ERESTARTSYS;
626
627 if (dev->state & DEV_DISCONNECTED) {
628 em28xx_videodbg("mmap: device not present\n");
629 up(&dev->fileop_lock);
630 return -ENODEV;
631 }
632
633 if (dev->state & DEV_MISCONFIGURED) {
634 em28xx_videodbg ("mmap: Device is misconfigured; close and "
635 "open it again\n");
636 up(&dev->fileop_lock);
637 return -EIO;
638 }
639
640 if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
641 size != PAGE_ALIGN(dev->frame[0].buf.length)) {
642 up(&dev->fileop_lock);
643 return -EINVAL;
644 }
645
646 for (i = 0; i < dev->num_frames; i++) {
647 if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
648 break;
649 }
650 if (i == dev->num_frames) {
651 em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
652 up(&dev->fileop_lock);
653 return -EINVAL;
654 }
655
656 /* VM_IO is eventually going to replace PageReserved altogether */
657 vma->vm_flags |= VM_IO;
658 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
659
660 pos = (unsigned long)dev->frame[i].bufmem;
661 while (size > 0) { /* size is page-aligned */
662 page = vmalloc_to_pfn((void *)pos);
663 if (remap_pfn_range(vma, start, page, PAGE_SIZE,
664 vma->vm_page_prot)) {
665 em28xx_videodbg("mmap: rename page map failed\n");
666 up(&dev->fileop_lock);
667 return -EAGAIN;
668 }
669 start += PAGE_SIZE;
670 pos += PAGE_SIZE;
671 size -= PAGE_SIZE;
672 }
673
674 vma->vm_ops = &em28xx_vm_ops;
675 vma->vm_private_data = &dev->frame[i];
676
677 em28xx_vm_open(vma);
678 up(&dev->fileop_lock);
679 return 0;
680}
681
682/*
683 * em28xx_get_ctrl()
684 * return the current saturation, brightness or contrast, mute state
685 */
686static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
687{
688 s32 tmp;
689 switch (ctrl->id) {
690 case V4L2_CID_AUDIO_MUTE:
691 ctrl->value = dev->mute;
692 return 0;
693 case V4L2_CID_AUDIO_VOLUME:
694 ctrl->value = dev->volume;
695 return 0;
696 case V4L2_CID_BRIGHTNESS:
697 if ((tmp = em28xx_brightness_get(dev)) < 0)
698 return -EIO;
699 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
700 return 0;
701 case V4L2_CID_CONTRAST:
702 if ((ctrl->value = em28xx_contrast_get(dev)) < 0)
703 return -EIO;
704 return 0;
705 case V4L2_CID_SATURATION:
706 if ((ctrl->value = em28xx_saturation_get(dev)) < 0)
707 return -EIO;
708 return 0;
709 case V4L2_CID_RED_BALANCE:
710 if ((tmp = em28xx_v_balance_get(dev)) < 0)
711 return -EIO;
712 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
713 return 0;
714 case V4L2_CID_BLUE_BALANCE:
715 if ((tmp = em28xx_u_balance_get(dev)) < 0)
716 return -EIO;
717 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
718 return 0;
719 case V4L2_CID_GAMMA:
720 if ((ctrl->value = em28xx_gamma_get(dev)) < 0)
721 return -EIO;
722 return 0;
723 default:
724 return -EINVAL;
725 }
726}
727
728/*
729 * em28xx_set_ctrl()
730 * mute or set new saturation, brightness or contrast
731 */
732static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
733{
734 switch (ctrl->id) {
735 case V4L2_CID_AUDIO_MUTE:
736 if (ctrl->value != dev->mute) {
737 dev->mute = ctrl->value;
738 em28xx_audio_usb_mute(dev, ctrl->value);
739 return em28xx_audio_analog_set(dev);
740 }
741 return 0;
742 case V4L2_CID_AUDIO_VOLUME:
743 dev->volume = ctrl->value;
744 return em28xx_audio_analog_set(dev);
745 case V4L2_CID_BRIGHTNESS:
746 return em28xx_brightness_set(dev, ctrl->value);
747 case V4L2_CID_CONTRAST:
748 return em28xx_contrast_set(dev, ctrl->value);
749 case V4L2_CID_SATURATION:
750 return em28xx_saturation_set(dev, ctrl->value);
751 case V4L2_CID_RED_BALANCE:
752 return em28xx_v_balance_set(dev, ctrl->value);
753 case V4L2_CID_BLUE_BALANCE:
754 return em28xx_u_balance_set(dev, ctrl->value);
755 case V4L2_CID_GAMMA:
756 return em28xx_gamma_set(dev, ctrl->value);
757 default:
758 return -EINVAL;
759 }
760}
761
762/*
763 * em28xx_stream_interrupt()
764 * stops streaming
765 */
766static int em28xx_stream_interrupt(struct em28xx *dev)
767{
768 int ret = 0;
769
770 /* stop reading from the device */
771
772 dev->stream = STREAM_INTERRUPT;
773 ret = wait_event_timeout(dev->wait_stream,
774 (dev->stream == STREAM_OFF) ||
775 (dev->state & DEV_DISCONNECTED),
776 EM28XX_URB_TIMEOUT);
777 if (dev->state & DEV_DISCONNECTED)
778 return -ENODEV;
779 else if (ret) {
780 dev->state |= DEV_MISCONFIGURED;
781 em28xx_videodbg("device is misconfigured; close and "
782 "open /dev/video%d again\n", dev->vdev->minor);
783 return ret;
784 }
785
786 return 0;
787}
788
789static int em28xx_set_norm(struct em28xx *dev, int width, int height)
790{
791 unsigned int hscale, vscale;
792 unsigned int maxh, maxw;
793
794 maxw = norm_maxw(dev);
795 maxh = norm_maxh(dev);
796
797 /* width must even because of the YUYV format */
798 /* height must be even because of interlacing */
799 height &= 0xfffe;
800 width &= 0xfffe;
801
802 if (height < 32)
803 height = 32;
804 if (height > maxh)
805 height = maxh;
806 if (width < 48)
807 width = 48;
808 if (width > maxw)
809 width = maxw;
810
811 if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000)
812 hscale = 0x3fff;
813 width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
814
815 if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000)
816 vscale = 0x3fff;
817 height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
818
819 /* set new image size */
820 dev->width = width;
821 dev->height = height;
822 dev->frame_size = dev->width * dev->height * 2;
823 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
824 dev->bytesperline = dev->width * 2;
825 dev->hscale = hscale;
826 dev->vscale = vscale;
827
828 em28xx_resolution_set(dev);
829
830 return 0;
831}
832
833/*
834 * em28xx_v4l2_do_ioctl()
835 * This function is _not_ called directly, but from
836 * em28xx_v4l2_ioctl. Userspace
837 * copying is done already, arg is a kernel pointer.
838 */
839static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
840 struct em28xx *dev, unsigned int cmd, void *arg,
841 v4l2_kioctl driver_ioctl)
842{
843 int ret;
844
845 switch (cmd) {
846 /* ---------- tv norms ---------- */
847 case VIDIOC_ENUMSTD:
848 {
849 struct v4l2_standard *e = arg;
850 unsigned int i;
851
852 i = e->index;
853 if (i >= TVNORMS)
854 return -EINVAL;
855 ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
856 tvnorms[e->index].name);
857 e->index = i;
858 if (ret < 0)
859 return ret;
860 return 0;
861 }
862 case VIDIOC_G_STD:
863 {
864 v4l2_std_id *id = arg;
865
866 *id = dev->tvnorm->id;
867 return 0;
868 }
869 case VIDIOC_S_STD:
870 {
871 v4l2_std_id *id = arg;
872 unsigned int i;
873
874 for (i = 0; i < TVNORMS; i++)
875 if (*id == tvnorms[i].id)
876 break;
877 if (i == TVNORMS)
878 for (i = 0; i < TVNORMS; i++)
879 if (*id & tvnorms[i].id)
880 break;
881 if (i == TVNORMS)
882 return -EINVAL;
883
884 down(&dev->lock);
885 dev->tvnorm = &tvnorms[i];
886
887 em28xx_set_norm(dev, dev->width, dev->height);
888
889/*
890 dev->width=norm_maxw(dev);
891 dev->height=norm_maxh(dev);
892 dev->frame_size=dev->width*dev->height*2;
893 dev->field_size=dev->frame_size>>1;
894 dev->bytesperline=dev->width*2;
895 dev->hscale=0;
896 dev->vscale=0;
897
898 em28xx_resolution_set(dev);
899*/
900/*
901 em28xx_uninit_isoc(dev);
902 em28xx_set_alternate(dev);
903 em28xx_capture_start(dev, 1);
904 em28xx_resolution_set(dev);
905 em28xx_init_isoc(dev);
906*/
907 em28xx_i2c_call_clients(dev, DECODER_SET_NORM,
908 &tvnorms[i].mode);
909 em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
910 &dev->tvnorm->id);
911
912 up(&dev->lock);
913
914 return 0;
915 }
916
917 /* ------ input switching ---------- */
918 case VIDIOC_ENUMINPUT:
919 {
920 struct v4l2_input *i = arg;
921 unsigned int n;
922 static const char *iname[] = {
923 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
924 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
925 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
926 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
927 [EM28XX_VMUX_SVIDEO] = "S-Video",
928 [EM28XX_VMUX_TELEVISION] = "Television",
929 [EM28XX_VMUX_CABLE] = "Cable TV",
930 [EM28XX_VMUX_DVB] = "DVB",
931 [EM28XX_VMUX_DEBUG] = "for debug only",
932 };
933
934 n = i->index;
935 if (n >= MAX_EM28XX_INPUT)
936 return -EINVAL;
937 if (0 == INPUT(n)->type)
938 return -EINVAL;
939 memset(i, 0, sizeof(*i));
940 i->index = n;
941 i->type = V4L2_INPUT_TYPE_CAMERA;
942 strcpy(i->name, iname[INPUT(n)->type]);
943 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
944 (EM28XX_VMUX_CABLE == INPUT(n)->type))
945 i->type = V4L2_INPUT_TYPE_TUNER;
946 for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
947 i->std |= tvnorms[n].id;
948 return 0;
949 }
950
951 case VIDIOC_G_INPUT:
952 {
953 int *i = arg;
954 *i = dev->ctl_input;
955
956 return 0;
957 }
958
959 case VIDIOC_S_INPUT:
960 {
961 int *index = arg;
962
963 if (*index >= MAX_EM28XX_INPUT)
964 return -EINVAL;
965 if (0 == INPUT(*index)->type)
966 return -EINVAL;
967
968 down(&dev->lock);
969 video_mux(dev, *index);
970 up(&dev->lock);
971
972 return 0;
973 }
974
975 case VIDIOC_G_AUDIO:
976 {
977 struct v4l2_audio *a = arg;
978 unsigned int index = a->index;
979
980 if (a->index > 1)
981 return -EINVAL;
982 memset(a, 0, sizeof(*a));
983 index = dev->ctl_ainput;
984
985 if (index == 0) {
986 strcpy(a->name, "Television");
987 } else {
988 strcpy(a->name, "Line In");
989 }
990 a->capability = V4L2_AUDCAP_STEREO;
991 a->index = index;
992 return 0;
993 }
994
995 case VIDIOC_S_AUDIO:
996 {
997 struct v4l2_audio *a = arg;
998 if (a->index != dev->ctl_ainput)
999 return -EINVAL;
1000
1001 return 0;
1002 }
1003
1004 /* --- controls ---------------------------------------------- */
1005 case VIDIOC_QUERYCTRL:
1006 {
1007 struct v4l2_queryctrl *qc = arg;
1008 u8 i, n;
1009 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1010 for (i = 0; i < n; i++)
1011 if (qc->id && qc->id == em28xx_qctrl[i].id) {
1012 memcpy(qc, &(em28xx_qctrl[i]),
1013 sizeof(*qc));
1014 return 0;
1015 }
1016
1017 return -EINVAL;
1018 }
1019
1020 case VIDIOC_G_CTRL:
1021 {
1022 struct v4l2_control *ctrl = arg;
1023
1024
1025 return em28xx_get_ctrl(dev, ctrl);
1026 }
1027
1028 case VIDIOC_S_CTRL_OLD: /* ??? */
1029 case VIDIOC_S_CTRL:
1030 {
1031 struct v4l2_control *ctrl = arg;
1032 u8 i, n;
1033
1034
1035 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1036 for (i = 0; i < n; i++)
1037 if (ctrl->id == em28xx_qctrl[i].id) {
1038 if (ctrl->value <
1039 em28xx_qctrl[i].minimum
1040 || ctrl->value >
1041 em28xx_qctrl[i].maximum)
1042 return -ERANGE;
1043
1044 return em28xx_set_ctrl(dev, ctrl);
1045 }
1046 return -EINVAL;
1047 }
1048
1049 /* --- tuner ioctls ------------------------------------------ */
1050 case VIDIOC_G_TUNER:
1051 {
1052 struct v4l2_tuner *t = arg;
1053 int status = 0;
1054
1055 if (0 != t->index)
1056 return -EINVAL;
1057
1058 memset(t, 0, sizeof(*t));
1059 strcpy(t->name, "Tuner");
1060 t->type = V4L2_TUNER_ANALOG_TV;
1061 t->capability = V4L2_TUNER_CAP_NORM;
1062 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1063/* t->signal = 0xffff;*/
1064/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
1065 /* No way to get signal strength? */
1066 down(&dev->lock);
1067 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1068 &status);
1069 up(&dev->lock);
1070 t->signal =
1071 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1072
1073 em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
1074 t->afc);
1075 return 0;
1076 }
1077 case VIDIOC_S_TUNER:
1078 {
1079 struct v4l2_tuner *t = arg;
1080 int status = 0;
1081
1082 if (0 != t->index)
1083 return -EINVAL;
1084 memset(t, 0, sizeof(*t));
1085 strcpy(t->name, "Tuner");
1086 t->type = V4L2_TUNER_ANALOG_TV;
1087 t->capability = V4L2_TUNER_CAP_NORM;
1088 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1089/* t->signal = 0xffff; */
1090 /* No way to get signal strength? */
1091 down(&dev->lock);
1092 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1093 &status);
1094 up(&dev->lock);
1095 t->signal =
1096 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1097
1098 em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
1099 t->signal, t->afc);
1100 return 0;
1101 }
1102 case VIDIOC_G_FREQUENCY:
1103 {
1104 struct v4l2_frequency *f = arg;
1105
1106 memset(f, 0, sizeof(*f));
1107 f->type = V4L2_TUNER_ANALOG_TV;
1108 f->frequency = dev->ctl_freq;
1109
1110 return 0;
1111 }
1112 case VIDIOC_S_FREQUENCY:
1113 {
1114 struct v4l2_frequency *f = arg;
1115
1116 if (0 != f->tuner)
1117 return -EINVAL;
1118
1119 if (V4L2_TUNER_ANALOG_TV != f->type)
1120 return -EINVAL;
1121
1122 down(&dev->lock);
1123 dev->ctl_freq = f->frequency;
1124 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
1125 up(&dev->lock);
1126 return 0;
1127 }
1128
1129 case VIDIOC_CROPCAP:
1130 {
1131 struct v4l2_cropcap *cc = arg;
1132
1133 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1134 return -EINVAL;
1135 cc->bounds.left = 0;
1136 cc->bounds.top = 0;
1137 cc->bounds.width = dev->width;
1138 cc->bounds.height = dev->height;
1139 cc->defrect = cc->bounds;
1140 cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
1141 cc->pixelaspect.denominator = 59;
1142 return 0;
1143 }
1144 case VIDIOC_STREAMON:
1145 {
1146 int *type = arg;
1147
1148 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1149 || dev->io != IO_MMAP)
1150 return -EINVAL;
1151
1152 if (list_empty(&dev->inqueue))
1153 return -EINVAL;
1154
1155 dev->stream = STREAM_ON; /* FIXME: Start video capture here? */
1156
1157 em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
1158
1159 return 0;
1160 }
1161 case VIDIOC_STREAMOFF:
1162 {
1163 int *type = arg;
1164 int ret;
1165
1166 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1167 || dev->io != IO_MMAP)
1168 return -EINVAL;
1169
1170 if (dev->stream == STREAM_ON) {
1171 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
1172 if ((ret = em28xx_stream_interrupt(dev)))
1173 return ret;
1174 }
1175 em28xx_empty_framequeues(dev);
1176
1177 return 0;
1178 }
1179 default:
1180 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1181 driver_ioctl);
1182 }
1183 return 0;
1184}
1185
1186/*
1187 * em28xx_v4l2_do_ioctl()
1188 * This function is _not_ called directly, but from
1189 * em28xx_v4l2_ioctl. Userspace
1190 * copying is done already, arg is a kernel pointer.
1191 */
1192static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1193 unsigned int cmd, void *arg)
1194{
1195 struct em28xx *dev = filp->private_data;
1196
1197 if (!dev)
1198 return -ENODEV;
1199
1200 if (video_debug > 1)
1201 em28xx_print_ioctl(dev->name,cmd);
1202
1203 switch (cmd) {
1204
1205 /* --- capabilities ------------------------------------------ */
1206 case VIDIOC_QUERYCAP:
1207 {
1208 struct v4l2_capability *cap = arg;
1209
1210 memset(cap, 0, sizeof(*cap));
1211 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1212 strlcpy(cap->card, em28xx_boards[dev->model].name,
1213 sizeof(cap->card));
1214 strlcpy(cap->bus_info, dev->udev->dev.bus_id,
1215 sizeof(cap->bus_info));
1216 cap->version = EM28XX_VERSION_CODE;
1217 cap->capabilities =
1218 V4L2_CAP_VIDEO_CAPTURE |
1219 V4L2_CAP_AUDIO |
1220 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1221 if (dev->has_tuner)
1222 cap->capabilities |= V4L2_CAP_TUNER;
1223 return 0;
1224 }
1225
1226 /* --- capture ioctls ---------------------------------------- */
1227 case VIDIOC_ENUM_FMT:
1228 {
1229 struct v4l2_fmtdesc *fmtd = arg;
1230
1231 if (fmtd->index != 0)
1232 return -EINVAL;
1233 memset(fmtd, 0, sizeof(*fmtd));
1234 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1235 strcpy(fmtd->description, "Packed YUY2");
1236 fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
1237 memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
1238 return 0;
1239 }
1240
1241 case VIDIOC_G_FMT:
1242 {
1243 struct v4l2_format *format = arg;
1244
1245 em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
1246 format->type ==
1247 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1248 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1249 V4L2_BUF_TYPE_VBI_CAPTURE ?
1250 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1251 "not supported");
1252
1253 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1254 return -EINVAL;
1255
1256 format->fmt.pix.width = dev->width;
1257 format->fmt.pix.height = dev->height;
1258 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1259 format->fmt.pix.bytesperline = dev->bytesperline;
1260 format->fmt.pix.sizeimage = dev->frame_size;
1261 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1262 format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
1263
1264 em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
1265 dev->height);
1266 return 0;
1267 }
1268
1269 case VIDIOC_TRY_FMT:
1270 case VIDIOC_S_FMT:
1271 {
1272 struct v4l2_format *format = arg;
1273 u32 i;
1274 int ret = 0;
1275 int width = format->fmt.pix.width;
1276 int height = format->fmt.pix.height;
1277 unsigned int hscale, vscale;
1278 unsigned int maxh, maxw;
1279
1280 maxw = norm_maxw(dev);
1281 maxh = norm_maxh(dev);
1282
1283/* int both_fields; */
1284
1285 em28xx_videodbg("%s: type=%s\n",
1286 cmd ==
1287 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1288 "VIDIOC_S_FMT",
1289 format->type ==
1290 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1291 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1292 V4L2_BUF_TYPE_VBI_CAPTURE ?
1293 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1294 "not supported");
1295
1296 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1297 return -EINVAL;
1298
1299 em28xx_videodbg("%s: requested %dx%d\n",
1300 cmd ==
1301 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1302 "VIDIOC_S_FMT", format->fmt.pix.width,
1303 format->fmt.pix.height);
1304
1305 /* FIXME: Move some code away from here */
1306 /* width must even because of the YUYV format */
1307 /* height must be even because of interlacing */
1308 height &= 0xfffe;
1309 width &= 0xfffe;
1310
1311 if (height < 32)
1312 height = 32;
1313 if (height > maxh)
1314 height = maxh;
1315 if (width < 48)
1316 width = 48;
1317 if (width > maxw)
1318 width = maxw;
1319
1320 if(dev->is_em2800){
1321 /* the em2800 can only scale down to 50% */
1322 if(height % (maxh / 2))
1323 height=maxh;
1324 if(width % (maxw / 2))
1325 width=maxw;
1326 /* according to empiatech support */
1327 /* the MaxPacketSize is to small to support */
1328 /* framesizes larger than 640x480 @ 30 fps */
1329 /* or 640x576 @ 25 fps. As this would cut */
1330 /* of a part of the image we prefer */
1331 /* 360x576 or 360x480 for now */
1332 if(width == maxw && height == maxh)
1333 width /= 2;
1334 }
1335
1336 if ((hscale =
1337 (((unsigned long)maxw) << 12) / width - 4096L) >=
1338 0x4000)
1339 hscale = 0x3fff;
1340 width =
1341 (((unsigned long)maxw) << 12) / (hscale + 4096L);
1342
1343 if ((vscale =
1344 (((unsigned long)maxh) << 12) / height - 4096L) >=
1345 0x4000)
1346 vscale = 0x3fff;
1347 height =
1348 (((unsigned long)maxh) << 12) / (vscale + 4096L);
1349
1350 format->fmt.pix.width = width;
1351 format->fmt.pix.height = height;
1352 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1353 format->fmt.pix.bytesperline = width * 2;
1354 format->fmt.pix.sizeimage = width * 2 * height;
1355 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1356 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
1357
1358 em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
1359 cmd ==
1360 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1361 "VIDIOC_S_FMT", format->fmt.pix.width,
1362 format->fmt.pix.height, hscale, vscale);
1363
1364 if (cmd == VIDIOC_TRY_FMT)
1365 return 0;
1366
1367 for (i = 0; i < dev->num_frames; i++)
1368 if (dev->frame[i].vma_use_count) {
1369 em28xx_videodbg("VIDIOC_S_FMT failed. "
1370 "Unmap the buffers first.\n");
1371 return -EINVAL;
1372 }
1373
1374 /* stop io in case it is already in progress */
1375 if (dev->stream == STREAM_ON) {
1376 em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
1377 if ((ret = em28xx_stream_interrupt(dev)))
1378 return ret;
1379 }
1380
1381 em28xx_release_buffers(dev);
1382 dev->io = IO_NONE;
1383
1384 /* set new image size */
1385 dev->width = width;
1386 dev->height = height;
1387 dev->frame_size = dev->width * dev->height * 2;
1388 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
1389 dev->bytesperline = dev->width * 2;
1390 dev->hscale = hscale;
1391 dev->vscale = vscale;
1392/* dev->both_fileds = both_fileds; */
1393 em28xx_uninit_isoc(dev);
1394 em28xx_set_alternate(dev);
1395 em28xx_capture_start(dev, 1);
1396 em28xx_resolution_set(dev);
1397 em28xx_init_isoc(dev);
1398
1399 return 0;
1400 }
1401
1402 /* --- streaming capture ------------------------------------- */
1403 case VIDIOC_REQBUFS:
1404 {
1405 struct v4l2_requestbuffers *rb = arg;
1406 u32 i;
1407 int ret;
1408
1409 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1410 rb->memory != V4L2_MEMORY_MMAP)
1411 return -EINVAL;
1412
1413 if (dev->io == IO_READ) {
1414 em28xx_videodbg ("method is set to read;"
1415 " close and open the device again to"
1416 " choose the mmap I/O method\n");
1417 return -EINVAL;
1418 }
1419
1420 for (i = 0; i < dev->num_frames; i++)
1421 if (dev->frame[i].vma_use_count) {
1422 em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
1423 return -EINVAL;
1424 }
1425
1426 if (dev->stream == STREAM_ON) {
1427 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
1428 if ((ret = em28xx_stream_interrupt(dev)))
1429 return ret;
1430 }
1431
1432 em28xx_empty_framequeues(dev);
1433
1434 em28xx_release_buffers(dev);
1435 if (rb->count)
1436 rb->count =
1437 em28xx_request_buffers(dev, rb->count);
1438
1439 dev->frame_current = NULL;
1440
1441 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
1442 rb->count);
1443 dev->io = rb->count ? IO_MMAP : IO_NONE;
1444 return 0;
1445 }
1446
1447 case VIDIOC_QUERYBUF:
1448 {
1449 struct v4l2_buffer *b = arg;
1450
1451 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1452 b->index >= dev->num_frames || dev->io != IO_MMAP)
1453 return -EINVAL;
1454
1455 memcpy(b, &dev->frame[b->index].buf, sizeof(*b));
1456
1457 if (dev->frame[b->index].vma_use_count) {
1458 b->flags |= V4L2_BUF_FLAG_MAPPED;
1459 }
1460 if (dev->frame[b->index].state == F_DONE)
1461 b->flags |= V4L2_BUF_FLAG_DONE;
1462 else if (dev->frame[b->index].state != F_UNUSED)
1463 b->flags |= V4L2_BUF_FLAG_QUEUED;
1464 return 0;
1465 }
1466 case VIDIOC_QBUF:
1467 {
1468 struct v4l2_buffer *b = arg;
1469 unsigned long lock_flags;
1470
1471 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1472 b->index >= dev->num_frames || dev->io != IO_MMAP) {
1473 return -EINVAL;
1474 }
1475
1476 if (dev->frame[b->index].state != F_UNUSED) {
1477 return -EAGAIN;
1478 }
1479 dev->frame[b->index].state = F_QUEUED;
1480
1481 /* add frame to fifo */
1482 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1483 list_add_tail(&dev->frame[b->index].frame,
1484 &dev->inqueue);
1485 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1486
1487 return 0;
1488 }
1489 case VIDIOC_DQBUF:
1490 {
1491 struct v4l2_buffer *b = arg;
1492 struct em28xx_frame_t *f;
1493 unsigned long lock_flags;
1494 int ret = 0;
1495
1496 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1497 || dev->io != IO_MMAP)
1498 return -EINVAL;
1499
1500 if (list_empty(&dev->outqueue)) {
1501 if (dev->stream == STREAM_OFF)
1502 return -EINVAL;
1503 if (filp->f_flags & O_NONBLOCK)
1504 return -EAGAIN;
1505 ret = wait_event_interruptible
1506 (dev->wait_frame,
1507 (!list_empty(&dev->outqueue)) ||
1508 (dev->state & DEV_DISCONNECTED));
1509 if (ret)
1510 return ret;
1511 if (dev->state & DEV_DISCONNECTED)
1512 return -ENODEV;
1513 }
1514
1515 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1516 f = list_entry(dev->outqueue.next,
1517 struct em28xx_frame_t, frame);
1518 list_del(dev->outqueue.next);
1519 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1520
1521 f->state = F_UNUSED;
1522 memcpy(b, &f->buf, sizeof(*b));
1523
1524 if (f->vma_use_count)
1525 b->flags |= V4L2_BUF_FLAG_MAPPED;
1526
1527 return 0;
1528 }
1529 default:
1530 return em28xx_do_ioctl(inode, filp, dev, cmd, arg,
1531 em28xx_video_do_ioctl);
1532 }
1533 return 0;
1534}
1535
1536/*
1537 * em28xx_v4l2_ioctl()
1538 * handle v4l2 ioctl the main action happens in em28xx_v4l2_do_ioctl()
1539 */
1540static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
1541 unsigned int cmd, unsigned long arg)
1542{
1543 int ret = 0;
1544 struct em28xx *dev = filp->private_data;
1545
1546 if (down_interruptible(&dev->fileop_lock))
1547 return -ERESTARTSYS;
1548
1549 if (dev->state & DEV_DISCONNECTED) {
1550 em28xx_errdev("v4l2 ioctl: device not present\n");
1551 up(&dev->fileop_lock);
1552 return -ENODEV;
1553 }
1554
1555 if (dev->state & DEV_MISCONFIGURED) {
1556 em28xx_errdev
1557 ("v4l2 ioctl: device is misconfigured; close and open it again\n");
1558 up(&dev->fileop_lock);
1559 return -EIO;
1560 }
1561
1562 ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
1563
1564 up(&dev->fileop_lock);
1565
1566 return ret;
1567}
1568
1569static struct file_operations em28xx_v4l_fops = {
1570 .owner = THIS_MODULE,
1571 .open = em28xx_v4l2_open,
1572 .release = em28xx_v4l2_close,
1573 .ioctl = em28xx_v4l2_ioctl,
1574 .read = em28xx_v4l2_read,
1575 .poll = em28xx_v4l2_poll,
1576 .mmap = em28xx_v4l2_mmap,
1577 .llseek = no_llseek,
1578};
1579
1580/******************************** usb interface *****************************************/
1581
1582/*
1583 * em28xx_init_dev()
1584 * allocates and inits the device structs, registers i2c bus and v4l device
1585 */
1586static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1587 int minor, int model)
1588{
1589 struct em28xx *dev = *devhandle;
1590 int retval = -ENOMEM;
1591 int errCode, i;
1592 unsigned int maxh, maxw;
1593
1594 dev->udev = udev;
1595 dev->model = model;
1596 init_MUTEX(&dev->lock);
1597 init_waitqueue_head(&dev->open);
1598
1599 dev->em28xx_write_regs = em28xx_write_regs;
1600 dev->em28xx_read_reg = em28xx_read_reg;
1601 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
1602 dev->em28xx_write_regs_req = em28xx_write_regs_req;
1603 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1604 dev->is_em2800 = em28xx_boards[model].is_em2800;
1605 dev->has_tuner = em28xx_boards[model].has_tuner;
1606 dev->has_msp34xx = em28xx_boards[model].has_msp34xx;
1607 dev->tda9887_conf = em28xx_boards[model].tda9887_conf;
1608 dev->decoder = em28xx_boards[model].decoder;
1609
1610 if (tuner >= 0)
1611 dev->tuner_type = tuner;
1612 else
1613 dev->tuner_type = em28xx_boards[model].tuner_type;
1614
1615 dev->video_inputs = em28xx_boards[model].vchannels;
1616
1617 for (i = 0; i < TVNORMS; i++)
1618 if (em28xx_boards[model].norm == tvnorms[i].mode)
1619 break;
1620 if (i == TVNORMS)
1621 i = 0;
1622
1623 dev->tvnorm = &tvnorms[i]; /* set default norm */
1624
1625 em28xx_videodbg("tvnorm=%s\n", dev->tvnorm->name);
1626
1627 maxw = norm_maxw(dev);
1628 maxh = norm_maxh(dev);
1629
1630 /* set default image size */
1631 dev->width = maxw;
1632 dev->height = maxh;
1633 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
1634 dev->field_size = dev->width * dev->height;
1635 dev->frame_size =
1636 dev->interlaced ? dev->field_size << 1 : dev->field_size;
1637 dev->bytesperline = dev->width * 2;
1638 dev->hscale = 0;
1639 dev->vscale = 0;
1640 dev->ctl_input = 2;
1641
1642 /* setup video picture settings for saa7113h */
1643 memset(&dev->vpic, 0, sizeof(dev->vpic));
1644 dev->vpic.colour = 128 << 8;
1645 dev->vpic.hue = 128 << 8;
1646 dev->vpic.brightness = 128 << 8;
1647 dev->vpic.contrast = 192 << 8;
1648 dev->vpic.whiteness = 128 << 8; /* This one isn't used */
1649 dev->vpic.depth = 16;
1650 dev->vpic.palette = VIDEO_PALETTE_YUV422;
1651
1652#ifdef CONFIG_MODULES
1653 /* request some modules */
1654 if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
1655 request_module("saa711x");
1656 if (dev->decoder == EM28XX_TVP5150)
1657 request_module("tvp5150");
1658 if (dev->has_tuner)
1659 request_module("tuner");
1660 if (dev->tda9887_conf)
1661 request_module("tda9887");
1662#endif
1663 errCode = em28xx_config(dev);
1664 if (errCode) {
1665 em28xx_errdev("error configuring device\n");
1666 kfree(dev);
1667 return -ENOMEM;
1668 }
1669
1670 down(&dev->lock);
1671 /* register i2c bus */
1672 em28xx_i2c_register(dev);
1673
1674 /* Do board specific init and eeprom reading */
1675 em28xx_card_setup(dev);
1676
1677 /* configure the device */
1678 em28xx_config_i2c(dev);
1679
1680 up(&dev->lock);
1681
1682 errCode = em28xx_config(dev);
1683
1684#ifdef CONFIG_MODULES
1685 if (dev->has_msp34xx)
1686 request_module("msp3400");
1687#endif
1688 /* allocate and fill v4l2 device struct */
1689 dev->vdev = video_device_alloc();
1690 if (NULL == dev->vdev) {
1691 em28xx_errdev("cannot allocate video_device.\n");
1692 kfree(dev);
1693 return -ENOMEM;
1694 }
1695
1696 dev->vdev->type = VID_TYPE_CAPTURE;
1697 if (dev->has_tuner)
1698 dev->vdev->type |= VID_TYPE_TUNER;
1699 dev->vdev->hardware = 0;
1700 dev->vdev->fops = &em28xx_v4l_fops;
1701 dev->vdev->minor = -1;
1702 dev->vdev->dev = &dev->udev->dev;
1703 dev->vdev->release = video_device_release;
1704 snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s",
1705 "em28xx video");
1706 list_add_tail(&dev->devlist,&em28xx_devlist);
1707
1708 /* register v4l2 device */
1709 down(&dev->lock);
1710 if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) {
1711 em28xx_errdev("unable to register video device (error=%i).\n",
1712 retval);
1713 up(&dev->lock);
1714 list_del(&dev->devlist);
1715 video_device_release(dev->vdev);
1716 kfree(dev);
1717 return -ENODEV;
1718 }
1719 if (dev->has_msp34xx) {
1720 /* Send a reset to other chips via gpio */
1721 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
1722 udelay(2500);
1723 em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
1724 udelay(2500);
1725
1726 }
1727 video_mux(dev, 0);
1728
1729 up(&dev->lock);
1730
1731 em28xx_info("V4L2 device registered as /dev/video%d\n",
1732 dev->vdev->minor);
1733
1734 return 0;
1735}
1736
1737/*
1738 * em28xx_usb_probe()
1739 * checks for supported devices
1740 */
1741static int em28xx_usb_probe(struct usb_interface *interface,
1742 const struct usb_device_id *id)
1743{
1744 const struct usb_endpoint_descriptor *endpoint;
1745 struct usb_device *udev;
1746 struct usb_interface *uif;
1747 struct em28xx *dev = NULL;
1748 int retval = -ENODEV;
1749 int model,i,nr,ifnum;
1750
1751 udev = usb_get_dev(interface_to_usbdev(interface));
1752 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1753
1754
1755 /* Don't register audio interfaces */
1756 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1757 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n",
1758 udev->descriptor.idVendor,udev->descriptor.idProduct,
1759 ifnum,
1760 interface->altsetting[0].desc.bInterfaceClass);
1761 return -ENODEV;
1762 }
1763
1764 em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
1765 udev->descriptor.idVendor,udev->descriptor.idProduct,
1766 ifnum,
1767 interface->altsetting[0].desc.bInterfaceClass);
1768
1769 endpoint = &interface->cur_altsetting->endpoint[1].desc;
1770
1771 /* check if the the device has the iso in endpoint at the correct place */
1772 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1773 USB_ENDPOINT_XFER_ISOC) {
1774 em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
1775 return -ENODEV;
1776 }
1777 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
1778 em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
1779 return -ENODEV;
1780 }
1781
1782 model=id->driver_info;
1783 nr=interface->minor;
1784
1785 if (nr>EM28XX_MAXBOARDS) {
1786 printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS);
1787 return -ENOMEM;
1788 }
1789
1790 /* allocate memory for our device state and initialize it */
1791 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1792 if (dev == NULL) {
1793 em28xx_err(DRIVER_NAME ": out of memory!\n");
1794 return -ENOMEM;
1795 }
1796 memset(dev, 0, sizeof(*dev));
1797
1798 /* compute alternate max packet sizes */
1799 uif = udev->actconfig->interface[0];
1800
1801 dev->num_alt=uif->num_altsetting;
1802 printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt);
1803// dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)*
1804 dev->alt_max_pkt_size = kmalloc(32*
1805 dev->num_alt,GFP_KERNEL);
1806 if (dev->alt_max_pkt_size == NULL) {
1807 em28xx_err(DRIVER_NAME ": out of memory!\n");
1808 return -ENOMEM;
1809 }
1810
1811 for (i = 0; i < dev->num_alt ; i++) {
1812 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
1813 wMaxPacketSize);
1814 dev->alt_max_pkt_size[i] =
1815 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1816 printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i,
1817 dev->alt_max_pkt_size[i]);
1818 }
1819
1820 snprintf(dev->name, 29, "em28xx #%d", nr);
1821
1822 if ((card[nr]>=0)&&(card[nr]<em28xx_bcount))
1823 model=card[nr];
1824
1825 if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) {
1826 printk( "%s: Your board has no eeprom inside it and thus can't\n"
1827 "%s: be autodetected. Please pass card=<n> insmod option to\n"
1828 "%s: workaround that. Redirect complaints to the vendor of\n"
1829 "%s: the TV card. Best regards,\n"
1830 "%s: -- tux\n",
1831 dev->name,dev->name,dev->name,dev->name,dev->name);
1832 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
1833 dev->name);
1834 for (i = 0; i < em28xx_bcount; i++) {
1835 printk("%s: card=%d -> %s\n",
1836 dev->name, i, em28xx_boards[i].name);
1837 }
1838 }
1839
1840 /* allocate device struct */
1841 retval = em28xx_init_dev(&dev, udev, nr, model);
1842 if (retval)
1843 return retval;
1844
1845 em28xx_info("Found %s\n", em28xx_boards[model].name);
1846
1847 /* save our data pointer in this interface device */
1848 usb_set_intfdata(interface, dev);
1849 return 0;
1850}
1851
1852/*
1853 * em28xx_usb_disconnect()
1854 * called when the device gets diconencted
1855 * video device will be unregistered on v4l2_close in case it is still open
1856 */
1857static void em28xx_usb_disconnect(struct usb_interface *interface)
1858{
1859 struct em28xx *dev = usb_get_intfdata(interface);
1860 usb_set_intfdata(interface, NULL);
1861
1862 if (!dev)
1863 return;
1864
1865 down_write(&em28xx_disconnect);
1866
1867 down(&dev->lock);
1868
1869 em28xx_info("disconnecting %s\n", dev->vdev->name);
1870
1871 wake_up_interruptible_all(&dev->open);
1872
1873 if (dev->users) {
1874 em28xx_warn
1875 ("device /dev/video%d is open! Deregistration and memory "
1876 "deallocation are deferred on close.\n", dev->vdev->minor);
1877 dev->state |= DEV_MISCONFIGURED;
1878 em28xx_uninit_isoc(dev);
1879 dev->state |= DEV_DISCONNECTED;
1880 wake_up_interruptible(&dev->wait_frame);
1881 wake_up_interruptible(&dev->wait_stream);
1882 } else {
1883 dev->state |= DEV_DISCONNECTED;
1884 em28xx_release_resources(dev);
1885 }
1886
1887 up(&dev->lock);
1888
1889 if (!dev->users) {
1890 kfree(dev->alt_max_pkt_size);
1891 kfree(dev);
1892 }
1893
1894 up_write(&em28xx_disconnect);
1895}
1896
1897static struct usb_driver em28xx_usb_driver = {
1898 .owner = THIS_MODULE,
1899 .name = "em28xx",
1900 .probe = em28xx_usb_probe,
1901 .disconnect = em28xx_usb_disconnect,
1902 .id_table = em28xx_id_table,
1903};
1904
1905static int __init em28xx_module_init(void)
1906{
1907 int result;
1908
1909 printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
1910 (EM28XX_VERSION_CODE >> 16) & 0xff,
1911 (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
1912#ifdef SNAPSHOT
1913 printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
1914 SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
1915#endif
1916
1917 /* register this driver with the USB subsystem */
1918 result = usb_register(&em28xx_usb_driver);
1919 if (result)
1920 em28xx_err(DRIVER_NAME
1921 " usb_register failed. Error number %d.\n", result);
1922
1923 return result;
1924}
1925
1926static void __exit em28xx_module_exit(void)
1927{
1928 /* deregister this driver with the USB subsystem */
1929 usb_deregister(&em28xx_usb_driver);
1930}
1931
1932module_init(em28xx_module_init);
1933module_exit(em28xx_module_exit);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
new file mode 100644
index 000000000000..5c7a41ce69f3
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -0,0 +1,513 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7
8 Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#ifndef _EM28XX_H
26#define _EM28XX_H
27
28#include <linux/videodev.h>
29#include <linux/i2c.h>
30#include <media/ir-kbd-i2c.h>
31
32/* Boards supported by driver */
33
34#define EM2800_BOARD_UNKNOWN 0
35#define EM2820_BOARD_UNKNOWN 1
36#define EM2820_BOARD_TERRATEC_CINERGY_250 2
37#define EM2820_BOARD_PINNACLE_USB_2 3
38#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
39#define EM2820_BOARD_MSI_VOX_USB_2 5
40#define EM2800_BOARD_TERRATEC_CINERGY_200 6
41#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
42#define EM2800_BOARD_KWORLD_USB2800 8
43#define EM2820_BOARD_PINNACLE_DVC_90 9
44
45#define UNSET -1
46
47/* maximum number of em28xx boards */
48#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
49
50/* maximum number of frames that can be queued */
51#define EM28XX_NUM_FRAMES 5
52/* number of frames that get used for v4l2_read() */
53#define EM28XX_NUM_READ_FRAMES 2
54
55/* number of buffers for isoc transfers */
56#define EM28XX_NUM_BUFS 5
57
58/* number of packets for each buffer
59 windows requests only 40 packets .. so we better do the same
60 this is what I found out for all alternate numbers there!
61 */
62#define EM28XX_NUM_PACKETS 40
63
64/* default alternate; 0 means choose the best */
65#define EM28XX_PINOUT 0
66
67#define EM28XX_INTERLACED_DEFAULT 1
68
69/*
70#define (use usbview if you want to get the other alternate number infos)
71#define
72#define alternate number 2
73#define Endpoint Address: 82
74 Direction: in
75 Attribute: 1
76 Type: Isoc
77 Max Packet Size: 1448
78 Interval: 125us
79
80 alternate number 7
81
82 Endpoint Address: 82
83 Direction: in
84 Attribute: 1
85 Type: Isoc
86 Max Packet Size: 3072
87 Interval: 125us
88*/
89
90/* time to wait when stopping the isoc transfer */
91#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
92
93/* time in msecs to wait for i2c writes to finish */
94#define EM2800_I2C_WRITE_TIMEOUT 20
95
96/* the various frame states */
97enum em28xx_frame_state {
98 F_UNUSED = 0,
99 F_QUEUED,
100 F_GRABBING,
101 F_DONE,
102 F_ERROR,
103};
104
105/* stream states */
106enum em28xx_stream_state {
107 STREAM_OFF,
108 STREAM_INTERRUPT,
109 STREAM_ON,
110};
111
112/* frames */
113struct em28xx_frame_t {
114 void *bufmem;
115 struct v4l2_buffer buf;
116 enum em28xx_frame_state state;
117 struct list_head frame;
118 unsigned long vma_use_count;
119 int top_field;
120 int fieldbytesused;
121};
122
123/* io methods */
124enum em28xx_io_method {
125 IO_NONE,
126 IO_READ,
127 IO_MMAP,
128};
129
130/* inputs */
131
132#define MAX_EM28XX_INPUT 4
133enum enum28xx_itype {
134 EM28XX_VMUX_COMPOSITE1 = 1,
135 EM28XX_VMUX_COMPOSITE2,
136 EM28XX_VMUX_COMPOSITE3,
137 EM28XX_VMUX_COMPOSITE4,
138 EM28XX_VMUX_SVIDEO,
139 EM28XX_VMUX_TELEVISION,
140 EM28XX_VMUX_CABLE,
141 EM28XX_VMUX_DVB,
142 EM28XX_VMUX_DEBUG,
143 EM28XX_RADIO,
144};
145
146struct em28xx_input {
147 enum enum28xx_itype type;
148 unsigned int vmux;
149 unsigned int amux;
150};
151
152#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
153
154enum em28xx_decoder {
155 EM28XX_TVP5150,
156 EM28XX_SAA7113,
157 EM28XX_SAA7114
158};
159
160struct em28xx_board {
161 char *name;
162 int vchannels;
163 int norm;
164 int tuner_type;
165
166 /* i2c flags */
167 unsigned int is_em2800;
168 unsigned int tda9887_conf;
169
170 unsigned int has_tuner:1;
171 unsigned int has_msp34xx:1;
172
173 enum em28xx_decoder decoder;
174
175 struct em28xx_input input[MAX_EM28XX_INPUT];
176};
177
178struct em28xx_eeprom {
179 u32 id; /* 0x9567eb1a */
180 u16 vendor_ID;
181 u16 product_ID;
182
183 u16 chip_conf;
184
185 u16 board_conf;
186
187 u16 string1, string2, string3;
188
189 u8 string_idx_table;
190};
191
192/* device states */
193enum em28xx_dev_state {
194 DEV_INITIALIZED = 0x01,
195 DEV_DISCONNECTED = 0x02,
196 DEV_MISCONFIGURED = 0x04,
197};
198
199/* tvnorms */
200struct em28xx_tvnorm {
201 char *name;
202 v4l2_std_id id;
203 /* mode for saa7113h */
204 int mode;
205};
206
207/* main device struct */
208struct em28xx {
209 /* generic device properties */
210 char name[30]; /* name (including minor) of the device */
211 int model; /* index in the device_data struct */
212 unsigned int is_em2800;
213 int video_inputs; /* number of video inputs */
214 struct list_head devlist;
215 unsigned int has_tuner:1;
216 unsigned int has_msp34xx:1;
217 unsigned int has_tda9887:1;
218
219 enum em28xx_decoder decoder;
220
221 int tuner_type; /* type of the tuner */
222 int tuner_addr; /* tuner address */
223 int tda9887_conf;
224 /* i2c i/o */
225 struct i2c_adapter i2c_adap;
226 struct i2c_client i2c_client;
227 /* video for linux */
228 int users; /* user count for exclusive use */
229 struct video_device *vdev; /* video for linux device struct */
230 struct video_picture vpic; /* picture settings only used to init saa7113h */
231 struct em28xx_tvnorm *tvnorm; /* selected tv norm */
232 int ctl_freq; /* selected frequency */
233 unsigned int ctl_input; /* selected input */
234 unsigned int ctl_ainput; /* slected audio input */
235 int mute;
236 int volume;
237 /* frame properties */
238 struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */
239 int num_frames; /* number of frames currently in use */
240 unsigned int frame_count; /* total number of transfered frames */
241 struct em28xx_frame_t *frame_current; /* the frame that is being filled */
242 int width; /* current frame width */
243 int height; /* current frame height */
244 int frame_size; /* current frame size */
245 int field_size; /* current field size */
246 int bytesperline;
247 int hscale; /* horizontal scale factor (see datasheet) */
248 int vscale; /* vertical scale factor (see datasheet) */
249 int interlaced; /* 1=interlace fileds, 0=just top fileds */
250 int type;
251
252 /* states */
253 enum em28xx_dev_state state;
254 enum em28xx_stream_state stream;
255 enum em28xx_io_method io;
256 /* locks */
257 struct semaphore lock, fileop_lock;
258 spinlock_t queue_lock;
259 struct list_head inqueue, outqueue;
260 wait_queue_head_t open, wait_frame, wait_stream;
261 struct video_device *vbi_dev;
262
263 unsigned char eedata[256];
264
265 /* usb transfer */
266 struct usb_device *udev; /* the usb device */
267 int alt; /* alternate */
268 int max_pkt_size; /* max packet size of isoc transaction */
269 int num_alt; /* Number of alternative settings */
270 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
271 struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
272 char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
273 /* helper funcs that call usb_control_msg */
274 int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf,
275 int len);
276 int (*em28xx_read_reg) (struct em28xx * dev, u16 reg);
277 int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg,
278 char *buf, int len);
279 int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg,
280 char *buf, int len);
281 int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg);
282};
283
284/* Provided by em28xx-i2c.c */
285
286void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
287int em28xx_i2c_register(struct em28xx *dev);
288int em28xx_i2c_unregister(struct em28xx *dev);
289
290/* Provided by em28xx-input.c */
291
292void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir);
293
294/* Provided by em28xx-core.c */
295
296void em28xx_print_ioctl(char *name, unsigned int cmd);
297
298u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
299void em28xx_queue_unusedframes(struct em28xx *dev);
300void em28xx_release_buffers(struct em28xx *dev);
301
302int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
303 char *buf, int len);
304int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg);
305int em28xx_read_reg(struct em28xx *dev, u16 reg);
306int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
307 int len);
308int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
309int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
310 u8 bitmask);
311int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val);
312int em28xx_audio_analog_set(struct em28xx *dev);
313int em28xx_colorlevels_set_default(struct em28xx *dev);
314int em28xx_capture_start(struct em28xx *dev, int start);
315int em28xx_outfmt_set_yuv422(struct em28xx *dev);
316int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
317 u8 ymax);
318int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
319 u16 width, u16 height);
320int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v);
321int em28xx_resolution_set(struct em28xx *dev);
322void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs);
323int em28xx_init_isoc(struct em28xx *dev);
324void em28xx_uninit_isoc(struct em28xx *dev);
325int em28xx_set_alternate(struct em28xx *dev);
326
327/* Provided by em28xx-cards.c */
328extern int em2800_variant_detect(struct usb_device* udev,int model);
329extern void em28xx_card_setup(struct em28xx *dev);
330extern struct em28xx_board em28xx_boards[];
331extern struct usb_device_id em28xx_id_table[];
332extern const unsigned int em28xx_bcount;
333
334/* em28xx registers */
335#define CHIPID_REG 0x0a
336#define USBSUSP_REG 0x0c /* */
337
338#define AUDIOSRC_REG 0x0e
339#define XCLK_REG 0x0f
340
341#define VINMODE_REG 0x10
342#define VINCTRL_REG 0x11
343#define VINENABLE_REG 0x12 /* */
344
345#define GAMMA_REG 0x14
346#define RGAIN_REG 0x15
347#define GGAIN_REG 0x16
348#define BGAIN_REG 0x17
349#define ROFFSET_REG 0x18
350#define GOFFSET_REG 0x19
351#define BOFFSET_REG 0x1a
352
353#define OFLOW_REG 0x1b
354#define HSTART_REG 0x1c
355#define VSTART_REG 0x1d
356#define CWIDTH_REG 0x1e
357#define CHEIGHT_REG 0x1f
358
359#define YGAIN_REG 0x20
360#define YOFFSET_REG 0x21
361#define UVGAIN_REG 0x22
362#define UOFFSET_REG 0x23
363#define VOFFSET_REG 0x24
364#define SHARPNESS_REG 0x25
365
366#define COMPR_REG 0x26
367#define OUTFMT_REG 0x27
368
369#define XMIN_REG 0x28
370#define XMAX_REG 0x29
371#define YMIN_REG 0x2a
372#define YMAX_REG 0x2b
373
374#define HSCALELOW_REG 0x30
375#define HSCALEHIGH_REG 0x31
376#define VSCALELOW_REG 0x32
377#define VSCALEHIGH_REG 0x33
378
379#define AC97LSB_REG 0x40
380#define AC97MSB_REG 0x41
381#define AC97ADDR_REG 0x42
382#define AC97BUSY_REG 0x43
383
384/* em202 registers */
385#define MASTER_AC97 0x02
386#define VIDEO_AC97 0x14
387
388/* register settings */
389#define EM28XX_AUDIO_SRC_TUNER 0xc0
390#define EM28XX_AUDIO_SRC_LINE 0x80
391
392/* printk macros */
393
394#define em28xx_err(fmt, arg...) do {\
395 printk(KERN_ERR fmt , ##arg); } while (0)
396
397#define em28xx_errdev(fmt, arg...) do {\
398 printk(KERN_ERR "%s: "fmt,\
399 dev->name , ##arg); } while (0)
400
401#define em28xx_info(fmt, arg...) do {\
402 printk(KERN_INFO "%s: "fmt,\
403 dev->name , ##arg); } while (0)
404#define em28xx_warn(fmt, arg...) do {\
405 printk(KERN_WARNING "%s: "fmt,\
406 dev->name , ##arg); } while (0)
407
408inline static int em28xx_audio_source(struct em28xx *dev, int input)
409{
410 return em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
411}
412
413inline static int em28xx_audio_usb_mute(struct em28xx *dev, int mute)
414{
415 return em28xx_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80);
416}
417
418inline static int em28xx_audio_analog_setup(struct em28xx *dev)
419{
420 /* unmute video mixer with default volume level */
421 return em28xx_write_ac97(dev, VIDEO_AC97, "\x08\x08");
422}
423
424inline static int em28xx_compression_disable(struct em28xx *dev)
425{
426 /* side effect of disabling scaler and mixer */
427 return em28xx_write_regs(dev, COMPR_REG, "\x00", 1);
428}
429
430inline static int em28xx_contrast_get(struct em28xx *dev)
431{
432 return em28xx_read_reg(dev, YGAIN_REG) & 0x1f;
433}
434
435inline static int em28xx_brightness_get(struct em28xx *dev)
436{
437 return em28xx_read_reg(dev, YOFFSET_REG);
438}
439
440inline static int em28xx_saturation_get(struct em28xx *dev)
441{
442 return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f;
443}
444
445inline static int em28xx_u_balance_get(struct em28xx *dev)
446{
447 return em28xx_read_reg(dev, UOFFSET_REG);
448}
449
450inline static int em28xx_v_balance_get(struct em28xx *dev)
451{
452 return em28xx_read_reg(dev, VOFFSET_REG);
453}
454
455inline static int em28xx_gamma_get(struct em28xx *dev)
456{
457 return em28xx_read_reg(dev, GAMMA_REG) & 0x3f;
458}
459
460inline static int em28xx_contrast_set(struct em28xx *dev, s32 val)
461{
462 u8 tmp = (u8) val;
463 return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1);
464}
465
466inline static int em28xx_brightness_set(struct em28xx *dev, s32 val)
467{
468 u8 tmp = (u8) val;
469 return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1);
470}
471
472inline static int em28xx_saturation_set(struct em28xx *dev, s32 val)
473{
474 u8 tmp = (u8) val;
475 return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1);
476}
477
478inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val)
479{
480 u8 tmp = (u8) val;
481 return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1);
482}
483
484inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val)
485{
486 u8 tmp = (u8) val;
487 return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1);
488}
489
490inline static int em28xx_gamma_set(struct em28xx *dev, s32 val)
491{
492 u8 tmp = (u8) val;
493 return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1);
494}
495
496/*FIXME: maxw should be dependent of alt mode */
497inline static unsigned int norm_maxw(struct em28xx *dev)
498{
499 switch(dev->model){
500 case (EM2820_BOARD_MSI_VOX_USB_2): return(640);
501 default: return(720);
502 }
503}
504
505inline static unsigned int norm_maxh(struct em28xx *dev)
506{
507 switch(dev->model){
508 case (EM2820_BOARD_MSI_VOX_USB_2): return(480);
509 default: return (dev->tvnorm->id & V4L2_STD_625_50) ? 576 : 480;
510 }
511}
512
513#endif
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index 234151e48edc..ed81934ef3cd 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -156,6 +156,71 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
156 156
157/* ---------------------------------------------------------------------- */ 157/* ---------------------------------------------------------------------- */
158 158
159/* Ricardo Cerqueira <v4l@cerqueira.org> */
160/* Weird matching, since the remote has "uncommon" keys */
161
162static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
163
164 [ 30 ] = KEY_POWER, // power
165 [ 7 ] = KEY_MEDIA, // source
166 [ 28 ] = KEY_SEARCH, // scan
167
168/* FIXME: duplicate keycodes?
169 *
170 * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
171 * The GPIO values are
172 * 6397fb for both "Scan <" and "CH -",
173 * 639ffb for "Scan >" and "CH+",
174 * 6384fb for "Tune <" and "<<<",
175 * 638cfb for "Tune >" and ">>>", regardless of the mask.
176 *
177 * [ 23 ] = KEY_BACK, // fm scan <<
178 * [ 31 ] = KEY_FORWARD, // fm scan >>
179 *
180 * [ 4 ] = KEY_LEFT, // fm tuning <
181 * [ 12 ] = KEY_RIGHT, // fm tuning >
182 *
183 * For now, these four keys are disabled. Pressing them will generate
184 * the CH+/CH-/<<</>>> events
185 */
186
187 [ 3 ] = KEY_TUNER, // TV/FM
188
189 [ 0 ] = KEY_RECORD,
190 [ 8 ] = KEY_STOP,
191 [ 17 ] = KEY_PLAY,
192
193 [ 26 ] = KEY_PLAYPAUSE, // freeze
194 [ 25 ] = KEY_ZOOM, // zoom
195 [ 15 ] = KEY_TEXT, // min
196
197 [ 1 ] = KEY_KP1,
198 [ 11 ] = KEY_KP2,
199 [ 27 ] = KEY_KP3,
200 [ 5 ] = KEY_KP4,
201 [ 9 ] = KEY_KP5,
202 [ 21 ] = KEY_KP6,
203 [ 6 ] = KEY_KP7,
204 [ 10 ] = KEY_KP8,
205 [ 18 ] = KEY_KP9,
206 [ 2 ] = KEY_KP0,
207 [ 16 ] = KEY_LAST, // +100
208 [ 19 ] = KEY_LIST, // recall
209
210 [ 31 ] = KEY_CHANNELUP, // chn down
211 [ 23 ] = KEY_CHANNELDOWN, // chn up
212 [ 22 ] = KEY_VOLUMEUP, // vol down
213 [ 20 ] = KEY_VOLUMEDOWN, // vol up
214
215 [ 4 ] = KEY_KPMINUS, // <<<
216 [ 14 ] = KEY_SETUP, // function
217 [ 12 ] = KEY_KPPLUS, // >>>
218
219 [ 13 ] = KEY_GOTO, // mts
220 [ 29 ] = KEY_REFRESH, // reset
221 [ 24 ] = KEY_MUTE // mute/unmute
222};
223
159struct IR { 224struct IR {
160 struct bttv_sub_device *sub; 225 struct bttv_sub_device *sub;
161 struct input_dev *input; 226 struct input_dev *input;
@@ -282,53 +347,59 @@ static int ir_probe(struct device *dev)
282 347
283 /* detect & configure */ 348 /* detect & configure */
284 switch (sub->core->type) { 349 switch (sub->core->type) {
285 case BTTV_AVERMEDIA: 350 case BTTV_BOARD_AVERMEDIA:
286 case BTTV_AVPHONE98: 351 case BTTV_BOARD_AVPHONE98:
287 case BTTV_AVERMEDIA98: 352 case BTTV_BOARD_AVERMEDIA98:
288 ir_codes = ir_codes_avermedia; 353 ir_codes = ir_codes_avermedia;
289 ir->mask_keycode = 0xf88000; 354 ir->mask_keycode = 0xf88000;
290 ir->mask_keydown = 0x010000; 355 ir->mask_keydown = 0x010000;
291 ir->polling = 50; // ms 356 ir->polling = 50; // ms
292 break; 357 break;
293 358
294 case BTTV_AVDVBT_761: 359 case BTTV_BOARD_AVDVBT_761:
295 case BTTV_AVDVBT_771: 360 case BTTV_BOARD_AVDVBT_771:
296 ir_codes = ir_codes_avermedia_dvbt; 361 ir_codes = ir_codes_avermedia_dvbt;
297 ir->mask_keycode = 0x0f00c0; 362 ir->mask_keycode = 0x0f00c0;
298 ir->mask_keydown = 0x000020; 363 ir->mask_keydown = 0x000020;
299 ir->polling = 50; // ms 364 ir->polling = 50; // ms
300 break; 365 break;
301 366
302 case BTTV_PXELVWPLTVPAK: 367 case BTTV_BOARD_PXELVWPLTVPAK:
303 ir_codes = ir_codes_pixelview; 368 ir_codes = ir_codes_pixelview;
304 ir->mask_keycode = 0x003e00; 369 ir->mask_keycode = 0x003e00;
305 ir->mask_keyup = 0x010000; 370 ir->mask_keyup = 0x010000;
306 ir->polling = 50; // ms 371 ir->polling = 50; // ms
307 break; 372 break;
308 case BTTV_PV_BT878P_9B: 373 case BTTV_BOARD_PV_BT878P_9B:
309 case BTTV_PV_BT878P_PLUS: 374 case BTTV_BOARD_PV_BT878P_PLUS:
310 ir_codes = ir_codes_pixelview; 375 ir_codes = ir_codes_pixelview;
311 ir->mask_keycode = 0x001f00; 376 ir->mask_keycode = 0x001f00;
312 ir->mask_keyup = 0x008000; 377 ir->mask_keyup = 0x008000;
313 ir->polling = 50; // ms 378 ir->polling = 50; // ms
314 break; 379 break;
315 380
316 case BTTV_WINFAST2000: 381 case BTTV_BOARD_WINFAST2000:
317 ir_codes = ir_codes_winfast; 382 ir_codes = ir_codes_winfast;
318 ir->mask_keycode = 0x1f8; 383 ir->mask_keycode = 0x1f8;
319 break; 384 break;
320 case BTTV_MAGICTVIEW061: 385 case BTTV_BOARD_MAGICTVIEW061:
321 case BTTV_MAGICTVIEW063: 386 case BTTV_BOARD_MAGICTVIEW063:
322 ir_codes = ir_codes_winfast; 387 ir_codes = ir_codes_winfast;
323 ir->mask_keycode = 0x0008e000; 388 ir->mask_keycode = 0x0008e000;
324 ir->mask_keydown = 0x00200000; 389 ir->mask_keydown = 0x00200000;
325 break; 390 break;
326 case BTTV_APAC_VIEWCOMP: 391 case BTTV_BOARD_APAC_VIEWCOMP:
327 ir_codes = ir_codes_apac_viewcomp; 392 ir_codes = ir_codes_apac_viewcomp;
328 ir->mask_keycode = 0x001f00; 393 ir->mask_keycode = 0x001f00;
329 ir->mask_keyup = 0x008000; 394 ir->mask_keyup = 0x008000;
330 ir->polling = 50; // ms 395 ir->polling = 50; // ms
331 break; 396 break;
397 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
398 ir_codes = ir_codes_conceptronic;
399 ir->mask_keycode = 0x001F00;
400 ir->mask_keyup = 0x006000;
401 ir->polling = 50; // ms
402 break;
332 } 403 }
333 if (NULL == ir_codes) { 404 if (NULL == ir_codes) {
334 kfree(ir); 405 kfree(ir);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 9703d3d351f9..0085567a1421 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -8,6 +8,8 @@
8 * Christoph Bartelmus <lirc@bartelmus.de> 8 * Christoph Bartelmus <lirc@bartelmus.de>
9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by 9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
10 * Ulrich Mueller <ulrich.mueller42@web.de> 10 * Ulrich Mueller <ulrich.mueller42@web.de>
11 * modified for em2820 based USB TV tuners by
12 * Markus Rechberger <mrechberger@gmail.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -37,10 +39,9 @@
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/i2c.h> 40#include <linux/i2c.h>
39#include <linux/workqueue.h> 41#include <linux/workqueue.h>
40
41#include <asm/semaphore.h> 42#include <asm/semaphore.h>
42
43#include <media/ir-common.h> 43#include <media/ir-common.h>
44#include <media/ir-kbd-i2c.h>
44 45
45/* Mark Phalan <phalanm@o2.ie> */ 46/* Mark Phalan <phalanm@o2.ie> */
46static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { 47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
@@ -81,57 +82,6 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
81 [ 28 ] = KEY_MEDIA, /* PC/TV */ 82 [ 28 ] = KEY_MEDIA, /* PC/TV */
82}; 83};
83 84
84static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
85 [ 0x3 ] = KEY_POWER,
86 [ 0x6f ] = KEY_MUTE,
87 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
88
89 [ 0x11 ] = KEY_KP0,
90 [ 0x4 ] = KEY_KP1,
91 [ 0x5 ] = KEY_KP2,
92 [ 0x6 ] = KEY_KP3,
93 [ 0x8 ] = KEY_KP4,
94 [ 0x9 ] = KEY_KP5,
95 [ 0xa ] = KEY_KP6,
96 [ 0xc ] = KEY_KP7,
97 [ 0xd ] = KEY_KP8,
98 [ 0xe ] = KEY_KP9,
99 [ 0x12 ] = KEY_KPDOT, /* 100+ */
100
101 [ 0x7 ] = KEY_VOLUMEUP,
102 [ 0xb ] = KEY_VOLUMEDOWN,
103 [ 0x1a ] = KEY_KPPLUS,
104 [ 0x18 ] = KEY_KPMINUS,
105 [ 0x15 ] = KEY_UP,
106 [ 0x1d ] = KEY_DOWN,
107 [ 0xf ] = KEY_CHANNELUP,
108 [ 0x13 ] = KEY_CHANNELDOWN,
109 [ 0x48 ] = KEY_ZOOM,
110
111 [ 0x1b ] = KEY_VIDEO, /* Video source */
112 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
113 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
114
115 [ 0x4b ] = KEY_RECORD,
116 [ 0x46 ] = KEY_PLAY,
117 [ 0x45 ] = KEY_PAUSE, /* Pause */
118 [ 0x44 ] = KEY_STOP,
119 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
120 [ 0x42 ] = KEY_REWIND, /* Backward ? */
121
122};
123
124struct IR {
125 struct i2c_client c;
126 struct input_dev *input;
127 struct ir_input_state ir;
128
129 struct work_struct work;
130 struct timer_list timer;
131 char phys[32];
132 int (*get_key)(struct IR*, u32*, u32*);
133};
134
135/* ----------------------------------------------------------------------- */ 85/* ----------------------------------------------------------------------- */
136/* insmod parameters */ 86/* insmod parameters */
137 87
@@ -144,7 +94,7 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
144 94
145/* ----------------------------------------------------------------------- */ 95/* ----------------------------------------------------------------------- */
146 96
147static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) 97static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
148{ 98{
149 unsigned char buf[3]; 99 unsigned char buf[3];
150 int start, toggle, dev, code; 100 int start, toggle, dev, code;
@@ -171,9 +121,9 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
171 return 1; 121 return 1;
172} 122}
173 123
174static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) 124static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
175{ 125{
176 unsigned char b; 126 unsigned char b;
177 127
178 /* poll IR chip */ 128 /* poll IR chip */
179 if (1 != i2c_master_recv(&ir->c,&b,1)) { 129 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -185,9 +135,9 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
185 return 1; 135 return 1;
186} 136}
187 137
188static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) 138static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
189{ 139{
190 unsigned char b; 140 unsigned char b;
191 141
192 /* poll IR chip */ 142 /* poll IR chip */
193 if (1 != i2c_master_recv(&ir->c,&b,1)) { 143 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -205,7 +155,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
205 return 1; 155 return 1;
206} 156}
207 157
208static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) 158static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
209{ 159{
210 unsigned char b; 160 unsigned char b;
211 161
@@ -216,15 +166,15 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
216 } 166 }
217 167
218 /* it seems that 0xFE indicates that a button is still hold 168 /* it seems that 0xFE indicates that a button is still hold
219 down, while 0xFF indicates that no button is hold 169 down, while 0xff indicates that no button is hold
220 down. 0xFE sequences are sometimes interrupted by 0xFF */ 170 down. 0xfe sequences are sometimes interrupted by 0xFF */
221 171
222 dprintk(2,"key %02x\n", b); 172 dprintk(2,"key %02x\n", b);
223 173
224 if (b == 0xFF) 174 if (b == 0xff)
225 return 0; 175 return 0;
226 176
227 if (b == 0xFE) 177 if (b == 0xfe)
228 /* keep old data */ 178 /* keep old data */
229 return 1; 179 return 1;
230 180
@@ -233,31 +183,9 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
233 return 1; 183 return 1;
234} 184}
235 185
236static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
237{
238 unsigned char b;
239
240 /* poll IR chip */
241 if (1 != i2c_master_recv(&ir->c,&b,1)) {
242 dprintk(1,"read error\n");
243 return -EIO;
244 }
245
246 /* no button press */
247 if (b==0)
248 return 0;
249
250 /* repeating */
251 if (b & 0x80)
252 return 1;
253
254 *ir_key = b;
255 *ir_raw = b;
256 return 1;
257}
258/* ----------------------------------------------------------------------- */ 186/* ----------------------------------------------------------------------- */
259 187
260static void ir_key_poll(struct IR *ir) 188static void ir_key_poll(struct IR_i2c *ir)
261{ 189{
262 static u32 ir_key, ir_raw; 190 static u32 ir_key, ir_raw;
263 int rc; 191 int rc;
@@ -278,13 +206,13 @@ static void ir_key_poll(struct IR *ir)
278 206
279static void ir_timer(unsigned long data) 207static void ir_timer(unsigned long data)
280{ 208{
281 struct IR *ir = (struct IR*)data; 209 struct IR_i2c *ir = (struct IR_i2c*)data;
282 schedule_work(&ir->work); 210 schedule_work(&ir->work);
283} 211}
284 212
285static void ir_work(void *data) 213static void ir_work(void *data)
286{ 214{
287 struct IR *ir = data; 215 struct IR_i2c *ir = data;
288 ir_key_poll(ir); 216 ir_key_poll(ir);
289 mod_timer(&ir->timer, jiffies+HZ/10); 217 mod_timer(&ir->timer, jiffies+HZ/10);
290} 218}
@@ -297,17 +225,17 @@ static int ir_detach(struct i2c_client *client);
297static int ir_probe(struct i2c_adapter *adap); 225static int ir_probe(struct i2c_adapter *adap);
298 226
299static struct i2c_driver driver = { 227static struct i2c_driver driver = {
300 .name = "ir remote kbd driver", 228 .name = "ir remote kbd driver",
301 .id = I2C_DRIVERID_EXP3, /* FIXME */ 229 .id = I2C_DRIVERID_EXP3, /* FIXME */
302 .flags = I2C_DF_NOTIFY, 230 .flags = I2C_DF_NOTIFY,
303 .attach_adapter = ir_probe, 231 .attach_adapter = ir_probe,
304 .detach_client = ir_detach, 232 .detach_client = ir_detach,
305}; 233};
306 234
307static struct i2c_client client_template = 235static struct i2c_client client_template =
308{ 236{
309 .name = "unset", 237 .name = "unset",
310 .driver = &driver 238 .driver = &driver
311}; 239};
312 240
313static int ir_attach(struct i2c_adapter *adap, int addr, 241static int ir_attach(struct i2c_adapter *adap, int addr,
@@ -316,10 +244,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
316 IR_KEYTAB_TYPE *ir_codes = NULL; 244 IR_KEYTAB_TYPE *ir_codes = NULL;
317 char *name; 245 char *name;
318 int ir_type; 246 int ir_type;
319 struct IR *ir; 247 struct IR_i2c *ir;
320 struct input_dev *input_dev; 248 struct input_dev *input_dev;
321 249
322 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 250 ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
323 input_dev = input_allocate_device(); 251 input_dev = input_allocate_device();
324 if (!ir || !input_dev) { 252 if (!ir || !input_dev) {
325 kfree(ir); 253 kfree(ir);
@@ -361,10 +289,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
361 ir_codes = ir_codes_empty; 289 ir_codes = ir_codes_empty;
362 break; 290 break;
363 case 0x7a: 291 case 0x7a:
364 name = "Purple TV"; 292 case 0x47:
365 ir->get_key = get_key_purpletv; 293 /* Handled by saa7134-input */
294 name = "SAA713x remote";
366 ir_type = IR_TYPE_OTHER; 295 ir_type = IR_TYPE_OTHER;
367 ir_codes = ir_codes_purpletv;
368 break; 296 break;
369 default: 297 default:
370 /* shouldn't happen */ 298 /* shouldn't happen */
@@ -373,9 +301,24 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
373 return -1; 301 return -1;
374 } 302 }
375 303
376 /* register i2c device */ 304 /* Sets name */
377 i2c_attach_client(&ir->c);
378 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); 305 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
306 ir->ir_codes=ir_codes;
307
308 /* register i2c device
309 * At device register, IR codes may be changed to be
310 * board dependent.
311 */
312 i2c_attach_client(&ir->c);
313
314 /* If IR not supported or disabled, unregisters driver */
315 if (ir->get_key == NULL) {
316 i2c_detach_client(&ir->c);
317 kfree(ir);
318 return -1;
319 }
320
321 /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
379 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 322 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
380 ir->c.adapter->dev.bus_id, 323 ir->c.adapter->dev.bus_id,
381 ir->c.dev.bus_id); 324 ir->c.dev.bus_id);
@@ -386,6 +329,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
386 input_dev->name = ir->c.name; 329 input_dev->name = ir->c.name;
387 input_dev->phys = ir->phys; 330 input_dev->phys = ir->phys;
388 331
332 /* register event device */
389 input_register_device(ir->input); 333 input_register_device(ir->input);
390 334
391 /* start polling via eventd */ 335 /* start polling via eventd */
@@ -400,7 +344,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
400 344
401static int ir_detach(struct i2c_client *client) 345static int ir_detach(struct i2c_client *client)
402{ 346{
403 struct IR *ir = i2c_get_clientdata(client); 347 struct IR_i2c *ir = i2c_get_clientdata(client);
404 348
405 /* kill outstanding polls */ 349 /* kill outstanding polls */
406 del_timer(&ir->timer); 350 del_timer(&ir->timer);
@@ -428,9 +372,12 @@ static int ir_probe(struct i2c_adapter *adap)
428 */ 372 */
429 373
430 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; 374 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
431 static const int probe_saa7134[] = { 0x7a, -1 }; 375 static const int probe_saa7134[] = { 0x7a, 0x47, -1 };
376 static const int probe_em28XX[] = { 0x30, 0x47, -1 };
432 const int *probe = NULL; 377 const int *probe = NULL;
433 struct i2c_client c; char buf; int i,rc; 378 struct i2c_client c;
379 unsigned char buf;
380 int i,rc;
434 381
435 switch (adap->id) { 382 switch (adap->id) {
436 case I2C_HW_B_BT848: 383 case I2C_HW_B_BT848:
@@ -439,6 +386,9 @@ static int ir_probe(struct i2c_adapter *adap)
439 case I2C_HW_SAA7134: 386 case I2C_HW_SAA7134:
440 probe = probe_saa7134; 387 probe = probe_saa7134;
441 break; 388 break;
389 case I2C_HW_B_EM28XX:
390 probe = probe_em28XX;
391 break;
442 } 392 }
443 if (NULL == probe) 393 if (NULL == probe)
444 return 0; 394 return 0;
@@ -447,11 +397,11 @@ static int ir_probe(struct i2c_adapter *adap)
447 c.adapter = adap; 397 c.adapter = adap;
448 for (i = 0; -1 != probe[i]; i++) { 398 for (i = 0; -1 != probe[i]; i++) {
449 c.addr = probe[i]; 399 c.addr = probe[i];
450 rc = i2c_master_recv(&c,&buf,1); 400 rc = i2c_master_recv(&c,&buf,0);
451 dprintk(1,"probe 0x%02x @ %s: %s\n", 401 dprintk(1,"probe 0x%02x @ %s: %s\n",
452 probe[i], adap->name, 402 probe[i], adap->name,
453 (1 == rc) ? "yes" : "no"); 403 (0 == rc) ? "yes" : "no");
454 if (1 == rc) { 404 if (0 == rc) {
455 ir_attach(adap,probe[i],0,0); 405 ir_attach(adap,probe[i],0,0);
456 break; 406 break;
457 } 407 }
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index e75e7948fd9d..a23fb0338986 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -54,9 +54,41 @@
54#include <asm/pgtable.h> 54#include <asm/pgtable.h>
55 55
56#include <media/audiochip.h> 56#include <media/audiochip.h>
57#include <media/id.h>
58#include "msp3400.h" 57#include "msp3400.h"
59 58
59#define msp3400_dbg(fmt, arg...) \
60 do { \
61 if (debug) \
62 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
63 i2c_adapter_id(client->adapter), client->addr , ## arg); \
64 } while (0)
65
66/* Medium volume debug. */
67#define msp3400_dbg_mediumvol(fmt, arg...) \
68 do { \
69 if (debug >= 2) \
70 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
71 i2c_adapter_id(client->adapter), client->addr , ## arg); \
72 } while (0)
73
74/* High volume debug. Use with care. */
75#define msp3400_dbg_highvol(fmt, arg...) \
76 do { \
77 if (debug >= 16) \
78 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
79 i2c_adapter_id(client->adapter), client->addr , ## arg); \
80 } while (0)
81
82#define msp3400_err(fmt, arg...) do { \
83 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
84 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
85#define msp3400_warn(fmt, arg...) do { \
86 printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \
87 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
88#define msp3400_info(fmt, arg...) do { \
89 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
90 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
91
60#define OPMODE_AUTO -1 92#define OPMODE_AUTO -1
61#define OPMODE_MANUAL 0 93#define OPMODE_MANUAL 0
62#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ 94#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
@@ -73,15 +105,26 @@ static int dolby = 0;
73 105
74static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual 106static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
75 (msp34xxg only) 0x00a0-0x03c0 */ 107 (msp34xxg only) 0x00a0-0x03c0 */
108#define DFP_COUNT 0x41
109static const int bl_dfp[] = {
110 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
111 0x0b, 0x0d, 0x0e, 0x10
112};
113
114#define IS_MSP34XX_G(msp) ((msp)->opmode==2)
76 115
77struct msp3400c { 116struct msp3400c {
78 int rev1,rev2; 117 int rev1,rev2;
79 118
80 int opmode; 119 int opmode;
120 int nicam;
81 int mode; 121 int mode;
82 int norm; 122 int norm;
123 int stereo;
83 int nicam_on; 124 int nicam_on;
84 int acb; 125 int acb;
126 int in_scart;
127 int i2s_mode;
85 int main, second; /* sound carrier */ 128 int main, second; /* sound carrier */
86 int input; 129 int input;
87 int source; /* see msp34xxg_set_source */ 130 int source; /* see msp34xxg_set_source */
@@ -91,9 +134,12 @@ struct msp3400c {
91 int rxsubchans; 134 int rxsubchans;
92 135
93 int muted; 136 int muted;
94 int volume, balance; 137 int left, right; /* volume */
95 int bass, treble; 138 int bass, treble;
96 139
140 /* shadow register set */
141 int dfp_regs[DFP_COUNT];
142
97 /* thread */ 143 /* thread */
98 struct task_struct *kthread; 144 struct task_struct *kthread;
99 wait_queue_head_t wq; 145 wait_queue_head_t wq;
@@ -101,6 +147,8 @@ struct msp3400c {
101 int watch_stereo:1; 147 int watch_stereo:1;
102}; 148};
103 149
150#define MIN(a,b) (((a)>(b))?(b):(a))
151#define MAX(a,b) (((a)>(b))?(a):(b))
104#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) 152#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
105#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') 153#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
106#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') 154#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
@@ -110,9 +158,6 @@ struct msp3400c {
110 158
111/* ---------------------------------------------------------------------- */ 159/* ---------------------------------------------------------------------- */
112 160
113#define dprintk if (debug >= 1) printk
114#define d2printk if (debug >= 2) printk
115
116/* read-only */ 161/* read-only */
117module_param(opmode, int, 0444); 162module_param(opmode, int, 0444);
118 163
@@ -132,11 +177,6 @@ MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Defau
132MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); 177MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
133MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); 178MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
134 179
135
136MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
137MODULE_AUTHOR("Gerd Knorr");
138MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
139
140/* ---------------------------------------------------------------------- */ 180/* ---------------------------------------------------------------------- */
141 181
142#define I2C_MSP3400C 0x80 182#define I2C_MSP3400C 0x80
@@ -153,6 +193,10 @@ static unsigned short normal_i2c[] = {
153}; 193};
154I2C_CLIENT_INSMOD; 194I2C_CLIENT_INSMOD;
155 195
196MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
197MODULE_AUTHOR("Gerd Knorr");
198MODULE_LICENSE("GPL");
199
156/* ----------------------------------------------------------------------- */ 200/* ----------------------------------------------------------------------- */
157/* functions for talking to the MSP3400C Sound processor */ 201/* functions for talking to the MSP3400C Sound processor */
158 202
@@ -172,68 +216,73 @@ static int msp3400c_reset(struct i2c_client *client)
172 { client->addr, I2C_M_RD, 2, read }, 216 { client->addr, I2C_M_RD, 2, read },
173 }; 217 };
174 218
219 msp3400_dbg_highvol("msp3400c_reset\n");
175 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || 220 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
176 (1 != i2c_transfer(client->adapter,&reset[1],1)) || 221 (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
177 (2 != i2c_transfer(client->adapter,test,2)) ) { 222 (2 != i2c_transfer(client->adapter,test,2)) ) {
178 printk(KERN_ERR "msp3400: chip reset failed\n"); 223 msp3400_err("chip reset failed\n");
179 return -1; 224 return -1;
180 } 225 }
181 return 0; 226 return 0;
182} 227}
183 228
184static int 229static int msp3400c_read(struct i2c_client *client, int dev, int addr)
185msp3400c_read(struct i2c_client *client, int dev, int addr)
186{ 230{
187 int err; 231 int err,retval;
232
233 unsigned char write[3];
234 unsigned char read[2];
235 struct i2c_msg msgs[2] = {
236 { client->addr, 0, 3, write },
237 { client->addr, I2C_M_RD, 2, read }
238 };
188 239
189 unsigned char write[3]; 240 write[0] = dev+1;
190 unsigned char read[2]; 241 write[1] = addr >> 8;
191 struct i2c_msg msgs[2] = { 242 write[2] = addr & 0xff;
192 { client->addr, 0, 3, write },
193 { client->addr, I2C_M_RD, 2, read }
194 };
195 write[0] = dev+1;
196 write[1] = addr >> 8;
197 write[2] = addr & 0xff;
198 243
199 for (err = 0; err < 3;) { 244 for (err = 0; err < 3;) {
200 if (2 == i2c_transfer(client->adapter,msgs,2)) 245 if (2 == i2c_transfer(client->adapter,msgs,2))
201 break; 246 break;
202 err++; 247 err++;
203 printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n", 248 msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
204 err, dev, addr); 249 dev, addr);
205 msleep(10); 250 current->state = TASK_INTERRUPTIBLE;
251 schedule_timeout(msecs_to_jiffies(10));
206 } 252 }
207 if (3 == err) { 253 if (3 == err) {
208 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 254 msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
209 msp3400c_reset(client); 255 msp3400c_reset(client);
210 return -1; 256 return -1;
211 } 257 }
212 return read[0] << 8 | read[1]; 258 retval = read[0] << 8 | read[1];
259 msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
260 return retval;
213} 261}
214 262
215static int 263static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
216msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
217{ 264{
218 int err; 265 int err;
219 unsigned char buffer[5]; 266 unsigned char buffer[5];
220 267
221 buffer[0] = dev; 268 buffer[0] = dev;
222 buffer[1] = addr >> 8; 269 buffer[1] = addr >> 8;
223 buffer[2] = addr & 0xff; 270 buffer[2] = addr & 0xff;
224 buffer[3] = val >> 8; 271 buffer[3] = val >> 8;
225 buffer[4] = val & 0xff; 272 buffer[4] = val & 0xff;
226 273
274 msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
227 for (err = 0; err < 3;) { 275 for (err = 0; err < 3;) {
228 if (5 == i2c_master_send(client, buffer, 5)) 276 if (5 == i2c_master_send(client, buffer, 5))
229 break; 277 break;
230 err++; 278 err++;
231 printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n", 279 msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
232 err, dev, addr); 280 dev, addr);
233 msleep(10); 281 current->state = TASK_INTERRUPTIBLE;
282 schedule_timeout(msecs_to_jiffies(10));
234 } 283 }
235 if (3 == err) { 284 if (3 == err) {
236 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 285 msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n");
237 msp3400c_reset(client); 286 msp3400c_reset(client);
238 return -1; 287 return -1;
239 } 288 }
@@ -266,45 +315,47 @@ static struct MSP_INIT_DATA_DEM {
266 int dfp_src; 315 int dfp_src;
267 int dfp_matrix; 316 int dfp_matrix;
268} msp_init_data[] = { 317} msp_init_data[] = {
269 /* AM (for carrier detect / msp3400) */ 318 { /* AM (for carrier detect / msp3400) */
270 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 }, 319 {75, 19, 36, 35, 39, 40},
271 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 320 {75, 19, 36, 35, 39, 40},
272 0x00d0, 0x0500, 0x0020, 0x3000}, 321 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
273 322 0x00d0, 0x0500, 0x0020, 0x3000
274 /* AM (for carrier detect / msp3410) */ 323 },{ /* AM (for carrier detect / msp3410) */
275 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 }, 324 {-1, -1, -8, 2, 59, 126},
276 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 325 {-1, -1, -8, 2, 59, 126},
277 0x00d0, 0x0100, 0x0020, 0x3000}, 326 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
278 327 0x00d0, 0x0100, 0x0020, 0x3000
279 /* FM Radio */ 328 },{ /* FM Radio */
280 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 }, 329 {-8, -8, 4, 6, 78, 107},
281 MSP_CARRIER(10.7), MSP_CARRIER(10.7), 330 {-8, -8, 4, 6, 78, 107},
282 0x00d0, 0x0480, 0x0020, 0x3000 }, 331 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
283 332 0x00d0, 0x0480, 0x0020, 0x3000
284 /* Terrestial FM-mono + FM-stereo */ 333 },{ /* Terrestial FM-mono + FM-stereo */
285 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 }, 334 {3, 18, 27, 48, 66, 72},
286 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 335 {3, 18, 27, 48, 66, 72},
287 0x00d0, 0x0480, 0x0030, 0x3000}, 336 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
288 337 0x00d0, 0x0480, 0x0030, 0x3000
289 /* Sat FM-mono */ 338 },{ /* Sat FM-mono */
290 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 }, 339 { 1, 9, 14, 24, 33, 37},
291 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 340 { 3, 18, 27, 48, 66, 72},
292 0x00c6, 0x0480, 0x0000, 0x3000}, 341 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
293 342 0x00c6, 0x0480, 0x0000, 0x3000
294 /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ 343 },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
295 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 }, 344 {-2, -8, -10, 10, 50, 86},
296 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 345 {3, 18, 27, 48, 66, 72},
297 0x00d0, 0x0040, 0x0120, 0x3000}, 346 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
298 347 0x00d0, 0x0040, 0x0120, 0x3000
299 /* NICAM/FM -- I (6.0/6.552) */ 348 },{ /* NICAM/FM -- I (6.0/6.552) */
300 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 }, 349 {2, 4, -6, -4, 40, 94},
301 MSP_CARRIER(6.0), MSP_CARRIER(6.0), 350 {3, 18, 27, 48, 66, 72},
302 0x00d0, 0x0040, 0x0120, 0x3000}, 351 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
303 352 0x00d0, 0x0040, 0x0120, 0x3000
304 /* NICAM/AM -- L (6.5/5.85) */ 353 },{ /* NICAM/AM -- L (6.5/5.85) */
305 { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 }, 354 {-2, -8, -10, 10, 50, 86},
306 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 355 {-4, -12, -9, 23, 79, 126},
307 0x00c6, 0x0140, 0x0120, 0x7c03}, 356 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
357 0x00c6, 0x0140, 0x0120, 0x7c03
358 },
308}; 359};
309 360
310struct CARRIER_DETECT { 361struct CARRIER_DETECT {
@@ -338,32 +389,68 @@ static struct CARRIER_DETECT carrier_detect_65[] = {
338 389
339#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) 390#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
340 391
341/* ----------------------------------------------------------------------- */ 392/* ----------------------------------------------------------------------- *
393 * bits 9 8 5 - SCART DSP input Select:
394 * 0 0 0 - SCART 1 to DSP input (reset position)
395 * 0 1 0 - MONO to DSP input
396 * 1 0 0 - SCART 2 to DSP input
397 * 1 1 1 - Mute DSP input
398 *
399 * bits 11 10 6 - SCART 1 Output Select:
400 * 0 0 0 - undefined (reset position)
401 * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
402 * 1 0 0 - MONO input to SCART 1 Output
403 * 1 1 0 - SCART 1 DA to SCART 1 Output
404 * 0 0 1 - SCART 2 DA to SCART 1 Output
405 * 0 1 1 - SCART 1 Input to SCART 1 Output
406 * 1 1 1 - Mute SCART 1 Output
407 *
408 * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
409 * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
410 * 0 1 0 - SCART 1 Input to SCART 2 Output
411 * 1 0 0 - MONO input to SCART 2 Output
412 * 0 0 1 - SCART 2 DA to SCART 2 Output
413 * 0 1 1 - SCART 2 Input to SCART 2 Output
414 * 1 1 0 - Mute SCART 2 Output
415 *
416 * Bits 4 to 0 should be zero.
417 * ----------------------------------------------------------------------- */
342 418
343static int scarts[3][9] = { 419static int scarts[3][9] = {
344 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ 420 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
345 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, 421 /* SCART DSP Input select */
346 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, 422 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
347 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, 423 /* SCART1 Output select */
424 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
425 /* SCART2 Output select */
426 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
348}; 427};
349 428
350static char *scart_names[] = { 429static char *scart_names[] = {
351 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" 430 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
352}; 431};
353 432
354static void 433static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
355msp3400c_set_scart(struct i2c_client *client, int in, int out)
356{ 434{
357 struct msp3400c *msp = i2c_get_clientdata(client); 435 struct msp3400c *msp = i2c_get_clientdata(client);
358 436
359 if (-1 == scarts[out][in]) 437 msp->in_scart=in;
360 return; 438
439 if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
440 if (-1 == scarts[out][in])
441 return;
361 442
362 dprintk(KERN_DEBUG 443 msp->acb &= ~scarts[out][SCART_MASK];
363 "msp34xx: scart switch: %s => %d\n",scart_names[in],out); 444 msp->acb |= scarts[out][in];
364 msp->acb &= ~scarts[out][SCART_MASK]; 445 } else
365 msp->acb |= scarts[out][in]; 446 msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
366 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); 447
448 msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n",
449 scart_names[in], out, msp->acb);
450 msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
451
452 /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
453 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
367} 454}
368 455
369/* ------------------------------------------------------------------------ */ 456/* ------------------------------------------------------------------------ */
@@ -378,33 +465,34 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
378} 465}
379 466
380static void msp3400c_setvolume(struct i2c_client *client, 467static void msp3400c_setvolume(struct i2c_client *client,
381 int muted, int volume, int balance) 468 int muted, int left, int right)
382{ 469 {
383 int val = 0, bal = 0; 470 int vol = 0, val = 0, balance = 0;
384 471
385 if (!muted) { 472 if (!muted) {
386 /* 0x7f instead if 0x73 here has sound quality issues, 473 /* 0x7f instead if 0x73 here has sound quality issues,
387 * probably due to overmodulation + clipping ... */ 474 * probably due to overmodulation + clipping ... */
388 val = (volume * 0x73 / 65535) << 8; 475 vol = (left > right) ? left : right;
476 val = (vol * 0x73 / 65535) << 8;
389 } 477 }
390 if (val) { 478 if (vol > 0) {
391 bal = (balance / 256) - 128; 479 balance = ((right - left) * 127) / vol;
392 } 480 }
393 dprintk(KERN_DEBUG 481
394 "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", 482 msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
395 muted ? "on" : "off", volume, balance, val>>8, bal); 483 muted ? "on" : "off", left, right, val >> 8, balance);
396 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ 484 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
397 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ 485 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
398 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, 486 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
399 muted ? 0x01 : (val | 0x01)); 487 muted ? 0x1 : (val | 0x1));
400 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); 488 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8);
401} 489}
402 490
403static void msp3400c_setbass(struct i2c_client *client, int bass) 491static void msp3400c_setbass(struct i2c_client *client, int bass)
404{ 492{
405 int val = ((bass-32768) * 0x60 / 65535) << 8; 493 int val = ((bass-32768) * 0x60 / 65535) << 8;
406 494
407 dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8); 495 msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8);
408 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ 496 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
409} 497}
410 498
@@ -412,7 +500,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble)
412{ 500{
413 int val = ((treble-32768) * 0x60 / 65535) << 8; 501 int val = ((treble-32768) * 0x60 / 65535) << 8;
414 502
415 dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8); 503 msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8);
416 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ 504 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
417} 505}
418 506
@@ -421,7 +509,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
421 struct msp3400c *msp = i2c_get_clientdata(client); 509 struct msp3400c *msp = i2c_get_clientdata(client);
422 int i; 510 int i;
423 511
424 dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type); 512 msp3400_dbg("setmode: %d\n",type);
425 msp->mode = type; 513 msp->mode = type;
426 msp->audmode = V4L2_TUNER_MODE_MONO; 514 msp->audmode = V4L2_TUNER_MODE_MONO;
427 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 515 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -474,7 +562,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
474 } 562 }
475} 563}
476 564
477static int best_audio_mode(int rxsubchans) 565/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
566static int best_video_sound(int rxsubchans)
478{ 567{
479 if (rxsubchans & V4L2_TUNER_SUB_STEREO) 568 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
480 return V4L2_TUNER_MODE_STEREO; 569 return V4L2_TUNER_MODE_STEREO;
@@ -486,31 +575,31 @@ static int best_audio_mode(int rxsubchans)
486} 575}
487 576
488/* turn on/off nicam + stereo */ 577/* turn on/off nicam + stereo */
489static void msp3400c_set_audmode(struct i2c_client *client, int audmode) 578static void msp3400c_setstereo(struct i2c_client *client, int mode)
490{ 579{
491 static char *strmode[16] = { 580 static char *strmode[] = { "0", "mono", "stereo", "3",
492#if __GNUC__ >= 3 581 "lang1", "5", "6", "7", "lang2"
493 [ 0 ... 15 ] = "invalid",
494#endif
495 [ V4L2_TUNER_MODE_MONO ] = "mono",
496 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
497 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
498 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
499 }; 582 };
500 struct msp3400c *msp = i2c_get_clientdata(client); 583 struct msp3400c *msp = i2c_get_clientdata(client);
501 int nicam=0; /* channel source: FM/AM or nicam */ 584 int nicam = 0; /* channel source: FM/AM or nicam */
502 int src=0; 585 int src = 0;
503 586
504 BUG_ON(msp->opmode == OPMODE_SIMPLER); 587 if (IS_MSP34XX_G(msp)) {
505 msp->audmode = audmode; 588 /* this method would break everything, let's make sure
589 * it's never called
590 */
591 msp3400_dbg
592 ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n",
593 mode);
594 return;
595 }
506 596
507 /* switch demodulator */ 597 /* switch demodulator */
508 switch (msp->mode) { 598 switch (msp->mode) {
509 case MSP_MODE_FM_TERRA: 599 case MSP_MODE_FM_TERRA:
510 dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n", 600 msp3400_dbg("FM setstereo: %s\n", strmode[mode]);
511 strmode[audmode]);
512 msp3400c_setcarrier(client,msp->second,msp->main); 601 msp3400c_setcarrier(client,msp->second,msp->main);
513 switch (audmode) { 602 switch (mode) {
514 case V4L2_TUNER_MODE_STEREO: 603 case V4L2_TUNER_MODE_STEREO:
515 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); 604 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
516 break; 605 break;
@@ -522,9 +611,8 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
522 } 611 }
523 break; 612 break;
524 case MSP_MODE_FM_SAT: 613 case MSP_MODE_FM_SAT:
525 dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n", 614 msp3400_dbg("SAT setstereo: %s\n", strmode[mode]);
526 strmode[audmode]); 615 switch (mode) {
527 switch (audmode) {
528 case V4L2_TUNER_MODE_MONO: 616 case V4L2_TUNER_MODE_MONO:
529 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); 617 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
530 break; 618 break;
@@ -542,39 +630,35 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
542 case MSP_MODE_FM_NICAM1: 630 case MSP_MODE_FM_NICAM1:
543 case MSP_MODE_FM_NICAM2: 631 case MSP_MODE_FM_NICAM2:
544 case MSP_MODE_AM_NICAM: 632 case MSP_MODE_AM_NICAM:
545 dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n", 633 msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]);
546 strmode[audmode]);
547 msp3400c_setcarrier(client,msp->second,msp->main); 634 msp3400c_setcarrier(client,msp->second,msp->main);
548 if (msp->nicam_on) 635 if (msp->nicam_on)
549 nicam=0x0100; 636 nicam=0x0100;
550 break; 637 break;
551 case MSP_MODE_BTSC: 638 case MSP_MODE_BTSC:
552 dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n", 639 msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]);
553 strmode[audmode]);
554 nicam=0x0300; 640 nicam=0x0300;
555 break; 641 break;
556 case MSP_MODE_EXTERN: 642 case MSP_MODE_EXTERN:
557 dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n", 643 msp3400_dbg("extern setstereo: %s\n",strmode[mode]);
558 strmode[audmode]);
559 nicam = 0x0200; 644 nicam = 0x0200;
560 break; 645 break;
561 case MSP_MODE_FM_RADIO: 646 case MSP_MODE_FM_RADIO:
562 dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n", 647 msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]);
563 strmode[audmode]);
564 break; 648 break;
565 default: 649 default:
566 dprintk(KERN_DEBUG "msp3400: mono setstereo\n"); 650 msp3400_dbg("mono setstereo\n");
567 return; 651 return;
568 } 652 }
569 653
570 /* switch audio */ 654 /* switch audio */
571 switch (audmode) { 655 switch (best_video_sound(mode)) {
572 case V4L2_TUNER_MODE_STEREO: 656 case V4L2_TUNER_MODE_STEREO:
573 src = 0x0020 | nicam; 657 src = 0x0020 | nicam;
574 break; 658 break;
575 case V4L2_TUNER_MODE_MONO: 659 case V4L2_TUNER_MODE_MONO:
576 if (msp->mode == MSP_MODE_AM_NICAM) { 660 if (msp->mode == MSP_MODE_AM_NICAM) {
577 dprintk("msp3400: switching to AM mono\n"); 661 msp3400_dbg("switching to AM mono\n");
578 /* AM mono decoding is handled by tuner, not MSP chip */ 662 /* AM mono decoding is handled by tuner, not MSP chip */
579 /* SCART switching control register */ 663 /* SCART switching control register */
580 msp3400c_set_scart(client,SCART_MONO,0); 664 msp3400c_set_scart(client,SCART_MONO,0);
@@ -588,8 +672,7 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
588 src = 0x0010 | nicam; 672 src = 0x0010 | nicam;
589 break; 673 break;
590 } 674 }
591 dprintk(KERN_DEBUG 675 msp3400_dbg("setstereo final source/matrix = 0x%x\n", src);
592 "msp3400: setstereo final source/matrix = 0x%x\n", src);
593 676
594 if (dolby) { 677 if (dolby) {
595 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); 678 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
@@ -605,29 +688,55 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
605} 688}
606 689
607static void 690static void
608msp3400c_print_mode(struct msp3400c *msp) 691msp3400c_print_mode(struct i2c_client *client)
609{ 692{
693 struct msp3400c *msp = i2c_get_clientdata(client);
694
610 if (msp->main == msp->second) { 695 if (msp->main == msp->second) {
611 printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n", 696 msp3400_dbg("mono sound carrier: %d.%03d MHz\n",
612 msp->main/910000,(msp->main/910)%1000); 697 msp->main/910000,(msp->main/910)%1000);
613 } else { 698 } else {
614 printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n", 699 msp3400_dbg("main sound carrier: %d.%03d MHz\n",
615 msp->main/910000,(msp->main/910)%1000); 700 msp->main/910000,(msp->main/910)%1000);
616 } 701 }
617 if (msp->mode == MSP_MODE_FM_NICAM1 || 702 if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2)
618 msp->mode == MSP_MODE_FM_NICAM2) 703 msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n",
619 printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
620 msp->second/910000,(msp->second/910)%1000); 704 msp->second/910000,(msp->second/910)%1000);
621 if (msp->mode == MSP_MODE_AM_NICAM) 705 if (msp->mode == MSP_MODE_AM_NICAM)
622 printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n", 706 msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n",
623 msp->second/910000,(msp->second/910)%1000); 707 msp->second/910000,(msp->second/910)%1000);
624 if (msp->mode == MSP_MODE_FM_TERRA && 708 if (msp->mode == MSP_MODE_FM_TERRA &&
625 msp->main != msp->second) { 709 msp->main != msp->second) {
626 printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n", 710 msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n",
627 msp->second/910000,(msp->second/910)%1000); 711 msp->second/910000,(msp->second/910)%1000);
628 } 712 }
629} 713}
630 714
715#define MSP3400_MAX 4
716static struct i2c_client *msps[MSP3400_MAX];
717static void msp3400c_restore_dfp(struct i2c_client *client)
718{
719 struct msp3400c *msp = i2c_get_clientdata(client);
720 int i;
721
722 for (i = 0; i < DFP_COUNT; i++) {
723 if (-1 == msp->dfp_regs[i])
724 continue;
725 msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
726 }
727}
728
729/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
730static int msp3400c_write_dfp_with_default(struct i2c_client *client,
731 int addr, int default_value)
732{
733 struct msp3400c *msp = i2c_get_clientdata(client);
734 int value = default_value;
735 if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
736 value = msp->dfp_regs[addr];
737 return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
738}
739
631/* ----------------------------------------------------------------------- */ 740/* ----------------------------------------------------------------------- */
632 741
633struct REGISTER_DUMP { 742struct REGISTER_DUMP {
@@ -635,8 +744,15 @@ struct REGISTER_DUMP {
635 char *name; 744 char *name;
636}; 745};
637 746
638static int 747struct REGISTER_DUMP d1[] = {
639autodetect_stereo(struct i2c_client *client) 748 {0x007e, "autodetect"},
749 {0x0023, "C_AD_BITS "},
750 {0x0038, "ADD_BITS "},
751 {0x003e, "CIB_BITS "},
752 {0x0057, "ERROR_RATE"},
753};
754
755static int autodetect_stereo(struct i2c_client *client)
640{ 756{
641 struct msp3400c *msp = i2c_get_clientdata(client); 757 struct msp3400c *msp = i2c_get_clientdata(client);
642 int val; 758 int val;
@@ -649,8 +765,7 @@ autodetect_stereo(struct i2c_client *client)
649 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); 765 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
650 if (val > 32767) 766 if (val > 32767)
651 val -= 65536; 767 val -= 65536;
652 dprintk(KERN_DEBUG 768 msp3400_dbg("stereo detect register: %d\n",val);
653 "msp34xx: stereo detect register: %d\n",val);
654 if (val > 4096) { 769 if (val > 4096) {
655 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; 770 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
656 } else if (val < -4096) { 771 } else if (val < -4096) {
@@ -664,8 +779,7 @@ autodetect_stereo(struct i2c_client *client)
664 case MSP_MODE_FM_NICAM2: 779 case MSP_MODE_FM_NICAM2:
665 case MSP_MODE_AM_NICAM: 780 case MSP_MODE_AM_NICAM:
666 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); 781 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
667 dprintk(KERN_DEBUG 782 msp3400_dbg("nicam sync=%d, mode=%d\n",
668 "msp34xx: nicam sync=%d, mode=%d\n",
669 val & 1, (val & 0x1e) >> 1); 783 val & 1, (val & 0x1e) >> 1);
670 784
671 if (val & 1) { 785 if (val & 1) {
@@ -698,8 +812,7 @@ autodetect_stereo(struct i2c_client *client)
698 break; 812 break;
699 case MSP_MODE_BTSC: 813 case MSP_MODE_BTSC:
700 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); 814 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
701 dprintk(KERN_DEBUG 815 msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
702 "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
703 val, 816 val,
704 (val & 0x0002) ? "no" : "yes", 817 (val & 0x0002) ? "no" : "yes",
705 (val & 0x0004) ? "no" : "yes", 818 (val & 0x0004) ? "no" : "yes",
@@ -713,13 +826,13 @@ autodetect_stereo(struct i2c_client *client)
713 } 826 }
714 if (rxsubchans != msp->rxsubchans) { 827 if (rxsubchans != msp->rxsubchans) {
715 update = 1; 828 update = 1;
716 dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n", 829 msp3400_dbg("watch: rxsubchans %d => %d\n",
717 msp->rxsubchans,rxsubchans); 830 msp->rxsubchans,rxsubchans);
718 msp->rxsubchans = rxsubchans; 831 msp->rxsubchans = rxsubchans;
719 } 832 }
720 if (newnicam != msp->nicam_on) { 833 if (newnicam != msp->nicam_on) {
721 update = 1; 834 update = 1;
722 dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n", 835 msp3400_dbg("watch: nicam %d => %d\n",
723 msp->nicam_on,newnicam); 836 msp->nicam_on,newnicam);
724 msp->nicam_on = newnicam; 837 msp->nicam_on = newnicam;
725 } 838 }
@@ -756,8 +869,15 @@ static void watch_stereo(struct i2c_client *client)
756{ 869{
757 struct msp3400c *msp = i2c_get_clientdata(client); 870 struct msp3400c *msp = i2c_get_clientdata(client);
758 871
759 if (autodetect_stereo(client)) 872 if (autodetect_stereo(client)) {
760 msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans)); 873 if (msp->stereo & V4L2_TUNER_MODE_STEREO)
874 msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
875 else if (msp->stereo & VIDEO_SOUND_LANG1)
876 msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
877 else
878 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
879 }
880
761 if (once) 881 if (once)
762 msp->watch_stereo = 0; 882 msp->watch_stereo = 0;
763} 883}
@@ -769,14 +889,14 @@ static int msp3400c_thread(void *data)
769 struct CARRIER_DETECT *cd; 889 struct CARRIER_DETECT *cd;
770 int count, max1,max2,val1,val2, val,this; 890 int count, max1,max2,val1,val2, val,this;
771 891
772 printk("msp3400: kthread started\n"); 892 msp3400_info("msp3400 daemon started\n");
773 for (;;) { 893 for (;;) {
774 d2printk("msp3400: thread: sleep\n"); 894 msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
775 msp34xx_sleep(msp,-1); 895 msp34xx_sleep(msp,-1);
776 d2printk("msp3400: thread: wakeup\n"); 896 msp3400_dbg_mediumvol("msp3400 thread: wakeup\n");
777 897
778 restart: 898 restart:
779 dprintk("msp3410: thread: restart scan\n"); 899 msp3400_dbg("thread: restart scan\n");
780 msp->restart = 0; 900 msp->restart = 0;
781 if (kthread_should_stop()) 901 if (kthread_should_stop())
782 break; 902 break;
@@ -784,9 +904,8 @@ static int msp3400c_thread(void *data)
784 if (VIDEO_MODE_RADIO == msp->norm || 904 if (VIDEO_MODE_RADIO == msp->norm ||
785 MSP_MODE_EXTERN == msp->mode) { 905 MSP_MODE_EXTERN == msp->mode) {
786 /* no carrier scan, just unmute */ 906 /* no carrier scan, just unmute */
787 printk("msp3400: thread: no carrier scan\n"); 907 msp3400_info("thread: no carrier scan\n");
788 msp3400c_setvolume(client, msp->muted, 908 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
789 msp->volume, msp->balance);
790 continue; 909 continue;
791 } 910 }
792 911
@@ -802,13 +921,14 @@ static int msp3400c_thread(void *data)
802 goto restart; 921 goto restart;
803 922
804 /* carrier detect pass #1 -- main carrier */ 923 /* carrier detect pass #1 -- main carrier */
805 cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); 924 cd = carrier_detect_main;
925 count = CARRIER_COUNT(carrier_detect_main);
806 926
807 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 927 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
808 /* autodetect doesn't work well with AM ... */ 928 /* autodetect doesn't work well with AM ... */
809 max1 = 3; 929 max1 = 3;
810 count = 0; 930 count = 0;
811 dprintk("msp3400: AM sound override\n"); 931 msp3400_dbg("AM sound override\n");
812 } 932 }
813 933
814 for (this = 0; this < count; this++) { 934 for (this = 0; this < count; this++) {
@@ -820,7 +940,7 @@ static int msp3400c_thread(void *data)
820 val -= 65536; 940 val -= 65536;
821 if (val1 < val) 941 if (val1 < val)
822 val1 = val, max1 = this; 942 val1 = val, max1 = this;
823 dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name); 943 msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name);
824 } 944 }
825 945
826 /* carrier detect pass #2 -- second (stereo) carrier */ 946 /* carrier detect pass #2 -- second (stereo) carrier */
@@ -836,13 +956,16 @@ static int msp3400c_thread(void *data)
836 case 0: /* 4.5 */ 956 case 0: /* 4.5 */
837 case 2: /* 6.0 */ 957 case 2: /* 6.0 */
838 default: 958 default:
839 cd = NULL; count = 0; 959 cd = NULL;
960 count = 0;
840 break; 961 break;
841 } 962 }
842 963
843 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 964 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
844 /* autodetect doesn't work well with AM ... */ 965 /* autodetect doesn't work well with AM ... */
845 cd = NULL; count = 0; max2 = 0; 966 cd = NULL;
967 count = 0;
968 max2 = 0;
846 } 969 }
847 for (this = 0; this < count; this++) { 970 for (this = 0; this < count; this++) {
848 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); 971 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
@@ -853,7 +976,7 @@ static int msp3400c_thread(void *data)
853 val -= 65536; 976 val -= 65536;
854 if (val2 < val) 977 if (val2 < val)
855 val2 = val, max2 = this; 978 val2 = val, max2 = this;
856 dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name); 979 msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name);
857 } 980 }
858 981
859 /* programm the msp3400 according to the results */ 982 /* programm the msp3400 according to the results */
@@ -865,7 +988,7 @@ static int msp3400c_thread(void *data)
865 msp->second = carrier_detect_55[max2].cdo; 988 msp->second = carrier_detect_55[max2].cdo;
866 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 989 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
867 msp->nicam_on = 0; 990 msp->nicam_on = 0;
868 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 991 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
869 msp->watch_stereo = 1; 992 msp->watch_stereo = 1;
870 } else if (max2 == 1 && HAVE_NICAM(msp)) { 993 } else if (max2 == 1 && HAVE_NICAM(msp)) {
871 /* B/G NICAM */ 994 /* B/G NICAM */
@@ -892,7 +1015,7 @@ static int msp3400c_thread(void *data)
892 msp->second = carrier_detect_65[max2].cdo; 1015 msp->second = carrier_detect_65[max2].cdo;
893 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 1016 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
894 msp->nicam_on = 0; 1017 msp->nicam_on = 0;
895 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1018 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
896 msp->watch_stereo = 1; 1019 msp->watch_stereo = 1;
897 } else if (max2 == 0 && 1020 } else if (max2 == 0 &&
898 msp->norm == VIDEO_MODE_SECAM) { 1021 msp->norm == VIDEO_MODE_SECAM) {
@@ -900,7 +1023,7 @@ static int msp3400c_thread(void *data)
900 msp->second = carrier_detect_65[max2].cdo; 1023 msp->second = carrier_detect_65[max2].cdo;
901 msp3400c_setmode(client, MSP_MODE_AM_NICAM); 1024 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
902 msp->nicam_on = 0; 1025 msp->nicam_on = 0;
903 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1026 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
904 msp3400c_setcarrier(client, msp->second, msp->main); 1027 msp3400c_setcarrier(client, msp->second, msp->main);
905 /* volume prescale for SCART (AM mono input) */ 1028 /* volume prescale for SCART (AM mono input) */
906 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); 1029 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
@@ -924,15 +1047,16 @@ static int msp3400c_thread(void *data)
924 msp->nicam_on = 0; 1047 msp->nicam_on = 0;
925 msp3400c_setcarrier(client, msp->second, msp->main); 1048 msp3400c_setcarrier(client, msp->second, msp->main);
926 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1049 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
927 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1050 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
928 break; 1051 break;
929 } 1052 }
930 1053
931 /* unmute */ 1054 /* unmute */
932 msp3400c_setvolume(client, msp->muted, 1055 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
933 msp->volume, msp->balance); 1056 msp3400c_restore_dfp(client);
1057
934 if (debug) 1058 if (debug)
935 msp3400c_print_mode(msp); 1059 msp3400c_print_mode(client);
936 1060
937 /* monitor tv audio mode */ 1061 /* monitor tv audio mode */
938 while (msp->watch_stereo) { 1062 while (msp->watch_stereo) {
@@ -941,7 +1065,7 @@ static int msp3400c_thread(void *data)
941 watch_stereo(client); 1065 watch_stereo(client);
942 } 1066 }
943 } 1067 }
944 dprintk(KERN_DEBUG "msp3400: thread: exit\n"); 1068 msp3400_dbg("thread: exit\n");
945 return 0; 1069 return 0;
946} 1070}
947 1071
@@ -985,10 +1109,12 @@ static inline const char *msp34xx_standard_mode_name(int mode)
985 return "unknown"; 1109 return "unknown";
986} 1110}
987 1111
988static int msp34xx_modus(int norm) 1112static int msp34xx_modus(struct i2c_client *client, int norm)
989{ 1113{
990 switch (norm) { 1114 switch (norm) {
991 case VIDEO_MODE_PAL: 1115 case VIDEO_MODE_PAL:
1116 msp3400_dbg("video mode selected to PAL\n");
1117
992#if 1 1118#if 1
993 /* experimental: not sure this works with all chip versions */ 1119 /* experimental: not sure this works with all chip versions */
994 return 0x7003; 1120 return 0x7003;
@@ -997,12 +1123,16 @@ static int msp34xx_modus(int norm)
997 return 0x1003; 1123 return 0x1003;
998#endif 1124#endif
999 case VIDEO_MODE_NTSC: /* BTSC */ 1125 case VIDEO_MODE_NTSC: /* BTSC */
1126 msp3400_dbg("video mode selected to NTSC\n");
1000 return 0x2003; 1127 return 0x2003;
1001 case VIDEO_MODE_SECAM: 1128 case VIDEO_MODE_SECAM:
1129 msp3400_dbg("video mode selected to SECAM\n");
1002 return 0x0003; 1130 return 0x0003;
1003 case VIDEO_MODE_RADIO: 1131 case VIDEO_MODE_RADIO:
1132 msp3400_dbg("video mode selected to Radio\n");
1004 return 0x0003; 1133 return 0x0003;
1005 case VIDEO_MODE_AUTO: 1134 case VIDEO_MODE_AUTO:
1135 msp3400_dbg("video mode selected to Auto\n");
1006 return 0x2003; 1136 return 0x2003;
1007 default: 1137 default:
1008 return 0x0003; 1138 return 0x0003;
@@ -1031,23 +1161,22 @@ static int msp3410d_thread(void *data)
1031 struct msp3400c *msp = i2c_get_clientdata(client); 1161 struct msp3400c *msp = i2c_get_clientdata(client);
1032 int mode,val,i,std; 1162 int mode,val,i,std;
1033 1163
1034 printk("msp3410: daemon started\n"); 1164 msp3400_info("msp3410 daemon started\n");
1035 for (;;) { 1165 for (;;) {
1036 d2printk(KERN_DEBUG "msp3410: thread: sleep\n"); 1166 msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
1037 msp34xx_sleep(msp,-1); 1167 msp34xx_sleep(msp,-1);
1038 d2printk(KERN_DEBUG "msp3410: thread: wakeup\n"); 1168 msp3400_dbg_mediumvol("msp3410 thread: wakeup\n");
1039 1169
1040 restart: 1170 restart:
1041 dprintk("msp3410: thread: restart scan\n"); 1171 msp3400_dbg("thread: restart scan\n");
1042 msp->restart = 0; 1172 msp->restart = 0;
1043 if (kthread_should_stop()) 1173 if (kthread_should_stop())
1044 break; 1174 break;
1045 1175
1046 if (msp->mode == MSP_MODE_EXTERN) { 1176 if (msp->mode == MSP_MODE_EXTERN) {
1047 /* no carrier scan needed, just unmute */ 1177 /* no carrier scan needed, just unmute */
1048 dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n"); 1178 msp3400_dbg("thread: no carrier scan\n");
1049 msp3400c_setvolume(client, msp->muted, 1179 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1050 msp->volume, msp->balance);
1051 continue; 1180 continue;
1052 } 1181 }
1053 1182
@@ -1059,14 +1188,14 @@ static int msp3410d_thread(void *data)
1059 goto restart; 1188 goto restart;
1060 1189
1061 /* start autodetect */ 1190 /* start autodetect */
1062 mode = msp34xx_modus(msp->norm); 1191 mode = msp34xx_modus(client, msp->norm);
1063 std = msp34xx_standard(msp->norm); 1192 std = msp34xx_standard(msp->norm);
1064 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); 1193 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1065 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); 1194 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1066 msp->watch_stereo = 0; 1195 msp->watch_stereo = 0;
1067 1196
1068 if (debug) 1197 if (debug)
1069 printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n", 1198 msp3400_dbg("setting mode: %s (0x%04x)\n",
1070 msp34xx_standard_mode_name(std) ,std); 1199 msp34xx_standard_mode_name(std) ,std);
1071 1200
1072 if (std != 1) { 1201 if (std != 1) {
@@ -1082,13 +1211,13 @@ static int msp3410d_thread(void *data)
1082 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); 1211 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1083 if (val < 0x07ff) 1212 if (val < 0x07ff)
1084 break; 1213 break;
1085 dprintk(KERN_DEBUG "msp3410: detection still in progress\n"); 1214 msp3400_dbg("detection still in progress\n");
1086 } 1215 }
1087 } 1216 }
1088 for (i = 0; modelist[i].name != NULL; i++) 1217 for (i = 0; modelist[i].name != NULL; i++)
1089 if (modelist[i].retval == val) 1218 if (modelist[i].retval == val)
1090 break; 1219 break;
1091 dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n", 1220 msp3400_dbg("current mode: %s (0x%04x)\n",
1092 modelist[i].name ? modelist[i].name : "unknown", 1221 modelist[i].name ? modelist[i].name : "unknown",
1093 val); 1222 val);
1094 msp->main = modelist[i].main; 1223 msp->main = modelist[i].main;
@@ -1096,7 +1225,7 @@ static int msp3410d_thread(void *data)
1096 1225
1097 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { 1226 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1098 /* autodetection has failed, let backup */ 1227 /* autodetection has failed, let backup */
1099 dprintk(KERN_DEBUG "msp3410: autodetection failed," 1228 msp3400_dbg("autodetection failed,"
1100 " switching to backup mode: %s (0x%04x)\n", 1229 " switching to backup mode: %s (0x%04x)\n",
1101 modelist[8].name ? modelist[8].name : "unknown",val); 1230 modelist[8].name ? modelist[8].name : "unknown",val);
1102 val = 0x0009; 1231 val = 0x0009;
@@ -1120,13 +1249,13 @@ static int msp3410d_thread(void *data)
1120 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1249 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1121 msp->nicam_on = 1; 1250 msp->nicam_on = 1;
1122 msp->watch_stereo = 1; 1251 msp->watch_stereo = 1;
1123 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1252 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1124 break; 1253 break;
1125 case 0x0009: 1254 case 0x0009:
1126 msp->mode = MSP_MODE_AM_NICAM; 1255 msp->mode = MSP_MODE_AM_NICAM;
1127 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1256 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1128 msp->nicam_on = 1; 1257 msp->nicam_on = 1;
1129 msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO); 1258 msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
1130 msp->watch_stereo = 1; 1259 msp->watch_stereo = 1;
1131 break; 1260 break;
1132 case 0x0020: /* BTSC */ 1261 case 0x0020: /* BTSC */
@@ -1135,7 +1264,7 @@ static int msp3410d_thread(void *data)
1135 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1264 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1136 msp->nicam_on = 0; 1265 msp->nicam_on = 0;
1137 msp->watch_stereo = 1; 1266 msp->watch_stereo = 1;
1138 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1267 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1139 break; 1268 break;
1140 case 0x0040: /* FM radio */ 1269 case 0x0040: /* FM radio */
1141 msp->mode = MSP_MODE_FM_RADIO; 1270 msp->mode = MSP_MODE_FM_RADIO;
@@ -1169,9 +1298,10 @@ static int msp3410d_thread(void *data)
1169 /* unmute, restore misc registers */ 1298 /* unmute, restore misc registers */
1170 msp3400c_setbass(client, msp->bass); 1299 msp3400c_setbass(client, msp->bass);
1171 msp3400c_settreble(client, msp->treble); 1300 msp3400c_settreble(client, msp->treble);
1172 msp3400c_setvolume(client, msp->muted, 1301 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1173 msp->volume, msp->balance); 1302 msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
1174 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); 1303 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1304 msp3400c_restore_dfp(client);
1175 1305
1176 /* monitor tv audio mode */ 1306 /* monitor tv audio mode */
1177 while (msp->watch_stereo) { 1307 while (msp->watch_stereo) {
@@ -1180,7 +1310,7 @@ static int msp3410d_thread(void *data)
1180 watch_stereo(client); 1310 watch_stereo(client);
1181 } 1311 }
1182 } 1312 }
1183 dprintk(KERN_DEBUG "msp3410: thread: exit\n"); 1313 msp3400_dbg("thread: exit\n");
1184 return 0; 1314 return 0;
1185} 1315}
1186 1316
@@ -1195,7 +1325,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source);
1195/* (re-)initialize the msp34xxg, according to the current norm in msp->norm 1325/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
1196 * return 0 if it worked, -1 if it failed 1326 * return 0 if it worked, -1 if it failed
1197 */ 1327 */
1198static int msp34xxg_init(struct i2c_client *client) 1328static int msp34xxg_reset(struct i2c_client *client)
1199{ 1329{
1200 struct msp3400c *msp = i2c_get_clientdata(client); 1330 struct msp3400c *msp = i2c_get_clientdata(client);
1201 int modus,std; 1331 int modus,std;
@@ -1210,8 +1340,10 @@ static int msp34xxg_init(struct i2c_client *client)
1210 0x0f20 /* mute DSP input, mute SCART 1 */)) 1340 0x0f20 /* mute DSP input, mute SCART 1 */))
1211 return -1; 1341 return -1;
1212 1342
1343 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1344
1213 /* step-by-step initialisation, as described in the manual */ 1345 /* step-by-step initialisation, as described in the manual */
1214 modus = msp34xx_modus(msp->norm); 1346 modus = msp34xx_modus(client, msp->norm);
1215 std = msp34xx_standard(msp->norm); 1347 std = msp34xx_standard(msp->norm);
1216 modus &= ~0x03; /* STATUS_CHANGE=0 */ 1348 modus &= ~0x03; /* STATUS_CHANGE=0 */
1217 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ 1349 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
@@ -1222,7 +1354,7 @@ static int msp34xxg_init(struct i2c_client *client)
1222 return -1; 1354 return -1;
1223 if (msp3400c_write(client, 1355 if (msp3400c_write(client,
1224 I2C_MSP3400C_DEM, 1356 I2C_MSP3400C_DEM,
1225 0x20/*stanard*/, 1357 0x20/*standard*/,
1226 std)) 1358 std))
1227 return -1; 1359 return -1;
1228 1360
@@ -1230,21 +1362,18 @@ static int msp34xxg_init(struct i2c_client *client)
1230 standard/audio autodetection right now */ 1362 standard/audio autodetection right now */
1231 msp34xxg_set_source(client, msp->source); 1363 msp34xxg_set_source(client, msp->source);
1232 1364
1233 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1365 if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */
1234 0x0e, /* AM/FM Prescale */ 1366 0x3000
1235 0x3000 /* default: [15:8] 75khz deviation */)) 1367 /* default: [15:8] 75khz deviation */
1368 ))
1236 return -1; 1369 return -1;
1237 1370
1238 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1371 if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */
1239 0x10, /* NICAM Prescale */ 1372 0x5a00
1240 0x5a00 /* default: 9db gain (as recommended) */)) 1373 /* default: 9db gain (as recommended) */
1374 ))
1241 return -1; 1375 return -1;
1242 1376
1243 if (msp3400c_write(client,
1244 I2C_MSP3400C_DEM,
1245 0x20, /* STANDARD SELECT */
1246 standard /* default: 0x01 for automatic standard select*/))
1247 return -1;
1248 return 0; 1377 return 0;
1249} 1378}
1250 1379
@@ -1254,27 +1383,27 @@ static int msp34xxg_thread(void *data)
1254 struct msp3400c *msp = i2c_get_clientdata(client); 1383 struct msp3400c *msp = i2c_get_clientdata(client);
1255 int val, std, i; 1384 int val, std, i;
1256 1385
1257 printk("msp34xxg: daemon started\n"); 1386 msp3400_info("msp34xxg daemon started\n");
1258 msp->source = 1; /* default */ 1387 msp->source = 1; /* default */
1259 for (;;) { 1388 for (;;) {
1260 d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); 1389 msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
1261 msp34xx_sleep(msp,-1); 1390 msp34xx_sleep(msp,-1);
1262 d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n"); 1391 msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n");
1263 1392
1264 restart: 1393 restart:
1265 dprintk("msp34xxg: thread: restart scan\n"); 1394 msp3400_dbg("thread: restart scan\n");
1266 msp->restart = 0; 1395 msp->restart = 0;
1267 if (kthread_should_stop()) 1396 if (kthread_should_stop())
1268 break; 1397 break;
1269 1398
1270 /* setup the chip*/ 1399 /* setup the chip*/
1271 msp34xxg_init(client); 1400 msp34xxg_reset(client);
1272 std = standard; 1401 std = standard;
1273 if (std != 0x01) 1402 if (std != 0x01)
1274 goto unmute; 1403 goto unmute;
1275 1404
1276 /* watch autodetect */ 1405 /* watch autodetect */
1277 dprintk("msp34xxg: triggered autodetect, waiting for result\n"); 1406 msp3400_dbg("triggered autodetect, waiting for result\n");
1278 for (i = 0; i < 10; i++) { 1407 for (i = 0; i < 10; i++) {
1279 if (msp34xx_sleep(msp,100)) 1408 if (msp34xx_sleep(msp,100))
1280 goto restart; 1409 goto restart;
@@ -1285,23 +1414,23 @@ static int msp34xxg_thread(void *data)
1285 std = val; 1414 std = val;
1286 break; 1415 break;
1287 } 1416 }
1288 dprintk("msp34xxg: detection still in progress\n"); 1417 msp3400_dbg("detection still in progress\n");
1289 } 1418 }
1290 if (0x01 == std) { 1419 if (0x01 == std) {
1291 dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n"); 1420 msp3400_dbg("detection still in progress after 10 tries. giving up.\n");
1292 continue; 1421 continue;
1293 } 1422 }
1294 1423
1295 unmute: 1424 unmute:
1296 dprintk("msp34xxg: current mode: %s (0x%04x)\n", 1425 msp3400_dbg("current mode: %s (0x%04x)\n",
1297 msp34xx_standard_mode_name(std), std); 1426 msp34xx_standard_mode_name(std), std);
1298 1427
1299 /* unmute: dispatch sound to scart output, set scart volume */ 1428 /* unmute: dispatch sound to scart output, set scart volume */
1300 dprintk("msp34xxg: unmute\n"); 1429 msp3400_dbg("unmute\n");
1301 1430
1302 msp3400c_setbass(client, msp->bass); 1431 msp3400c_setbass(client, msp->bass);
1303 msp3400c_settreble(client, msp->treble); 1432 msp3400c_settreble(client, msp->treble);
1304 msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance); 1433 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1305 1434
1306 /* restore ACB */ 1435 /* restore ACB */
1307 if (msp3400c_write(client, 1436 if (msp3400c_write(client,
@@ -1309,8 +1438,10 @@ static int msp34xxg_thread(void *data)
1309 0x13, /* ACB */ 1438 0x13, /* ACB */
1310 msp->acb)) 1439 msp->acb))
1311 return -1; 1440 return -1;
1441
1442 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1312 } 1443 }
1313 dprintk(KERN_DEBUG "msp34xxg: thread: exit\n"); 1444 msp3400_dbg("thread: exit\n");
1314 return 0; 1445 return 0;
1315} 1446}
1316 1447
@@ -1329,7 +1460,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
1329 * for MONO (source==0) downmixing set bit[7:0] to 0x30 1460 * for MONO (source==0) downmixing set bit[7:0] to 0x30
1330 */ 1461 */
1331 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); 1462 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
1332 dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); 1463 msp3400_dbg("set source to %d (0x%x)\n", source, value);
1333 msp3400c_write(client, 1464 msp3400c_write(client,
1334 I2C_MSP3400C_DFP, 1465 I2C_MSP3400C_DFP,
1335 0x08, /* Loudspeaker Output */ 1466 0x08, /* Loudspeaker Output */
@@ -1380,7 +1511,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
1380 * this is a problem, I'll handle SAP just like lang1/lang2. 1511 * this is a problem, I'll handle SAP just like lang1/lang2.
1381 */ 1512 */
1382 } 1513 }
1383 dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", 1514 msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1384 status, is_stereo, is_bilingual, msp->rxsubchans); 1515 status, is_stereo, is_bilingual, msp->rxsubchans);
1385} 1516}
1386 1517
@@ -1427,7 +1558,7 @@ static void msp_wake_thread(struct i2c_client *client);
1427 1558
1428static struct i2c_driver driver = { 1559static struct i2c_driver driver = {
1429 .owner = THIS_MODULE, 1560 .owner = THIS_MODULE,
1430 .name = "i2c msp3400 driver", 1561 .name = "msp3400",
1431 .id = I2C_DRIVERID_MSP3400, 1562 .id = I2C_DRIVERID_MSP3400,
1432 .flags = I2C_DF_NOTIFY, 1563 .flags = I2C_DF_NOTIFY,
1433 .attach_adapter = msp_probe, 1564 .attach_adapter = msp_probe,
@@ -1449,57 +1580,64 @@ static struct i2c_client client_template =
1449static int msp_attach(struct i2c_adapter *adap, int addr, int kind) 1580static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1450{ 1581{
1451 struct msp3400c *msp; 1582 struct msp3400c *msp;
1452 struct i2c_client *c; 1583 struct i2c_client *client = &client_template;
1453 int (*thread_func)(void *data) = NULL; 1584 int (*thread_func)(void *data) = NULL;
1585 int i;
1454 1586
1455 client_template.adapter = adap; 1587 client_template.adapter = adap;
1456 client_template.addr = addr; 1588 client_template.addr = addr;
1457 1589
1458 if (-1 == msp3400c_reset(&client_template)) { 1590 if (-1 == msp3400c_reset(&client_template)) {
1459 dprintk("msp34xx: no chip found\n"); 1591 msp3400_dbg("no chip found\n");
1460 return -1; 1592 return -1;
1461 } 1593 }
1462 1594
1463 if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) 1595 if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1464 return -ENOMEM; 1596 return -ENOMEM;
1465 memcpy(c,&client_template,sizeof(struct i2c_client)); 1597 memcpy(client,&client_template,sizeof(struct i2c_client));
1466 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { 1598 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1467 kfree(c); 1599 kfree(client);
1468 return -ENOMEM; 1600 return -ENOMEM;
1469 } 1601 }
1470 1602
1471 memset(msp,0,sizeof(struct msp3400c)); 1603 memset(msp,0,sizeof(struct msp3400c));
1472 msp->volume = 58880; /* 0db gain */ 1604 msp->norm = VIDEO_MODE_NTSC;
1473 msp->balance = 32768; 1605 msp->left = 58880; /* 0db gain */
1474 msp->bass = 32768; 1606 msp->right = 58880; /* 0db gain */
1475 msp->treble = 32768; 1607 msp->bass = 32768;
1476 msp->input = -1; 1608 msp->treble = 32768;
1477 msp->muted = 1; 1609 msp->input = -1;
1478 1610 msp->muted = 0;
1479 i2c_set_clientdata(c, msp); 1611 msp->i2s_mode = 0;
1612 for (i = 0; i < DFP_COUNT; i++)
1613 msp->dfp_regs[i] = -1;
1614
1615 i2c_set_clientdata(client, msp);
1480 init_waitqueue_head(&msp->wq); 1616 init_waitqueue_head(&msp->wq);
1481 1617
1482 if (-1 == msp3400c_reset(c)) { 1618 if (-1 == msp3400c_reset(client)) {
1483 kfree(msp); 1619 kfree(msp);
1484 kfree(c); 1620 kfree(client);
1485 dprintk("msp34xx: no chip found\n"); 1621 msp3400_dbg("no chip found\n");
1486 return -1; 1622 return -1;
1487 } 1623 }
1488 1624
1489 msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e); 1625 msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e);
1490 if (-1 != msp->rev1) 1626 if (-1 != msp->rev1)
1491 msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); 1627 msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f);
1492 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { 1628 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1493 kfree(msp); 1629 kfree(msp);
1494 kfree(c); 1630 kfree(client);
1495 dprintk("msp34xx: error while reading chip version\n"); 1631 msp3400_dbg("error while reading chip version\n");
1496 return -1; 1632 return -1;
1497 } 1633 }
1634 msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
1498 1635
1499 msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance); 1636 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1500 1637
1501 snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d", 1638 snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
1502 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@', 1639 ((msp->rev1>>4)&0x0f) + '3',
1640 (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@',
1503 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); 1641 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
1504 1642
1505 msp->opmode = opmode; 1643 msp->opmode = opmode;
@@ -1513,7 +1651,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1513 } 1651 }
1514 1652
1515 /* hello world :-) */ 1653 /* hello world :-) */
1516 printk(KERN_INFO "msp34xx: init: chip=%s", c->name); 1654 msp3400_info("chip=%s", client->name);
1517 if (HAVE_NICAM(msp)) 1655 if (HAVE_NICAM(msp))
1518 printk(" +nicam"); 1656 printk(" +nicam");
1519 if (HAVE_SIMPLE(msp)) 1657 if (HAVE_SIMPLE(msp))
@@ -1542,29 +1680,49 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1542 1680
1543 /* startup control thread if needed */ 1681 /* startup control thread if needed */
1544 if (thread_func) { 1682 if (thread_func) {
1545 msp->kthread = kthread_run(thread_func, c, "msp34xx"); 1683 msp->kthread = kthread_run(thread_func, client, "msp34xx");
1684
1546 if (NULL == msp->kthread) 1685 if (NULL == msp->kthread)
1547 printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); 1686 msp3400_warn("kernel_thread() failed\n");
1548 msp_wake_thread(c); 1687 msp_wake_thread(client);
1549 } 1688 }
1550 1689
1551 /* done */ 1690 /* done */
1552 i2c_attach_client(c); 1691 i2c_attach_client(client);
1692
1693 /* update our own array */
1694 for (i = 0; i < MSP3400_MAX; i++) {
1695 if (NULL == msps[i]) {
1696 msps[i] = client;
1697 break;
1698 }
1699 }
1700
1553 return 0; 1701 return 0;
1554} 1702}
1555 1703
1556static int msp_detach(struct i2c_client *client) 1704static int msp_detach(struct i2c_client *client)
1557{ 1705{
1558 struct msp3400c *msp = i2c_get_clientdata(client); 1706 struct msp3400c *msp = i2c_get_clientdata(client);
1707 int i;
1559 1708
1560 /* shutdown control thread */ 1709 /* shutdown control thread */
1561 if (msp->kthread >= 0) { 1710 if (msp->kthread) {
1562 msp->restart = 1; 1711 msp->restart = 1;
1563 kthread_stop(msp->kthread); 1712 kthread_stop(msp->kthread);
1564 } 1713 }
1565 msp3400c_reset(client); 1714 msp3400c_reset(client);
1715
1716 /* update our own array */
1717 for (i = 0; i < MSP3400_MAX; i++) {
1718 if (client == msps[i]) {
1719 msps[i] = NULL;
1720 break;
1721 }
1722 }
1566 1723
1567 i2c_detach_client(client); 1724 i2c_detach_client(client);
1725
1568 kfree(msp); 1726 kfree(msp);
1569 kfree(client); 1727 kfree(client);
1570 return 0; 1728 return 0;
@@ -1640,7 +1798,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1640 case OPMODE_MANUAL: 1798 case OPMODE_MANUAL:
1641 case OPMODE_SIMPLE: 1799 case OPMODE_SIMPLE:
1642 msp->watch_stereo = 0; 1800 msp->watch_stereo = 0;
1643 msp3400c_set_audmode(client, audmode); 1801 msp3400c_setstereo(client, audmode);
1644 break; 1802 break;
1645 case OPMODE_SIMPLER: 1803 case OPMODE_SIMPLER:
1646 msp34xxg_set_audmode(client, audmode); 1804 msp34xxg_set_audmode(client, audmode);
@@ -1648,16 +1806,18 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1648 } 1806 }
1649} 1807}
1650 1808
1809
1651static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 1810static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1652{ 1811{
1653 struct msp3400c *msp = i2c_get_clientdata(client); 1812 struct msp3400c *msp = i2c_get_clientdata(client);
1654 __u16 *sarg = arg; 1813 __u16 *sarg = arg;
1655 int scart = 0; 1814 int scart = 0;
1656 1815
1657 switch (cmd) { 1816 switch (cmd) {
1658 1817
1659 case AUDC_SET_INPUT: 1818 case AUDC_SET_INPUT:
1660 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); 1819 msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg);
1820
1661 if (*sarg == msp->input) 1821 if (*sarg == msp->input)
1662 break; 1822 break;
1663 msp->input = *sarg; 1823 msp->input = *sarg;
@@ -1691,15 +1851,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1691 msp3400c_set_scart(client,scart,0); 1851 msp3400c_set_scart(client,scart,0);
1692 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); 1852 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
1693 if (msp->opmode != OPMODE_SIMPLER) 1853 if (msp->opmode != OPMODE_SIMPLER)
1694 msp3400c_set_audmode(client, msp->audmode); 1854 msp3400c_setstereo(client, msp->audmode);
1695 } 1855 }
1696 msp_wake_thread(client); 1856 msp_wake_thread(client);
1697 break; 1857 break;
1698 1858
1699 case AUDC_SET_RADIO: 1859 case AUDC_SET_RADIO:
1700 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n"); 1860 msp3400_dbg("AUDC_SET_RADIO\n");
1701 msp->norm = VIDEO_MODE_RADIO; 1861 msp->norm = VIDEO_MODE_RADIO;
1702 dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n"); 1862 msp3400_dbg("switching to radio mode\n");
1703 msp->watch_stereo = 0; 1863 msp->watch_stereo = 0;
1704 switch (msp->opmode) { 1864 switch (msp->opmode) {
1705 case OPMODE_MANUAL: 1865 case OPMODE_MANUAL:
@@ -1707,8 +1867,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1707 msp3400c_setmode(client,MSP_MODE_FM_RADIO); 1867 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1708 msp3400c_setcarrier(client, MSP_CARRIER(10.7), 1868 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1709 MSP_CARRIER(10.7)); 1869 MSP_CARRIER(10.7));
1710 msp3400c_setvolume(client, msp->muted, 1870 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1711 msp->volume, msp->balance);
1712 break; 1871 break;
1713 case OPMODE_SIMPLE: 1872 case OPMODE_SIMPLE:
1714 case OPMODE_SIMPLER: 1873 case OPMODE_SIMPLER:
@@ -1717,6 +1876,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1717 break; 1876 break;
1718 } 1877 }
1719 break; 1878 break;
1879 /* work-in-progress: hook to control the DFP registers */
1880 case MSP_SET_DFPREG:
1881 {
1882 struct msp_dfpreg *r = arg;
1883 int i;
1884
1885 if (r->reg < 0 || r->reg >= DFP_COUNT)
1886 return -EINVAL;
1887 for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
1888 if (r->reg == bl_dfp[i])
1889 return -EINVAL;
1890 msp->dfp_regs[r->reg] = r->value;
1891 msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
1892 return 0;
1893 }
1894 case MSP_GET_DFPREG:
1895 {
1896 struct msp_dfpreg *r = arg;
1897
1898 if (r->reg < 0 || r->reg >= DFP_COUNT)
1899 return -EINVAL;
1900 r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
1901 return 0;
1902 }
1720 1903
1721 /* --- v4l ioctls --- */ 1904 /* --- v4l ioctls --- */
1722 /* take care: bttv does userspace copying, we'll get a 1905 /* take care: bttv does userspace copying, we'll get a
@@ -1725,7 +1908,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1725 { 1908 {
1726 struct video_audio *va = arg; 1909 struct video_audio *va = arg;
1727 1910
1728 dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n"); 1911 msp3400_dbg("VIDIOCGAUDIO\n");
1729 va->flags |= VIDEO_AUDIO_VOLUME | 1912 va->flags |= VIDEO_AUDIO_VOLUME |
1730 VIDEO_AUDIO_BASS | 1913 VIDEO_AUDIO_BASS |
1731 VIDEO_AUDIO_TREBLE | 1914 VIDEO_AUDIO_TREBLE |
@@ -1733,8 +1916,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1733 if (msp->muted) 1916 if (msp->muted)
1734 va->flags |= VIDEO_AUDIO_MUTE; 1917 va->flags |= VIDEO_AUDIO_MUTE;
1735 1918
1736 va->volume = msp->volume; 1919 if (msp->muted)
1737 va->balance = (va->volume) ? msp->balance : 32768; 1920 va->flags |= VIDEO_AUDIO_MUTE;
1921 va->volume = MAX(msp->left, msp->right);
1922 va->balance = (32768 * MIN(msp->left, msp->right)) /
1923 (va->volume ? va->volume : 1);
1924 va->balance = (msp->left < msp->right) ?
1925 (65535 - va->balance) : va->balance;
1926 if (0 == va->volume)
1927 va->balance = 32768;
1738 va->bass = msp->bass; 1928 va->bass = msp->bass;
1739 va->treble = msp->treble; 1929 va->treble = msp->treble;
1740 1930
@@ -1746,27 +1936,43 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1746 { 1936 {
1747 struct video_audio *va = arg; 1937 struct video_audio *va = arg;
1748 1938
1749 dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); 1939 msp3400_dbg("VIDIOCSAUDIO\n");
1750 msp->muted = (va->flags & VIDEO_AUDIO_MUTE); 1940 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1751 msp->volume = va->volume; 1941 msp->left = (MIN(65536 - va->balance, 32768) *
1752 msp->balance = va->balance; 1942 va->volume) / 32768;
1943 msp->right = (MIN(va->balance, 32768) * va->volume) / 32768;
1753 msp->bass = va->bass; 1944 msp->bass = va->bass;
1754 msp->treble = va->treble; 1945 msp->treble = va->treble;
1755 1946 msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n",
1756 msp3400c_setvolume(client, msp->muted, 1947 va->volume);
1757 msp->volume, msp->balance); 1948 msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n",
1758 msp3400c_setbass(client,msp->bass); 1949 va->balance);
1759 msp3400c_settreble(client,msp->treble); 1950 msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n",
1951 va->flags);
1952 msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n",
1953 msp->left);
1954 msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n",
1955 msp->right);
1956 msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n",
1957 msp->bass);
1958 msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n",
1959 msp->treble);
1960 msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n",
1961 msp->mode);
1962 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1963 msp3400c_setbass(client, msp->bass);
1964 msp3400c_settreble(client, msp->treble);
1760 1965
1761 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) 1966 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
1762 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); 1967 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
1763 break; 1968 break;
1764 } 1969 }
1970
1765 case VIDIOCSCHAN: 1971 case VIDIOCSCHAN:
1766 { 1972 {
1767 struct video_channel *vc = arg; 1973 struct video_channel *vc = arg;
1768 1974
1769 dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm); 1975 msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm);
1770 msp->norm = vc->norm; 1976 msp->norm = vc->norm;
1771 msp_wake_thread(client); 1977 msp_wake_thread(client);
1772 break; 1978 break;
@@ -1776,12 +1982,135 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1776 case VIDIOC_S_FREQUENCY: 1982 case VIDIOC_S_FREQUENCY:
1777 { 1983 {
1778 /* new channel -- kick audio carrier scan */ 1984 /* new channel -- kick audio carrier scan */
1779 dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n"); 1985 msp3400_dbg("VIDIOCSFREQ\n");
1780 msp_wake_thread(client); 1986 msp_wake_thread(client);
1781 break; 1987 break;
1782 } 1988 }
1783 1989
1990 /* msp34xx specific */
1991 case MSP_SET_MATRIX:
1992 {
1993 struct msp_matrix *mspm = arg;
1994
1995 msp3400_dbg("MSP_SET_MATRIX\n");
1996 msp3400c_set_scart(client, mspm->input, mspm->output);
1997 break;
1998 }
1999
1784 /* --- v4l2 ioctls --- */ 2000 /* --- v4l2 ioctls --- */
2001 case VIDIOC_S_STD:
2002 {
2003 v4l2_std_id *id = arg;
2004
2005 /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
2006 if (*id & V4L2_STD_PAL) {
2007 msp->norm=VIDEO_MODE_PAL;
2008 } else if (*id & V4L2_STD_SECAM) {
2009 msp->norm=VIDEO_MODE_SECAM;
2010 } else {
2011 msp->norm=VIDEO_MODE_NTSC;
2012 }
2013
2014 msp_wake_thread(client);
2015 return 0;
2016 }
2017
2018 case VIDIOC_ENUMINPUT:
2019 {
2020 struct v4l2_input *i = arg;
2021
2022 if (i->index != 0)
2023 return -EINVAL;
2024
2025 i->type = V4L2_INPUT_TYPE_TUNER;
2026 switch (i->index) {
2027 case AUDIO_RADIO:
2028 strcpy(i->name,"Radio");
2029 break;
2030 case AUDIO_EXTERN_1:
2031 strcpy(i->name,"Extern 1");
2032 break;
2033 case AUDIO_EXTERN_2:
2034 strcpy(i->name,"Extern 2");
2035 break;
2036 case AUDIO_TUNER:
2037 strcpy(i->name,"Television");
2038 break;
2039 default:
2040 return -EINVAL;
2041 }
2042 return 0;
2043 }
2044
2045 case VIDIOC_G_AUDIO:
2046 {
2047 struct v4l2_audio *a = arg;
2048
2049 memset(a,0,sizeof(*a));
2050
2051 switch (a->index) {
2052 case AUDIO_RADIO:
2053 strcpy(a->name,"Radio");
2054 break;
2055 case AUDIO_EXTERN_1:
2056 strcpy(a->name,"Extern 1");
2057 break;
2058 case AUDIO_EXTERN_2:
2059 strcpy(a->name,"Extern 2");
2060 break;
2061 case AUDIO_TUNER:
2062 strcpy(a->name,"Television");
2063 break;
2064 default:
2065 return -EINVAL;
2066 }
2067
2068 msp_any_detect_stereo(client);
2069 if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
2070 a->capability=V4L2_AUDCAP_STEREO;
2071 }
2072
2073 break;
2074 }
2075 case VIDIOC_S_AUDIO:
2076 {
2077 struct v4l2_audio *sarg = arg;
2078
2079 switch (sarg->index) {
2080 case AUDIO_RADIO:
2081 /* Hauppauge uses IN2 for the radio */
2082 msp->mode = MSP_MODE_FM_RADIO;
2083 scart = SCART_IN2;
2084 break;
2085 case AUDIO_EXTERN_1:
2086 /* IN1 is often used for external input ... */
2087 msp->mode = MSP_MODE_EXTERN;
2088 scart = SCART_IN1;
2089 break;
2090 case AUDIO_EXTERN_2:
2091 /* ... sometimes it is IN2 through ;) */
2092 msp->mode = MSP_MODE_EXTERN;
2093 scart = SCART_IN2;
2094 break;
2095 case AUDIO_TUNER:
2096 msp->mode = -1;
2097 break;
2098 }
2099 if (scart) {
2100 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
2101 msp->audmode = V4L2_TUNER_MODE_STEREO;
2102 msp3400c_set_scart(client,scart,0);
2103 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
2104 }
2105 if (sarg->capability==V4L2_AUDCAP_STEREO) {
2106 msp->audmode = V4L2_TUNER_MODE_STEREO;
2107 } else {
2108 msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
2109 }
2110 msp_any_set_audmode(client, msp->audmode);
2111 msp_wake_thread(client);
2112 break;
2113 }
1785 case VIDIOC_G_TUNER: 2114 case VIDIOC_G_TUNER:
1786 { 2115 {
1787 struct v4l2_tuner *vt = arg; 2116 struct v4l2_tuner *vt = arg;
@@ -1804,13 +2133,46 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1804 break; 2133 break;
1805 } 2134 }
1806 2135
1807 /* msp34xx specific */ 2136 case VIDIOC_G_AUDOUT:
1808 case MSP_SET_MATRIX:
1809 { 2137 {
1810 struct msp_matrix *mspm = arg; 2138 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2139 int idx=a->index;
2140
2141 memset(a,0,sizeof(*a));
2142
2143 switch (idx) {
2144 case 0:
2145 strcpy(a->name,"Scart1 Out");
2146 break;
2147 case 1:
2148 strcpy(a->name,"Scart2 Out");
2149 break;
2150 case 2:
2151 strcpy(a->name,"I2S Out");
2152 break;
2153 default:
2154 return -EINVAL;
2155 }
2156 break;
2157
2158 }
2159 case VIDIOC_S_AUDOUT:
2160 {
2161 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2162
2163 if (a->index<0||a->index>2)
2164 return -EINVAL;
2165
2166 if (a->index==2) {
2167 if (a->mode == V4L2_AUDMODE_32BITS)
2168 msp->i2s_mode=1;
2169 else
2170 msp->i2s_mode=0;
2171 }
2172 msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n",
2173 a->index,msp->i2s_mode);
2174 msp3400c_set_scart(client,msp->in_scart,a->index+1);
1811 2175
1812 dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n");
1813 msp3400c_set_scart(client, mspm->input, mspm->output);
1814 break; 2176 break;
1815 } 2177 }
1816 2178
@@ -1823,19 +2185,19 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1823 2185
1824static int msp_suspend(struct device * dev, pm_message_t state) 2186static int msp_suspend(struct device * dev, pm_message_t state)
1825{ 2187{
1826 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2188 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1827 2189
1828 dprintk("msp34xx: suspend\n"); 2190 msp3400_dbg("msp34xx: suspend\n");
1829 msp3400c_reset(c); 2191 msp3400c_reset(client);
1830 return 0; 2192 return 0;
1831} 2193}
1832 2194
1833static int msp_resume(struct device * dev) 2195static int msp_resume(struct device * dev)
1834{ 2196{
1835 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2197 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1836 2198
1837 dprintk("msp34xx: resume\n"); 2199 msp3400_dbg("msp34xx: resume\n");
1838 msp_wake_thread(c); 2200 msp_wake_thread(client);
1839 return 0; 2201 return 0;
1840} 2202}
1841 2203
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 972aa5e0aeef..2180018f06de 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -76,17 +76,17 @@ static int mt2032_compute_freq(struct i2c_client *c,
76 unsigned int xogc) //all in Hz 76 unsigned int xogc) //all in Hz
77{ 77{
78 struct tuner *t = i2c_get_clientdata(c); 78 struct tuner *t = i2c_get_clientdata(c);
79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, 79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; 80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
81 81
82 fref= 5250 *1000; //5.25MHz 82 fref= 5250 *1000; //5.25MHz
83 desired_lo1=rfin+if1; 83 desired_lo1=rfin+if1;
84 84
85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); 85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
86 lo1n=lo1/8; 86 lo1n=lo1/8;
87 lo1a=lo1-(lo1n*8); 87 lo1a=lo1-(lo1n*8);
88 88
89 s=rfin/1000/1000+1090; 89 s=rfin/1000/1000+1090;
90 90
91 if(optimize_vco) { 91 if(optimize_vco) {
92 if(s>1890) sel=0; 92 if(s>1890) sel=0;
@@ -96,34 +96,34 @@ static int mt2032_compute_freq(struct i2c_client *c,
96 else sel=4; // >1090 96 else sel=4; // >1090
97 } 97 }
98 else { 98 else {
99 if(s>1790) sel=0; // <1958 99 if(s>1790) sel=0; // <1958
100 else if(s>1617) sel=1; 100 else if(s>1617) sel=1;
101 else if(s>1449) sel=2; 101 else if(s>1449) sel=2;
102 else if(s>1291) sel=3; 102 else if(s>1291) sel=3;
103 else sel=4; // >1090 103 else sel=4; // >1090
104 } 104 }
105 *ret_sel=sel; 105 *ret_sel=sel;
106 106
107 lo1freq=(lo1a+8*lo1n)*fref; 107 lo1freq=(lo1a+8*lo1n)*fref;
108 108
109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", 109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
110 rfin,lo1,lo1n,lo1a,sel,lo1freq); 110 rfin,lo1,lo1n,lo1a,sel,lo1freq);
111 111
112 desired_lo2=lo1freq-rfin-if2; 112 desired_lo2=lo1freq-rfin-if2;
113 lo2=(desired_lo2)/fref; 113 lo2=(desired_lo2)/fref;
114 lo2n=lo2/8; 114 lo2n=lo2/8;
115 lo2a=lo2-(lo2n*8); 115 lo2a=lo2-(lo2n*8);
116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith 116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; 117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
118 118
119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", 119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq); 120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
121 121
122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { 122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", 123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
124 lo1a, lo1n, lo2a,lo2n); 124 lo1a, lo1n, lo2a,lo2n);
125 return(-1); 125 return(-1);
126 } 126 }
127 127
128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to); 128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to);
129 // should recalculate lo1 (one step up/down) 129 // should recalculate lo1 (one step up/down)
@@ -135,10 +135,10 @@ static int mt2032_compute_freq(struct i2c_client *c,
135 buf[3]=0x0f; //reserved 135 buf[3]=0x0f; //reserved
136 buf[4]=0x1f; 136 buf[4]=0x1f;
137 buf[5]=(lo2n-1) | (lo2a<<5); 137 buf[5]=(lo2n-1) | (lo2a<<5);
138 if(rfin >400*1000*1000) 138 if(rfin >400*1000*1000)
139 buf[6]=0xe4; 139 buf[6]=0xe4;
140 else 140 else
141 buf[6]=0xf4; // set PKEN per rev 1.2 141 buf[6]=0xf4; // set PKEN per rev 1.2
142 buf[7]=8+xogc; 142 buf[7]=8+xogc;
143 buf[8]=0xc3; //reserved 143 buf[8]=0xc3; //reserved
144 buf[9]=0x4e; //reserved 144 buf[9]=0x4e; //reserved
@@ -168,7 +168,7 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); 168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
169 udelay(1000); 169 udelay(1000);
170 } 170 }
171 return lock; 171 return lock;
172} 172}
173 173
174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock) 174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
@@ -202,7 +202,7 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
202 202
203 buf[0]=0x0f; 203 buf[0]=0x0f;
204 buf[1]=sel; 204 buf[1]=sel;
205 i2c_master_send(c,buf,2); 205 i2c_master_send(c,buf,2);
206 lock=mt2032_check_lo_lock(c); 206 lock=mt2032_check_lo_lock(c);
207 return lock; 207 return lock;
208} 208}
@@ -219,23 +219,23 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", 219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
220 rfin,if1,if2,from,to); 220 rfin,if1,if2,from,to);
221 221
222 buf[0]=0; 222 buf[0]=0;
223 ret=i2c_master_send(c,buf,1); 223 ret=i2c_master_send(c,buf,1);
224 i2c_master_recv(c,buf,21); 224 i2c_master_recv(c,buf,21);
225 225
226 buf[0]=0; 226 buf[0]=0;
227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc); 227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
228 if (ret<0) 228 if (ret<0)
229 return; 229 return;
230 230
231 // send only the relevant registers per Rev. 1.2 231 // send only the relevant registers per Rev. 1.2
232 buf[0]=0; 232 buf[0]=0;
233 ret=i2c_master_send(c,buf,4); 233 ret=i2c_master_send(c,buf,4);
234 buf[5]=5; 234 buf[5]=5;
235 ret=i2c_master_send(c,buf+5,4); 235 ret=i2c_master_send(c,buf+5,4);
236 buf[11]=11; 236 buf[11]=11;
237 ret=i2c_master_send(c,buf+11,3); 237 ret=i2c_master_send(c,buf+11,3);
238 if(ret!=3) 238 if(ret!=3)
239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); 239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
240 240
241 // wait for PLLs to lock (per manual), retry LINT if not. 241 // wait for PLLs to lock (per manual), retry LINT if not.
@@ -253,7 +253,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
253 mdelay(10); 253 mdelay(10);
254 buf[1]=8+t->xogc; 254 buf[1]=8+t->xogc;
255 i2c_master_send(c,buf,2); 255 i2c_master_send(c,buf,2);
256 } 256 }
257 257
258 if (lock!=6) 258 if (lock!=6)
259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); 259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
@@ -284,7 +284,7 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
284 if2 = 38900*1000; 284 if2 = 38900*1000;
285 } 285 }
286 286
287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, 287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
288 1090*1000*1000, if2, from, to); 288 1090*1000*1000, if2, from, to);
289} 289}
290 290
@@ -294,7 +294,7 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
294 int if2 = t->radio_if2; 294 int if2 = t->radio_if2;
295 295
296 // per Manual for FM tuning: first if center freq. 1085 MHz 296 // per Manual for FM tuning: first if center freq. 1085 MHz
297 mt2032_set_if_freq(c, freq * 1000 / 16, 297 mt2032_set_if_freq(c, freq * 1000 / 16,
298 1085*1000*1000,if2,if2,if2); 298 1085*1000*1000,if2,if2,if2);
299} 299}
300 300
@@ -302,57 +302,57 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
302static int mt2032_init(struct i2c_client *c) 302static int mt2032_init(struct i2c_client *c)
303{ 303{
304 struct tuner *t = i2c_get_clientdata(c); 304 struct tuner *t = i2c_get_clientdata(c);
305 unsigned char buf[21]; 305 unsigned char buf[21];
306 int ret,xogc,xok=0; 306 int ret,xogc,xok=0;
307 307
308 // Initialize Registers per spec. 308 // Initialize Registers per spec.
309 buf[1]=2; // Index to register 2 309 buf[1]=2; // Index to register 2
310 buf[2]=0xff; 310 buf[2]=0xff;
311 buf[3]=0x0f; 311 buf[3]=0x0f;
312 buf[4]=0x1f; 312 buf[4]=0x1f;
313 ret=i2c_master_send(c,buf+1,4); 313 ret=i2c_master_send(c,buf+1,4);
314 314
315 buf[5]=6; // Index register 6 315 buf[5]=6; // Index register 6
316 buf[6]=0xe4; 316 buf[6]=0xe4;
317 buf[7]=0x8f; 317 buf[7]=0x8f;
318 buf[8]=0xc3; 318 buf[8]=0xc3;
319 buf[9]=0x4e; 319 buf[9]=0x4e;
320 buf[10]=0xec; 320 buf[10]=0xec;
321 ret=i2c_master_send(c,buf+5,6); 321 ret=i2c_master_send(c,buf+5,6);
322 322
323 buf[12]=13; // Index register 13 323 buf[12]=13; // Index register 13
324 buf[13]=0x32; 324 buf[13]=0x32;
325 ret=i2c_master_send(c,buf+12,2); 325 ret=i2c_master_send(c,buf+12,2);
326 326
327 // Adjust XOGC (register 7), wait for XOK 327 // Adjust XOGC (register 7), wait for XOK
328 xogc=7; 328 xogc=7;
329 do { 329 do {
330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
331 mdelay(10); 331 mdelay(10);
332 buf[0]=0x0e; 332 buf[0]=0x0e;
333 i2c_master_send(c,buf,1); 333 i2c_master_send(c,buf,1);
334 i2c_master_recv(c,buf,1); 334 i2c_master_recv(c,buf,1);
335 xok=buf[0]&0x01; 335 xok=buf[0]&0x01;
336 tuner_dbg("mt2032: xok = 0x%02x\n",xok); 336 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
337 if (xok == 1) break; 337 if (xok == 1) break;
338 338
339 xogc--; 339 xogc--;
340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
341 if (xogc == 3) { 341 if (xogc == 3) {
342 xogc=4; // min. 4 per spec 342 xogc=4; // min. 4 per spec
343 break; 343 break;
344 } 344 }
345 buf[0]=0x07; 345 buf[0]=0x07;
346 buf[1]=0x88 + xogc; 346 buf[1]=0x88 + xogc;
347 ret=i2c_master_send(c,buf,2); 347 ret=i2c_master_send(c,buf,2);
348 if (ret!=2) 348 if (ret!=2)
349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); 349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
350 } while (xok != 1 ); 350 } while (xok != 1 );
351 t->xogc=xogc; 351 t->xogc=xogc;
352 352
353 t->tv_freq = mt2032_set_tv_freq; 353 t->tv_freq = mt2032_set_tv_freq;
354 t->radio_freq = mt2032_set_radio_freq; 354 t->radio_freq = mt2032_set_radio_freq;
355 return(1); 355 return(1);
356} 356}
357 357
358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) 358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
@@ -426,7 +426,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
426 } 426 }
427 427
428 ret=i2c_master_send(c,buf,6); 428 ret=i2c_master_send(c,buf,6);
429 if (ret!=6) 429 if (ret!=6)
430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); 430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
431} 431}
432 432
@@ -437,11 +437,11 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
437 437
438 if (t->std & V4L2_STD_525_60) { 438 if (t->std & V4L2_STD_525_60) {
439 // NTSC 439 // NTSC
440 if2 = 45750*1000; 440 if2 = 45750*1000;
441 } else { 441 } else {
442 // PAL 442 // PAL
443 if2 = 38900*1000; 443 if2 = 38900*1000;
444 } 444 }
445 if (V4L2_TUNER_DIGITAL_TV == t->mode) { 445 if (V4L2_TUNER_DIGITAL_TV == t->mode) {
446 // DVB (pinnacle 300i) 446 // DVB (pinnacle 300i)
447 if2 = 36150*1000; 447 if2 = 36150*1000;
@@ -455,7 +455,7 @@ static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
455 struct tuner *t = i2c_get_clientdata(c); 455 struct tuner *t = i2c_get_clientdata(c);
456 int if2 = t->radio_if2; 456 int if2 = t->radio_if2;
457 457
458 mt2050_set_if_freq(c, freq*62500, if2); 458 mt2050_set_if_freq(c, freq * 1000 / 16, if2);
459 mt2050_set_antenna(c, radio_antenna); 459 mt2050_set_antenna(c, radio_antenna);
460} 460}
461 461
@@ -487,7 +487,7 @@ int microtune_init(struct i2c_client *c)
487{ 487{
488 struct tuner *t = i2c_get_clientdata(c); 488 struct tuner *t = i2c_get_clientdata(c);
489 char *name; 489 char *name;
490 unsigned char buf[21]; 490 unsigned char buf[21];
491 int company_code; 491 int company_code;
492 492
493 memset(buf,0,sizeof(buf)); 493 memset(buf,0,sizeof(buf));
@@ -496,17 +496,17 @@ int microtune_init(struct i2c_client *c)
496 t->standby = NULL; 496 t->standby = NULL;
497 name = "unknown"; 497 name = "unknown";
498 498
499 i2c_master_send(c,buf,1); 499 i2c_master_send(c,buf,1);
500 i2c_master_recv(c,buf,21); 500 i2c_master_recv(c,buf,21);
501 if (tuner_debug) { 501 if (tuner_debug) {
502 int i; 502 int i;
503 tuner_dbg("MT20xx hexdump:"); 503 tuner_dbg("MT20xx hexdump:");
504 for(i=0;i<21;i++) { 504 for(i=0;i<21;i++) {
505 printk(" %02x",buf[i]); 505 printk(" %02x",buf[i]);
506 if(((i+1)%8)==0) printk(" "); 506 if(((i+1)%8)==0) printk(" ");
507 } 507 }
508 printk("\n"); 508 printk("\n");
509 } 509 }
510 company_code = buf[0x11] << 8 | buf[0x12]; 510 company_code = buf[0x11] << 8 | buf[0x12];
511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", 511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
512 company_code,buf[0x13],buf[0x14]); 512 company_code,buf[0x13],buf[0x14]);
@@ -525,8 +525,8 @@ int microtune_init(struct i2c_client *c)
525 default: 525 default:
526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", 526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
527 name); 527 name);
528 return 0; 528 return 0;
529 } 529 }
530 530
531 strlcpy(c->name, name, sizeof(c->name)); 531 strlcpy(c->name, name, sizeof(c->name));
532 tuner_info("microtune %s found, OK\n",name); 532 tuner_info("microtune %s found, OK\n",name);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 72b70eb5da1d..dca3ddfd510f 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -31,7 +31,6 @@
31#include <linux/wait.h> 31#include <linux/wait.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33 33
34#include <media/id.h>
35 34
36#include "rds.h" 35#include "rds.h"
37 36
@@ -246,7 +245,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
246 s->wr_index = 0; 245 s->wr_index = 0;
247 246
248 if (s->wr_index == s->rd_index) { 247 if (s->wr_index == s->rd_index) {
249 s->rd_index++; 248 s->rd_index += 3;
250 if (s->rd_index >= s->buf_size) 249 if (s->rd_index >= s->buf_size)
251 s->rd_index = 0; 250 s->rd_index = 0;
252 } else 251 } else
@@ -328,7 +327,7 @@ static void saa6588_work(void *data)
328 struct saa6588 *s = (struct saa6588 *)data; 327 struct saa6588 *s = (struct saa6588 *)data;
329 328
330 saa6588_i2c_poll(s); 329 saa6588_i2c_poll(s);
331 mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */ 330 mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
332} 331}
333 332
334static int saa6588_configure(struct saa6588 *s) 333static int saa6588_configure(struct saa6588 *s)
@@ -434,9 +433,9 @@ static int saa6588_probe(struct i2c_adapter *adap)
434 return i2c_probe(adap, &addr_data, saa6588_attach); 433 return i2c_probe(adap, &addr_data, saa6588_attach);
435#else 434#else
436 switch (adap->id) { 435 switch (adap->id) {
437 case I2C_ALGO_BIT | I2C_HW_B_BT848: 436 case I2C_HW_B_BT848:
438 case I2C_ALGO_BIT | I2C_HW_B_RIVA: 437 case I2C_HW_B_RIVA:
439 case I2C_ALGO_SAA7134: 438 case I2C_HW_SAA7134:
440 return i2c_probe(adap, &addr_data, saa6588_attach); 439 return i2c_probe(adap, &addr_data, saa6588_attach);
441 break; 440 break;
442 } 441 }
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
new file mode 100644
index 000000000000..9aa8827de2c3
--- /dev/null
+++ b/drivers/media/video/saa711x.c
@@ -0,0 +1,593 @@
1/*
2 * saa711x - Philips SAA711x video decoder driver version 0.0.1
3 *
4 * To do: Now, it handles only saa7113/7114. Should be improved to
5 * handle all Philips saa711x devices.
6 *
7 * Based on saa7113 driver from Dave Perks <dperks@ibm.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/fs.h>
29#include <linux/kernel.h>
30#include <linux/major.h>
31#include <linux/slab.h>
32#include <linux/mm.h>
33#include <linux/pci.h>
34#include <linux/signal.h>
35#include <asm/io.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/sched.h>
39#include <asm/segment.h>
40#include <linux/types.h>
41#include <asm/uaccess.h>
42#include <linux/videodev.h>
43
44MODULE_DESCRIPTION("Philips SAA711x video decoder driver");
45MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden");
46MODULE_LICENSE("GPL");
47
48#include <linux/i2c.h>
49#include <linux/i2c-dev.h>
50
51#define I2C_NAME(s) (s)->name
52
53#include <linux/video_decoder.h>
54
55static int debug = 0;
56MODULE_PARM(debug, "i");
57MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)");
58
59
60#define dprintk(num, format, args...) \
61 do { \
62 if (debug >= num) \
63 printk(format , ##args); \
64 } while (0)
65
66/* ----------------------------------------------------------------------- */
67
68struct saa711x {
69 unsigned char reg[32];
70
71 int norm;
72 int input;
73 int enable;
74 int bright;
75 int contrast;
76 int hue;
77 int sat;
78};
79
80#define I2C_SAA7113 0x4A
81#define I2C_SAA7114 0x42
82
83/* ----------------------------------------------------------------------- */
84
85static inline int
86saa711x_write (struct i2c_client *client,
87 u8 reg,
88 u8 value)
89{
90 struct saa711x *decoder = i2c_get_clientdata(client);
91
92 decoder->reg[reg] = value;
93 return i2c_smbus_write_byte_data(client, reg, value);
94}
95
96static int
97saa711x_write_block (struct i2c_client *client,
98 const u8 *data,
99 unsigned int len)
100{
101 int ret = -1;
102 u8 reg;
103
104 /* the saa711x has an autoincrement function, use it if
105 * the adapter understands raw I2C */
106 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
107 /* do raw I2C, not smbus compatible */
108 struct saa711x *decoder = i2c_get_clientdata(client);
109 struct i2c_msg msg;
110 u8 block_data[32];
111
112 msg.addr = client->addr;
113 msg.flags = 0;
114 while (len >= 2) {
115 msg.buf = (char *) block_data;
116 msg.len = 0;
117 block_data[msg.len++] = reg = data[0];
118 do {
119 block_data[msg.len++] =
120 decoder->reg[reg++] = data[1];
121 len -= 2;
122 data += 2;
123 } while (len >= 2 && data[0] == reg &&
124 msg.len < 32);
125 if ((ret = i2c_transfer(client->adapter,
126 &msg, 1)) < 0)
127 break;
128 }
129 } else {
130 /* do some slow I2C emulation kind of thing */
131 while (len >= 2) {
132 reg = *data++;
133 if ((ret = saa711x_write(client, reg,
134 *data++)) < 0)
135 break;
136 len -= 2;
137 }
138 }
139
140 return ret;
141}
142
143static int
144saa711x_init_decoder (struct i2c_client *client,
145 struct video_decoder_init *init)
146{
147 return saa711x_write_block(client, init->data, init->len);
148}
149
150static inline int
151saa711x_read (struct i2c_client *client,
152 u8 reg)
153{
154 return i2c_smbus_read_byte_data(client, reg);
155}
156
157/* ----------------------------------------------------------------------- */
158
159static const unsigned char saa711x_i2c_init[] = {
160 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */
161 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
162 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
163 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
164 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
165 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
166 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
167 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
168 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
169 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
170 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
171 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
172 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
173 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
174 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
175 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
176 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
177 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
178 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
179 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
180 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
181 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
182 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
183 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
184};
185
186static int
187saa711x_command (struct i2c_client *client,
188 unsigned int cmd,
189 void *arg)
190{
191 struct saa711x *decoder = i2c_get_clientdata(client);
192
193 switch (cmd) {
194
195 case 0:
196 case DECODER_INIT:
197 {
198 struct video_decoder_init *init = arg;
199 if (NULL != init)
200 return saa711x_init_decoder(client, init);
201 else {
202 struct video_decoder_init vdi;
203 vdi.data = saa711x_i2c_init;
204 vdi.len = sizeof(saa711x_i2c_init);
205 return saa711x_init_decoder(client, &vdi);
206 }
207 }
208
209 case DECODER_DUMP:
210 {
211 int i;
212
213 for (i = 0; i < 32; i += 16) {
214 int j;
215
216 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
217 for (j = 0; j < 16; ++j) {
218 printk(" %02x",
219 saa711x_read(client, i + j));
220 }
221 printk("\n");
222 }
223 }
224 break;
225
226 case DECODER_GET_CAPABILITIES:
227 {
228 struct video_decoder_capability *cap = arg;
229
230 cap->flags = VIDEO_DECODER_PAL |
231 VIDEO_DECODER_NTSC |
232 VIDEO_DECODER_SECAM |
233 VIDEO_DECODER_AUTO |
234 VIDEO_DECODER_CCIR;
235 cap->inputs = 8;
236 cap->outputs = 1;
237 }
238 break;
239
240 case DECODER_GET_STATUS:
241 {
242 int *iarg = arg;
243 int status;
244 int res;
245
246 status = saa711x_read(client, 0x1f);
247 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
248 status);
249 res = 0;
250 if ((status & (1 << 6)) == 0) {
251 res |= DECODER_STATUS_GOOD;
252 }
253 switch (decoder->norm) {
254 case VIDEO_MODE_NTSC:
255 res |= DECODER_STATUS_NTSC;
256 break;
257 case VIDEO_MODE_PAL:
258 res |= DECODER_STATUS_PAL;
259 break;
260 case VIDEO_MODE_SECAM:
261 res |= DECODER_STATUS_SECAM;
262 break;
263 default:
264 case VIDEO_MODE_AUTO:
265 if ((status & (1 << 5)) != 0) {
266 res |= DECODER_STATUS_NTSC;
267 } else {
268 res |= DECODER_STATUS_PAL;
269 }
270 break;
271 }
272 if ((status & (1 << 0)) != 0) {
273 res |= DECODER_STATUS_COLOR;
274 }
275 *iarg = res;
276 }
277 break;
278
279 case DECODER_SET_GPIO:
280 {
281 int *iarg = arg;
282 if (0 != *iarg) {
283 saa711x_write(client, 0x11,
284 (decoder->reg[0x11] | 0x80));
285 } else {
286 saa711x_write(client, 0x11,
287 (decoder->reg[0x11] & 0x7f));
288 }
289 break;
290 }
291
292 case DECODER_SET_VBI_BYPASS:
293 {
294 int *iarg = arg;
295 if (0 != *iarg) {
296 saa711x_write(client, 0x13,
297 (decoder->reg[0x13] & 0xf0) | 0x0a);
298 } else {
299 saa711x_write(client, 0x13,
300 (decoder->reg[0x13] & 0xf0));
301 }
302 break;
303 }
304
305 case DECODER_SET_NORM:
306 {
307 int *iarg = arg;
308
309 switch (*iarg) {
310
311 case VIDEO_MODE_NTSC:
312 saa711x_write(client, 0x08,
313 (decoder->reg[0x08] & 0x3f) | 0x40);
314 saa711x_write(client, 0x0e,
315 (decoder->reg[0x0e] & 0x8f));
316 break;
317
318 case VIDEO_MODE_PAL:
319 saa711x_write(client, 0x08,
320 (decoder->reg[0x08] & 0x3f) | 0x00);
321 saa711x_write(client, 0x0e,
322 (decoder->reg[0x0e] & 0x8f));
323 break;
324
325 case VIDEO_MODE_SECAM:
326 saa711x_write(client, 0x08,
327 (decoder->reg[0x0e] & 0x3f) | 0x00);
328 saa711x_write(client, 0x0e,
329 (decoder->reg[0x0e] & 0x8f) | 0x50);
330 break;
331
332 case VIDEO_MODE_AUTO:
333 saa711x_write(client, 0x08,
334 (decoder->reg[0x08] & 0x3f) | 0x80);
335 saa711x_write(client, 0x0e,
336 (decoder->reg[0x0e] & 0x8f));
337 break;
338
339 default:
340 return -EINVAL;
341
342 }
343 decoder->norm = *iarg;
344 }
345 break;
346
347 case DECODER_SET_INPUT:
348 {
349 int *iarg = arg;
350 if (*iarg < 0 || *iarg > 9) {
351 return -EINVAL;
352 }
353 if (decoder->input != *iarg) {
354 decoder->input = *iarg;
355 /* select mode */
356 saa711x_write(client, 0x02,
357 (decoder->reg[0x02] & 0xf0) | decoder->input);
358 /* bypass chrominance trap for modes 4..7 */
359 saa711x_write(client, 0x09,
360 (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
361 }
362 }
363 break;
364
365 case DECODER_SET_OUTPUT:
366 {
367 int *iarg = arg;
368
369 /* not much choice of outputs */
370 if (*iarg != 0) {
371 return -EINVAL;
372 }
373 }
374 break;
375
376 case DECODER_ENABLE_OUTPUT:
377 {
378 int *iarg = arg;
379 int enable = (*iarg != 0);
380
381 if (decoder->enable != enable) {
382 decoder->enable = enable;
383
384 /* RJ: If output should be disabled (for
385 * playing videos), we also need a open PLL.
386 * The input is set to 0 (where no input
387 * source is connected), although this
388 * is not necessary.
389 *
390 * If output should be enabled, we have to
391 * reverse the above.
392 */
393
394 if (decoder->enable) {
395 saa711x_write(client, 0x02,
396 (decoder->
397 reg[0x02] & 0xf8) |
398 decoder->input);
399 saa711x_write(client, 0x08,
400 (decoder->reg[0x08] & 0xfb));
401 saa711x_write(client, 0x11,
402 (decoder->
403 reg[0x11] & 0xf3) | 0x0c);
404 } else {
405 saa711x_write(client, 0x02,
406 (decoder->reg[0x02] & 0xf8));
407 saa711x_write(client, 0x08,
408 (decoder->
409 reg[0x08] & 0xfb) | 0x04);
410 saa711x_write(client, 0x11,
411 (decoder->reg[0x11] & 0xf3));
412 }
413 }
414 }
415 break;
416
417 case DECODER_SET_PICTURE:
418 {
419 struct video_picture *pic = arg;
420
421 if (decoder->bright != pic->brightness) {
422 /* We want 0 to 255 we get 0-65535 */
423 decoder->bright = pic->brightness;
424 saa711x_write(client, 0x0a, decoder->bright >> 8);
425 }
426 if (decoder->contrast != pic->contrast) {
427 /* We want 0 to 127 we get 0-65535 */
428 decoder->contrast = pic->contrast;
429 saa711x_write(client, 0x0b,
430 decoder->contrast >> 9);
431 }
432 if (decoder->sat != pic->colour) {
433 /* We want 0 to 127 we get 0-65535 */
434 decoder->sat = pic->colour;
435 saa711x_write(client, 0x0c, decoder->sat >> 9);
436 }
437 if (decoder->hue != pic->hue) {
438 /* We want -128 to 127 we get 0-65535 */
439 decoder->hue = pic->hue;
440 saa711x_write(client, 0x0d,
441 (decoder->hue - 32768) >> 8);
442 }
443 }
444 break;
445
446 default:
447 return -EINVAL;
448 }
449
450 return 0;
451}
452
453/* ----------------------------------------------------------------------- */
454
455/*
456 * Generic i2c probe
457 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
458 */
459
460/* standard i2c insmod options */
461static unsigned short normal_i2c[] = {
462 I2C_SAA7113>>1, /* saa7113 */
463 I2C_SAA7114>>1, /* saa7114 */
464 I2C_CLIENT_END
465};
466
467I2C_CLIENT_INSMOD;
468
469
470static struct i2c_driver i2c_driver_saa711x;
471
472static int
473saa711x_detect_client (struct i2c_adapter *adapter,
474 int address,
475 int kind)
476{
477 int i;
478 struct i2c_client *client;
479 struct saa711x *decoder;
480 struct video_decoder_init vdi;
481
482 dprintk(1,
483 KERN_INFO
484 "saa711x.c: detecting saa711x client on address 0x%x\n",
485 address << 1);
486
487 /* Check if the adapter supports the needed features */
488 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
489 return 0;
490
491 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
492 if (client == 0)
493 return -ENOMEM;
494 memset(client, 0, sizeof(struct i2c_client));
495 client->addr = address;
496 client->adapter = adapter;
497 client->driver = &i2c_driver_saa711x;
498 client->flags = I2C_CLIENT_ALLOW_USE;
499 strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client)));
500 decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL);
501 if (decoder == NULL) {
502 kfree(client);
503 return -ENOMEM;
504 }
505 memset(decoder, 0, sizeof(struct saa711x));
506 decoder->norm = VIDEO_MODE_NTSC;
507 decoder->input = 0;
508 decoder->enable = 1;
509 decoder->bright = 32768;
510 decoder->contrast = 32768;
511 decoder->hue = 32768;
512 decoder->sat = 32768;
513 i2c_set_clientdata(client, decoder);
514
515 i = i2c_attach_client(client);
516 if (i) {
517 kfree(client);
518 kfree(decoder);
519 return i;
520 }
521
522 vdi.data = saa711x_i2c_init;
523 vdi.len = sizeof(saa711x_i2c_init);
524 i = saa711x_init_decoder(client, &vdi);
525 if (i < 0) {
526 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
527 I2C_NAME(client), i);
528 } else {
529 dprintk(1,
530 KERN_INFO
531 "%s_attach: chip version %x at address 0x%x\n",
532 I2C_NAME(client), saa711x_read(client, 0x00) >> 4,
533 client->addr << 1);
534 }
535
536 return 0;
537}
538
539static int
540saa711x_attach_adapter (struct i2c_adapter *adapter)
541{
542 dprintk(1,
543 KERN_INFO
544 "saa711x.c: starting probe for adapter %s (0x%x)\n",
545 I2C_NAME(adapter), adapter->id);
546 return i2c_probe(adapter, &addr_data, &saa711x_detect_client);
547}
548
549static int
550saa711x_detach_client (struct i2c_client *client)
551{
552 struct saa711x *decoder = i2c_get_clientdata(client);
553 int err;
554
555 err = i2c_detach_client(client);
556 if (err) {
557 return err;
558 }
559
560 kfree(decoder);
561 kfree(client);
562
563 return 0;
564}
565
566/* ----------------------------------------------------------------------- */
567
568static struct i2c_driver i2c_driver_saa711x = {
569 .owner = THIS_MODULE,
570 .name = "saa711x",
571
572 .id = I2C_DRIVERID_SAA711X,
573 .flags = I2C_DF_NOTIFY,
574
575 .attach_adapter = saa711x_attach_adapter,
576 .detach_client = saa711x_detach_client,
577 .command = saa711x_command,
578};
579
580static int __init
581saa711x_init (void)
582{
583 return i2c_add_driver(&i2c_driver_saa711x);
584}
585
586static void __exit
587saa711x_exit (void)
588{
589 i2c_del_driver(&i2c_driver_saa711x);
590}
591
592module_init(saa711x_init);
593module_exit(saa711x_exit);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
new file mode 100644
index 000000000000..624e8808a517
--- /dev/null
+++ b/drivers/media/video/saa7134/Kconfig
@@ -0,0 +1,68 @@
1config VIDEO_SAA7134
2 tristate "Philips SAA7134 support"
3 depends on VIDEO_DEV && PCI && I2C && SOUND
4 select VIDEO_BUF
5 select VIDEO_IR
6 select VIDEO_TUNER
7 select CRC32
8 ---help---
9 This is a video4linux driver for Philips SAA713x based
10 TV cards.
11
12 To compile this driver as a module, choose M here: the
13 module will be called saa7134.
14
15config VIDEO_SAA7134_DVB
16 tristate "DVB/ATSC Support for saa7134 based TV cards"
17 depends on VIDEO_SAA7134 && DVB_CORE
18 select VIDEO_BUF_DVB
19 ---help---
20 This adds support for DVB cards based on the
21 Philips saa7134 chip.
22
23 To compile this driver as a module, choose M here: the
24 module will be called saa7134-dvb.
25
26 You must also select one or more DVB demodulators.
27 If you are unsure which you need, choose all of them.
28
29config VIDEO_SAA7134_DVB_ALL_FRONTENDS
30 bool "Build all supported frontends for saa7134 based TV cards"
31 default y
32 depends on VIDEO_SAA7134_DVB
33 select DVB_MT352
34 select DVB_TDA1004X
35 select DVB_NXT200X
36 ---help---
37 This builds saa7134-dvb with all currently supported frontend
38 demodulators. If you wish to tweak your configuration, and
39 only include support for the hardware that you need, choose N here.
40
41 If you are unsure, choose Y.
42
43config VIDEO_SAA7134_DVB_MT352
44 tristate "Zarlink MT352 DVB-T Support"
45 default m
46 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
47 select DVB_MT352
48 ---help---
49 This adds DVB-T support for cards based on the
50 Philips saa7134 chip and the MT352 demodulator.
51
52config VIDEO_SAA7134_DVB_TDA1004X
53 tristate "Phillips TDA10045H/TDA10046H DVB-T Support"
54 default m
55 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
56 select DVB_TDA1004X
57 ---help---
58 This adds DVB-T support for cards based on the
59 Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
60
61config VIDEO_SAA7134_DVB_NXT200X
62 tristate "NXT2002/NXT2004 ATSC Support"
63 default m
64 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
65 select DVB_NXT200X
66 ---help---
67 This adds ATSC 8VSB and QAM64/256 support for cards based on the
68 Philips saa7134 chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index b778ffd94e65..e0b28f0533af 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -3,15 +3,22 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \ 3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
4 saa7134-vbi.o saa7134-video.o saa7134-input.o 4 saa7134-vbi.o saa7134-video.o saa7134-input.o
5 5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o 6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \
7 saa6752hs.o saa7134-alsa.o
7obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 8obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
8 9
9EXTRA_CFLAGS += -I$(src)/.. 10EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 12EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
13ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
14 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
15endif
12ifneq ($(CONFIG_DVB_MT352),n) 16ifneq ($(CONFIG_DVB_MT352),n)
13 EXTRA_CFLAGS += -DHAVE_MT352=1 17 EXTRA_CFLAGS += -DHAVE_MT352=1
14endif 18endif
15ifneq ($(CONFIG_DVB_TDA1004X),n) 19ifneq ($(CONFIG_DVB_TDA1004X),n)
16 EXTRA_CFLAGS += -DHAVE_TDA1004X=1 20 EXTRA_CFLAGS += -DHAVE_TDA1004X=1
17endif 21endif
22ifneq ($(CONFIG_DVB_NXT200X),n)
23 EXTRA_CFLAGS += -DHAVE_NXT200X=1
24endif
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 382911c6ef22..cdd1ed9c8065 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -13,7 +13,6 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/crc32.h> 14#include <linux/crc32.h>
15 15
16#include <media/id.h>
17 16
18#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 17#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
19#define MPEG_VIDEO_MAX_BITRATE_MAX 27000 18#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
@@ -57,6 +56,7 @@ struct saa6752hs_state {
57 struct i2c_client client; 56 struct i2c_client client;
58 struct v4l2_mpeg_compression params; 57 struct v4l2_mpeg_compression params;
59 enum saa6752hs_videoformat video_format; 58 enum saa6752hs_videoformat video_format;
59 v4l2_std_id standard;
60}; 60};
61 61
62enum saa6752hs_command { 62enum saa6752hs_command {
@@ -74,58 +74,58 @@ enum saa6752hs_command {
74/* ---------------------------------------------------------------------- */ 74/* ---------------------------------------------------------------------- */
75 75
76static u8 PAT[] = { 76static u8 PAT[] = {
77 0xc2, // i2c register 77 0xc2, /* i2c register */
78 0x00, // table number for encoder 78 0x00, /* table number for encoder */
79 79
80 0x47, // sync 80 0x47, /* sync */
81 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) 81 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */
82 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 82 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
83 83
84 0x00, // PSI pointer to start of table 84 0x00, /* PSI pointer to start of table */
85 85
86 0x00, // tid(0) 86 0x00, /* tid(0) */
87 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13) 87 0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */
88 88
89 0x00, 0x01, // transport_stream_id(1) 89 0x00, 0x01, /* transport_stream_id(1) */
90 90
91 0xc1, // version_number(0), current_next_indicator(1) 91 0xc1, /* version_number(0), current_next_indicator(1) */
92 92
93 0x00, 0x00, // section_number(0), last_section_number(0) 93 0x00, 0x00, /* section_number(0), last_section_number(0) */
94 94
95 0x00, 0x01, // program_number(1) 95 0x00, 0x01, /* program_number(1) */
96 96
97 0xe0, 0x00, // PMT PID 97 0xe0, 0x00, /* PMT PID */
98 98
99 0x00, 0x00, 0x00, 0x00 // CRC32 99 0x00, 0x00, 0x00, 0x00 /* CRC32 */
100}; 100};
101 101
102static u8 PMT[] = { 102static u8 PMT[] = {
103 0xc2, // i2c register 103 0xc2, /* i2c register */
104 0x01, // table number for encoder 104 0x01, /* table number for encoder */
105 105
106 0x47, // sync 106 0x47, /* sync */
107 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid 107 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */
108 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 108 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
109 109
110 0x00, // PSI pointer to start of table 110 0x00, /* PSI pointer to start of table */
111 111
112 0x02, // tid(2) 112 0x02, /* tid(2) */
113 0xb0, 0x17, // section_syntax_indicator(1), section_length(23) 113 0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */
114 114
115 0x00, 0x01, // program_number(1) 115 0x00, 0x01, /* program_number(1) */
116 116
117 0xc1, // version_number(0), current_next_indicator(1) 117 0xc1, /* version_number(0), current_next_indicator(1) */
118 118
119 0x00, 0x00, // section_number(0), last_section_number(0) 119 0x00, 0x00, /* section_number(0), last_section_number(0) */
120 120
121 0xe0, 0x00, // PCR_PID 121 0xe0, 0x00, /* PCR_PID */
122 122
123 0xf0, 0x00, // program_info_length(0) 123 0xf0, 0x00, /* program_info_length(0) */
124 124
125 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid 125 0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
126 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid 126 0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */
127 127
128 0x00, 0x00, 0x00, 0x00 // CRC32 128 0x00, 0x00, 0x00, 0x00 /* CRC32 */
129}; 129};
130 130
131static struct v4l2_mpeg_compression param_defaults = 131static struct v4l2_mpeg_compression param_defaults =
@@ -166,33 +166,33 @@ static int saa6752hs_chip_command(struct i2c_client* client,
166 unsigned long timeout; 166 unsigned long timeout;
167 int status = 0; 167 int status = 0;
168 168
169 // execute the command 169 /* execute the command */
170 switch(command) { 170 switch(command) {
171 case SAA6752HS_COMMAND_RESET: 171 case SAA6752HS_COMMAND_RESET:
172 buf[0] = 0x00; 172 buf[0] = 0x00;
173 break; 173 break;
174 174
175 case SAA6752HS_COMMAND_STOP: 175 case SAA6752HS_COMMAND_STOP:
176 buf[0] = 0x03; 176 buf[0] = 0x03;
177 break; 177 break;
178 178
179 case SAA6752HS_COMMAND_START: 179 case SAA6752HS_COMMAND_START:
180 buf[0] = 0x02; 180 buf[0] = 0x02;
181 break; 181 break;
182 182
183 case SAA6752HS_COMMAND_PAUSE: 183 case SAA6752HS_COMMAND_PAUSE:
184 buf[0] = 0x04; 184 buf[0] = 0x04;
185 break; 185 break;
186 186
187 case SAA6752HS_COMMAND_RECONFIGURE: 187 case SAA6752HS_COMMAND_RECONFIGURE:
188 buf[0] = 0x05; 188 buf[0] = 0x05;
189 break; 189 break;
190 190
191 case SAA6752HS_COMMAND_SLEEP: 191 case SAA6752HS_COMMAND_SLEEP:
192 buf[0] = 0x06; 192 buf[0] = 0x06;
193 break; 193 break;
194 194
195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE: 195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
196 buf[0] = 0x07; 196 buf[0] = 0x07;
197 break; 197 break;
198 198
@@ -200,13 +200,13 @@ static int saa6752hs_chip_command(struct i2c_client* client,
200 return -EINVAL; 200 return -EINVAL;
201 } 201 }
202 202
203 // set it and wait for it to be so 203 /* set it and wait for it to be so */
204 i2c_master_send(client, buf, 1); 204 i2c_master_send(client, buf, 1);
205 timeout = jiffies + HZ * 3; 205 timeout = jiffies + HZ * 3;
206 for (;;) { 206 for (;;) {
207 // get the current status 207 /* get the current status */
208 buf[0] = 0x10; 208 buf[0] = 0x10;
209 i2c_master_send(client, buf, 1); 209 i2c_master_send(client, buf, 1);
210 i2c_master_recv(client, buf, 1); 210 i2c_master_recv(client, buf, 1);
211 211
212 if (!(buf[0] & 0x20)) 212 if (!(buf[0] & 0x20))
@@ -216,61 +216,58 @@ static int saa6752hs_chip_command(struct i2c_client* client,
216 break; 216 break;
217 } 217 }
218 218
219 // wait a bit
220 msleep(10); 219 msleep(10);
221 } 220 }
222 221
223 // delay a bit to let encoder settle 222 /* delay a bit to let encoder settle */
224 msleep(50); 223 msleep(50);
225 224
226 // done 225 return status;
227 return status;
228} 226}
229 227
230 228
231static int saa6752hs_set_bitrate(struct i2c_client* client, 229static int saa6752hs_set_bitrate(struct i2c_client* client,
232 struct v4l2_mpeg_compression* params) 230 struct v4l2_mpeg_compression* params)
233{ 231{
234 u8 buf[3]; 232 u8 buf[3];
235 233
236 // set the bitrate mode 234 /* set the bitrate mode */
237 buf[0] = 0x71; 235 buf[0] = 0x71;
238 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; 236 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
239 i2c_master_send(client, buf, 2); 237 i2c_master_send(client, buf, 2);
240 238
241 // set the video bitrate 239 /* set the video bitrate */
242 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { 240 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
243 // set the target bitrate 241 /* set the target bitrate */
244 buf[0] = 0x80; 242 buf[0] = 0x80;
245 buf[1] = params->vi_bitrate.target >> 8; 243 buf[1] = params->vi_bitrate.target >> 8;
246 buf[2] = params->vi_bitrate.target & 0xff; 244 buf[2] = params->vi_bitrate.target & 0xff;
247 i2c_master_send(client, buf, 3); 245 i2c_master_send(client, buf, 3);
248 246
249 // set the max bitrate 247 /* set the max bitrate */
250 buf[0] = 0x81; 248 buf[0] = 0x81;
251 buf[1] = params->vi_bitrate.max >> 8; 249 buf[1] = params->vi_bitrate.max >> 8;
252 buf[2] = params->vi_bitrate.max & 0xff; 250 buf[2] = params->vi_bitrate.max & 0xff;
253 i2c_master_send(client, buf, 3); 251 i2c_master_send(client, buf, 3);
254 } else { 252 } else {
255 // set the target bitrate (no max bitrate for CBR) 253 /* set the target bitrate (no max bitrate for CBR) */
256 buf[0] = 0x81; 254 buf[0] = 0x81;
257 buf[1] = params->vi_bitrate.target >> 8; 255 buf[1] = params->vi_bitrate.target >> 8;
258 buf[2] = params->vi_bitrate.target & 0xff; 256 buf[2] = params->vi_bitrate.target & 0xff;
259 i2c_master_send(client, buf, 3); 257 i2c_master_send(client, buf, 3);
260 } 258 }
261 259
262 // set the audio bitrate 260 /* set the audio bitrate */
263 buf[0] = 0x94; 261 buf[0] = 0x94;
264 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; 262 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
265 i2c_master_send(client, buf, 2); 263 i2c_master_send(client, buf, 2);
266 264
267 // set the total bitrate 265 /* set the total bitrate */
268 buf[0] = 0xb1; 266 buf[0] = 0xb1;
269 buf[1] = params->st_bitrate.target >> 8; 267 buf[1] = params->st_bitrate.target >> 8;
270 buf[2] = params->st_bitrate.target & 0xff; 268 buf[2] = params->st_bitrate.target & 0xff;
271 i2c_master_send(client, buf, 3); 269 i2c_master_send(client, buf, 3);
272 270
273 // return success
274 return 0; 271 return 0;
275} 272}
276 273
@@ -376,36 +373,43 @@ static int saa6752hs_init(struct i2c_client* client)
376 373
377 h = i2c_get_clientdata(client); 374 h = i2c_get_clientdata(client);
378 375
379 // Set video format - must be done first as it resets other settings 376 /* Set video format - must be done first as it resets other settings */
380 buf[0] = 0x41; 377 buf[0] = 0x41;
381 buf[1] = h->video_format; 378 buf[1] = h->video_format;
382 i2c_master_send(client, buf, 2); 379 i2c_master_send(client, buf, 2);
383 380
384 // set bitrate 381 /* Set number of lines in input signal */
385 saa6752hs_set_bitrate(client, &h->params); 382 buf[0] = 0x40;
383 buf[1] = 0x00;
384 if (h->standard & V4L2_STD_525_60)
385 buf[1] = 0x01;
386 i2c_master_send(client, buf, 2);
387
388 /* set bitrate */
389 saa6752hs_set_bitrate(client, &h->params);
386 390
387 // Set GOP structure {3, 13} 391 /* Set GOP structure {3, 13} */
388 buf[0] = 0x72; 392 buf[0] = 0x72;
389 buf[1] = 0x03; 393 buf[1] = 0x03;
390 buf[2] = 0x0D; 394 buf[2] = 0x0D;
391 i2c_master_send(client,buf,3); 395 i2c_master_send(client,buf,3);
392 396
393 // Set minimum Q-scale {4} 397 /* Set minimum Q-scale {4} */
394 buf[0] = 0x82; 398 buf[0] = 0x82;
395 buf[1] = 0x04; 399 buf[1] = 0x04;
396 i2c_master_send(client,buf,2); 400 i2c_master_send(client,buf,2);
397 401
398 // Set maximum Q-scale {12} 402 /* Set maximum Q-scale {12} */
399 buf[0] = 0x83; 403 buf[0] = 0x83;
400 buf[1] = 0x0C; 404 buf[1] = 0x0C;
401 i2c_master_send(client,buf,2); 405 i2c_master_send(client,buf,2);
402 406
403 // Set Output Protocol 407 /* Set Output Protocol */
404 buf[0] = 0xD0; 408 buf[0] = 0xD0;
405 buf[1] = 0x81; 409 buf[1] = 0x81;
406 i2c_master_send(client,buf,2); 410 i2c_master_send(client,buf,2);
407 411
408 // Set video output stream format {TS} 412 /* Set video output stream format {TS} */
409 buf[0] = 0xB0; 413 buf[0] = 0xB0;
410 buf[1] = 0x05; 414 buf[1] = 0x05;
411 i2c_master_send(client,buf,2); 415 i2c_master_send(client,buf,2);
@@ -421,9 +425,9 @@ static int saa6752hs_init(struct i2c_client* client)
421 localPAT[sizeof(PAT) - 1] = crc & 0xFF; 425 localPAT[sizeof(PAT) - 1] = crc & 0xFF;
422 426
423 /* compute PMT */ 427 /* compute PMT */
424 memcpy(localPMT, PMT, sizeof(PMT)); 428 memcpy(localPMT, PMT, sizeof(PMT));
425 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); 429 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
426 localPMT[4] = h->params.ts_pid_pmt & 0xff; 430 localPMT[4] = h->params.ts_pid_pmt & 0xff;
427 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); 431 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
428 localPMT[16] = h->params.ts_pid_pcr & 0xFF; 432 localPMT[16] = h->params.ts_pid_pcr & 0xFF;
429 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F); 433 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
@@ -436,39 +440,39 @@ static int saa6752hs_init(struct i2c_client* client)
436 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; 440 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
437 localPMT[sizeof(PMT) - 1] = crc & 0xFF; 441 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
438 442
439 // Set Audio PID 443 /* Set Audio PID */
440 buf[0] = 0xC1; 444 buf[0] = 0xC1;
441 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; 445 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
442 buf[2] = h->params.ts_pid_audio & 0xFF; 446 buf[2] = h->params.ts_pid_audio & 0xFF;
443 i2c_master_send(client,buf,3); 447 i2c_master_send(client,buf,3);
444 448
445 // Set Video PID 449 /* Set Video PID */
446 buf[0] = 0xC0; 450 buf[0] = 0xC0;
447 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; 451 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
448 buf[2] = h->params.ts_pid_video & 0xFF; 452 buf[2] = h->params.ts_pid_video & 0xFF;
449 i2c_master_send(client,buf,3); 453 i2c_master_send(client,buf,3);
450 454
451 // Set PCR PID 455 /* Set PCR PID */
452 buf[0] = 0xC4; 456 buf[0] = 0xC4;
453 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; 457 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
454 buf[2] = h->params.ts_pid_pcr & 0xFF; 458 buf[2] = h->params.ts_pid_pcr & 0xFF;
455 i2c_master_send(client,buf,3); 459 i2c_master_send(client,buf,3);
456 460
457 // Send SI tables 461 /* Send SI tables */
458 i2c_master_send(client,localPAT,sizeof(PAT)); 462 i2c_master_send(client,localPAT,sizeof(PAT));
459 i2c_master_send(client,localPMT,sizeof(PMT)); 463 i2c_master_send(client,localPMT,sizeof(PMT));
460 464
461 // mute then unmute audio. This removes buzzing artefacts 465 /* mute then unmute audio. This removes buzzing artefacts */
462 buf[0] = 0xa4; 466 buf[0] = 0xa4;
463 buf[1] = 1; 467 buf[1] = 1;
464 i2c_master_send(client, buf, 2); 468 i2c_master_send(client, buf, 2);
465 buf[1] = 0; 469 buf[1] = 0;
466 i2c_master_send(client, buf, 2); 470 i2c_master_send(client, buf, 2);
467 471
468 // start it going 472 /* start it going */
469 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); 473 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
470 474
471 // readout current state 475 /* readout current state */
472 buf[0] = 0xE1; 476 buf[0] = 0xE1;
473 buf[1] = 0xA7; 477 buf[1] = 0xA7;
474 buf[2] = 0xFE; 478 buf[2] = 0xFE;
@@ -477,7 +481,7 @@ static int saa6752hs_init(struct i2c_client* client)
477 i2c_master_send(client, buf, 5); 481 i2c_master_send(client, buf, 5);
478 i2c_master_recv(client, buf2, 4); 482 i2c_master_recv(client, buf2, 4);
479 483
480 // change aspect ratio 484 /* change aspect ratio */
481 buf[0] = 0xE0; 485 buf[0] = 0xE0;
482 buf[1] = 0xA7; 486 buf[1] = 0xA7;
483 buf[2] = 0xFE; 487 buf[2] = 0xFE;
@@ -498,7 +502,6 @@ static int saa6752hs_init(struct i2c_client* client)
498 buf[8] = buf2[3]; 502 buf[8] = buf2[3];
499 i2c_master_send(client, buf, 9); 503 i2c_master_send(client, buf, 9);
500 504
501 // return success
502 return 0; 505 return 0;
503} 506}
504 507
@@ -506,16 +509,19 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
506{ 509{
507 struct saa6752hs_state *h; 510 struct saa6752hs_state *h;
508 511
509 printk("saa6752hs: chip found @ 0x%x\n", addr<<1); 512 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
510 513
511 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) 514 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
512 return -ENOMEM; 515 return -ENOMEM;
513 memset(h,0,sizeof(*h)); 516 memset(h,0,sizeof(*h));
514 h->client = client_template; 517 h->client = client_template;
515 h->params = param_defaults; 518 h->params = param_defaults;
516 h->client.adapter = adap; 519 h->client.adapter = adap;
517 h->client.addr = addr; 520 h->client.addr = addr;
518 521
522 /* Assume 625 input lines */
523 h->standard = 0;
524
519 i2c_set_clientdata(&h->client, h); 525 i2c_set_clientdata(&h->client, h);
520 i2c_attach_client(&h->client); 526 i2c_attach_client(&h->client);
521 return 0; 527 return 0;
@@ -545,7 +551,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
545 struct v4l2_mpeg_compression *params = arg; 551 struct v4l2_mpeg_compression *params = arg;
546 int err = 0; 552 int err = 0;
547 553
548 switch (cmd) { 554 switch (cmd) {
549 case VIDIOC_S_MPEGCOMP: 555 case VIDIOC_S_MPEGCOMP:
550 if (NULL == params) { 556 if (NULL == params) {
551 /* apply settings and start encoder */ 557 /* apply settings and start encoder */
@@ -559,7 +565,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
559 break; 565 break;
560 case VIDIOC_G_FMT: 566 case VIDIOC_G_FMT:
561 { 567 {
562 struct v4l2_format *f = arg; 568 struct v4l2_format *f = arg;
563 569
564 if (h->video_format == SAA6752HS_VF_UNKNOWN) 570 if (h->video_format == SAA6752HS_VF_UNKNOWN)
565 h->video_format = SAA6752HS_VF_D1; 571 h->video_format = SAA6752HS_VF_D1;
@@ -576,6 +582,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
576 saa6752hs_set_subsampling(client, f); 582 saa6752hs_set_subsampling(client, f);
577 break; 583 break;
578 } 584 }
585 case VIDIOC_S_STD:
586 h->standard = *((v4l2_std_id *) arg);
587 break;
579 default: 588 default:
580 /* nothing */ 589 /* nothing */
581 break; 590 break;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
new file mode 100644
index 000000000000..4f3c42354329
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -0,0 +1,1047 @@
1/*
2 * SAA713x ALSA support for V4L
3 *
4 *
5 * Caveats:
6 * - Volume doesn't work (it's always at max)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <sound/driver.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/time.h>
27#include <linux/wait.h>
28#include <linux/moduleparam.h>
29#include <linux/module.h>
30#include <sound/core.h>
31#include <sound/control.h>
32#include <sound/pcm.h>
33#include <sound/initval.h>
34
35#include "saa7134.h"
36#include "saa7134-reg.h"
37
38static unsigned int debug = 0;
39module_param(debug, int, 0644);
40MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
41
42/*
43 * Configuration macros
44 */
45
46/* defaults */
47#define MIXER_ADDR_TVTUNER 0
48#define MIXER_ADDR_LINE1 1
49#define MIXER_ADDR_LINE2 2
50#define MIXER_ADDR_LAST 2
51
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
53static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
54static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
55
56module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
58
59#define dprintk(fmt, arg...) if (debug) \
60 printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
61
62/*
63 * Main chip structure
64 */
65typedef struct snd_card_saa7134 {
66 snd_card_t *card;
67 spinlock_t mixer_lock;
68 int mixer_volume[MIXER_ADDR_LAST+1][2];
69 int capture_source[MIXER_ADDR_LAST+1][2];
70 struct pci_dev *pci;
71 struct saa7134_dev *saadev;
72
73 unsigned long iobase;
74 int irq;
75
76 spinlock_t lock;
77} snd_card_saa7134_t;
78
79
80
81/*
82 * PCM structure
83 */
84
85typedef struct snd_card_saa7134_pcm {
86 struct saa7134_dev *saadev;
87
88 spinlock_t lock;
89 unsigned int pcm_size; /* buffer size */
90 unsigned int pcm_count; /* bytes per period */
91 unsigned int pcm_bps; /* bytes per second */
92 snd_pcm_substream_t *substream;
93} snd_card_saa7134_pcm_t;
94
95static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
96
97
98/*
99 * saa7134 DMA audio stop
100 *
101 * Called when the capture device is released or the buffer overflows
102 *
103 * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
104 * if we just share dsp_dma_stop and use it here
105 *
106 */
107
108static void saa7134_dma_stop(struct saa7134_dev *dev)
109
110{
111 dev->dmasound.dma_blk = -1;
112 dev->dmasound.dma_running = 0;
113 saa7134_set_dmabits(dev);
114}
115
116/*
117 * saa7134 DMA audio start
118 *
119 * Called when preparing the capture device for use
120 *
121 * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
122 * if we just share dsp_dma_start and use it here
123 *
124 */
125
126static void saa7134_dma_start(struct saa7134_dev *dev)
127{
128 dev->dmasound.dma_blk = 0;
129 dev->dmasound.dma_running = 1;
130 saa7134_set_dmabits(dev);
131}
132
133/*
134 * saa7134 audio DMA IRQ handler
135 *
136 * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
137 * Handles shifting between the 2 buffers, manages the read counters,
138 * and notifies ALSA when periods elapse
139 *
140 * - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
141 *
142 */
143
144void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
145{
146 int next_blk, reg = 0;
147
148 spin_lock(&dev->slock);
149 if (UNSET == dev->dmasound.dma_blk) {
150 dprintk("irq: recording stopped\n");
151 goto done;
152 }
153 if (0 != (status & 0x0f000000))
154 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
155 if (0 == (status & 0x10000000)) {
156 /* odd */
157 if (0 == (dev->dmasound.dma_blk & 0x01))
158 reg = SAA7134_RS_BA1(6);
159 } else {
160 /* even */
161 if (1 == (dev->dmasound.dma_blk & 0x01))
162 reg = SAA7134_RS_BA2(6);
163 }
164 if (0 == reg) {
165 dprintk("irq: field oops [%s]\n",
166 (status & 0x10000000) ? "even" : "odd");
167 goto done;
168 }
169
170 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
171 dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
172 dev->dmasound.bufsize, dev->dmasound.blocks);
173 snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
174 saa7134_dma_stop(dev);
175 goto done;
176 }
177
178 /* next block addr */
179 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
180 saa_writel(reg,next_blk * dev->dmasound.blksize);
181 if (debug > 2)
182 dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
183 (status & 0x10000000) ? "even" : "odd ", next_blk,
184 next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count);
185
186 /* update status & wake waiting readers */
187 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
188 dev->dmasound.read_count += dev->dmasound.blksize;
189
190 dev->dmasound.recording_on = reg;
191
192 if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
193 spin_unlock(&dev->slock);
194 snd_pcm_period_elapsed(dev->dmasound.substream);
195 spin_lock(&dev->slock);
196 }
197 done:
198 spin_unlock(&dev->slock);
199
200}
201
202/*
203 * IRQ request handler
204 *
205 * Runs along with saa7134's IRQ handler, discards anything that isn't
206 * DMA sound
207 *
208 */
209
210static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
211{
212 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
213 unsigned long report, status;
214 int loop, handled = 0;
215
216 for (loop = 0; loop < 10; loop++) {
217 report = saa_readl(SAA7134_IRQ_REPORT);
218 status = saa_readl(SAA7134_IRQ_STATUS);
219
220 if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
221 handled = 1;
222 saa_writel(SAA7134_IRQ_REPORT,report);
223 saa7134_irq_alsa_done(dev, status);
224 } else {
225 goto out;
226 }
227 }
228
229 if (loop == 10) {
230 dprintk("error! looping IRQ!");
231 }
232
233out:
234 return IRQ_RETVAL(handled);
235}
236
237/*
238 * ALSA capture trigger
239 *
240 * - One of the ALSA capture callbacks.
241 *
242 * Called whenever a capture is started or stopped. Must be defined,
243 * but there's nothing we want to do here
244 *
245 */
246
247static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
248 int cmd)
249{
250 snd_pcm_runtime_t *runtime = substream->runtime;
251 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
252 struct saa7134_dev *dev=saapcm->saadev;
253 int err = 0;
254
255 spin_lock_irq(&dev->slock);
256 if (cmd == SNDRV_PCM_TRIGGER_START) {
257 /* start dma */
258 saa7134_dma_start(dev);
259 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
260 /* stop dma */
261 saa7134_dma_stop(dev);
262 } else {
263 err = -EINVAL;
264 }
265 spin_unlock_irq(&dev->slock);
266
267 return err;
268}
269
270/*
271 * DMA buffer config
272 *
273 * Sets the values that will later be used as the size of the buffer,
274 * size of the fragments, and total number of fragments.
275 * Must be called during the preparation stage, before memory is
276 * allocated
277 *
278 * - Copied verbatim from saa7134-oss. Can be dropped
279 * if we just share dsp_buffer_conf from OSS.
280 */
281
282static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
283{
284 if (blksize < 0x100)
285 blksize = 0x100;
286 if (blksize > 0x10000)
287 blksize = 0x10000;
288
289 if (blocks < 2)
290 blocks = 2;
291 if ((blksize * blocks) > 1024*1024)
292 blocks = 1024*1024 / blksize;
293
294 dev->dmasound.blocks = blocks;
295 dev->dmasound.blksize = blksize;
296 dev->dmasound.bufsize = blksize * blocks;
297
298 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
299 blocks,blksize,blksize * blocks / 1024);
300 return 0;
301}
302
303/*
304 * DMA buffer initialization
305 *
306 * Uses V4L functions to initialize the DMA. Shouldn't be necessary in
307 * ALSA, but I was unable to use ALSA's own DMA, and had to force the
308 * usage of V4L's
309 *
310 * - Copied verbatim from saa7134-oss. Can be dropped
311 * if we just share dsp_buffer_init from OSS.
312 */
313
314static int dsp_buffer_init(struct saa7134_dev *dev)
315{
316 int err;
317
318 if (!dev->dmasound.bufsize)
319 BUG();
320 videobuf_dma_init(&dev->dmasound.dma);
321 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
322 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
323 if (0 != err)
324 return err;
325 return 0;
326}
327
328/*
329 * ALSA PCM preparation
330 *
331 * - One of the ALSA capture callbacks.
332 *
333 * Called right after the capture device is opened, this function configures
334 * the buffer using the previously defined functions, allocates the memory,
335 * sets up the hardware registers, and then starts the DMA. When this function
336 * returns, the audio should be flowing.
337 *
338 */
339
340static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
341{
342 snd_pcm_runtime_t *runtime = substream->runtime;
343 int err, bswap, sign;
344 u32 fmt, control;
345 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
346 struct saa7134_dev *dev;
347 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
348 unsigned int bps;
349 unsigned long size;
350 unsigned count;
351
352 size = snd_pcm_lib_buffer_bytes(substream);
353 count = snd_pcm_lib_period_bytes(substream);
354
355 saapcm->saadev->dmasound.substream = substream;
356 bps = runtime->rate * runtime->channels;
357 bps *= snd_pcm_format_width(runtime->format);
358 bps /= 8;
359 if (bps <= 0)
360 return -EINVAL;
361 saapcm->pcm_bps = bps;
362 saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
363 saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
364
365
366 dev=saa7134->saadev;
367
368 dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
369
370 err = dsp_buffer_init(dev);
371 if (0 != err)
372 goto fail2;
373
374 /* prepare buffer */
375 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
376 return err;
377 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
378 goto fail1;
379 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
380 dev->dmasound.dma.sglist,
381 dev->dmasound.dma.sglen,
382 0)))
383 goto fail2;
384
385
386
387 switch (runtime->format) {
388 case SNDRV_PCM_FORMAT_U8:
389 case SNDRV_PCM_FORMAT_S8:
390 fmt = 0x00;
391 break;
392 case SNDRV_PCM_FORMAT_U16_LE:
393 case SNDRV_PCM_FORMAT_U16_BE:
394 case SNDRV_PCM_FORMAT_S16_LE:
395 case SNDRV_PCM_FORMAT_S16_BE:
396 fmt = 0x01;
397 break;
398 default:
399 err = -EINVAL;
400 return 1;
401 }
402
403 switch (runtime->format) {
404 case SNDRV_PCM_FORMAT_S8:
405 case SNDRV_PCM_FORMAT_S16_LE:
406 case SNDRV_PCM_FORMAT_S16_BE:
407 sign = 1;
408 break;
409 default:
410 sign = 0;
411 break;
412 }
413
414 switch (runtime->format) {
415 case SNDRV_PCM_FORMAT_U16_BE:
416 case SNDRV_PCM_FORMAT_S16_BE:
417 bswap = 1; break;
418 default:
419 bswap = 0; break;
420 }
421
422 switch (dev->pci->device) {
423 case PCI_DEVICE_ID_PHILIPS_SAA7134:
424 if (1 == runtime->channels)
425 fmt |= (1 << 3);
426 if (2 == runtime->channels)
427 fmt |= (3 << 3);
428 if (sign)
429 fmt |= 0x04;
430
431 fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
432 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
433 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
434 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
435 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
436
437 break;
438 case PCI_DEVICE_ID_PHILIPS_SAA7133:
439 case PCI_DEVICE_ID_PHILIPS_SAA7135:
440 if (1 == runtime->channels)
441 fmt |= (1 << 4);
442 if (2 == runtime->channels)
443 fmt |= (2 << 4);
444 if (!sign)
445 fmt |= 0x04;
446 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
447 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
448 //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
449 break;
450 }
451
452 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
453 runtime->format, runtime->channels, fmt,
454 bswap ? 'b' : '-');
455 /* dma: setup channel 6 (= AUDIO) */
456 control = SAA7134_RS_CONTROL_BURST_16 |
457 SAA7134_RS_CONTROL_ME |
458 (dev->dmasound.pt.dma >> 12);
459 if (bswap)
460 control |= SAA7134_RS_CONTROL_BSWAP;
461
462 /* I should be able to use runtime->dma_addr in the control
463 byte, but it doesn't work. So I allocate the DMA using the
464 V4L functions, and force ALSA to use that as the DMA area */
465
466 runtime->dma_area = dev->dmasound.dma.vmalloc;
467
468 saa_writel(SAA7134_RS_BA1(6),0);
469 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
470 saa_writel(SAA7134_RS_PITCH(6),0);
471 saa_writel(SAA7134_RS_CONTROL(6),control);
472
473 dev->dmasound.rate = runtime->rate;
474
475 return 0;
476 fail2:
477 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
478 fail1:
479 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
480 return err;
481
482
483}
484
485/*
486 * ALSA pointer fetching
487 *
488 * - One of the ALSA capture callbacks.
489 *
490 * Called whenever a period elapses, it must return the current hardware
491 * position of the buffer.
492 * Also resets the read counter used to prevent overruns
493 *
494 */
495
496static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
497{
498 snd_pcm_runtime_t *runtime = substream->runtime;
499 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
500 struct saa7134_dev *dev=saapcm->saadev;
501
502
503
504 if (dev->dmasound.read_count) {
505 dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
506 dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
507 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
508 dev->dmasound.read_offset = 0;
509 }
510
511 return bytes_to_frames(runtime, dev->dmasound.read_offset);
512}
513
514/*
515 * ALSA hardware capabilities definition
516 */
517
518static snd_pcm_hardware_t snd_card_saa7134_capture =
519{
520 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
521 SNDRV_PCM_INFO_BLOCK_TRANSFER |
522 SNDRV_PCM_INFO_MMAP_VALID),
523 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
524 SNDRV_PCM_FMTBIT_S16_BE | \
525 SNDRV_PCM_FMTBIT_S8 | \
526 SNDRV_PCM_FMTBIT_U8 | \
527 SNDRV_PCM_FMTBIT_U16_LE | \
528 SNDRV_PCM_FMTBIT_U16_BE,
529 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
530 .rate_min = 32000,
531 .rate_max = 48000,
532 .channels_min = 1,
533 .channels_max = 2,
534 .buffer_bytes_max = (256*1024),
535 .period_bytes_min = 64,
536 .period_bytes_max = (256*1024),
537 .periods_min = 2,
538 .periods_max = 1024,
539};
540
541static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
542{
543 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
544
545 kfree(saapcm);
546}
547
548
549/*
550 * ALSA hardware params
551 *
552 * - One of the ALSA capture callbacks.
553 *
554 * Called on initialization, right before the PCM preparation
555 * Usually used in ALSA to allocate the DMA, but since we don't use the
556 * ALSA DMA it does nothing
557 *
558 */
559
560static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
561 snd_pcm_hw_params_t * hw_params)
562{
563
564 return 0;
565
566
567}
568
569/*
570 * ALSA hardware release
571 *
572 * - One of the ALSA capture callbacks.
573 *
574 * Called after closing the device, but before snd_card_saa7134_capture_close
575 * Usually used in ALSA to free the DMA, but since we don't use the
576 * ALSA DMA I'm almost sure this isn't necessary.
577 *
578 */
579
580static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
581{
582 return 0;
583}
584
585/*
586 * DMA buffer release
587 *
588 * Called after closing the device, during snd_card_saa7134_capture_close
589 *
590 */
591
592static int dsp_buffer_free(struct saa7134_dev *dev)
593{
594 if (!dev->dmasound.blksize)
595 BUG();
596
597 videobuf_dma_free(&dev->dmasound.dma);
598
599 dev->dmasound.blocks = 0;
600 dev->dmasound.blksize = 0;
601 dev->dmasound.bufsize = 0;
602
603 return 0;
604}
605
606/*
607 * ALSA capture finish
608 *
609 * - One of the ALSA capture callbacks.
610 *
611 * Called after closing the device. It stops the DMA audio and releases
612 * the buffers
613 *
614 */
615
616static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
617{
618 snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
619 struct saa7134_dev *dev = chip->saadev;
620
621 /* unlock buffer */
622 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
623 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
624
625 dsp_buffer_free(dev);
626 return 0;
627}
628
629/*
630 * ALSA capture start
631 *
632 * - One of the ALSA capture callbacks.
633 *
634 * Called when opening the device. It creates and populates the PCM
635 * structure
636 *
637 */
638
639static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
640{
641 snd_pcm_runtime_t *runtime = substream->runtime;
642 snd_card_saa7134_pcm_t *saapcm;
643 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
644 struct saa7134_dev *dev = saa7134->saadev;
645 int err;
646
647 down(&dev->dmasound.lock);
648
649 dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8;
650 dev->dmasound.channels = 2;
651 dev->dmasound.read_count = 0;
652 dev->dmasound.read_offset = 0;
653
654 up(&dev->dmasound.lock);
655
656 saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
657 if (saapcm == NULL)
658 return -ENOMEM;
659 saapcm->saadev=saa7134->saadev;
660
661 spin_lock_init(&saapcm->lock);
662
663 saapcm->substream = substream;
664 runtime->private_data = saapcm;
665 runtime->private_free = snd_card_saa7134_runtime_free;
666 runtime->hw = snd_card_saa7134_capture;
667
668 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
669 return err;
670
671 return 0;
672}
673
674/*
675 * ALSA capture callbacks definition
676 */
677
678static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
679 .open = snd_card_saa7134_capture_open,
680 .close = snd_card_saa7134_capture_close,
681 .ioctl = snd_pcm_lib_ioctl,
682 .hw_params = snd_card_saa7134_hw_params,
683 .hw_free = snd_card_saa7134_hw_free,
684 .prepare = snd_card_saa7134_capture_prepare,
685 .trigger = snd_card_saa7134_capture_trigger,
686 .pointer = snd_card_saa7134_capture_pointer,
687};
688
689/*
690 * ALSA PCM setup
691 *
692 * Called when initializing the board. Sets up the name and hooks up
693 * the callbacks
694 *
695 */
696
697static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
698{
699 snd_pcm_t *pcm;
700 int err;
701
702 if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
703 return err;
704 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
705 pcm->private_data = saa7134;
706 pcm->info_flags = 0;
707 strcpy(pcm->name, "SAA7134 PCM");
708 return 0;
709}
710
711#define SAA713x_VOLUME(xname, xindex, addr) \
712{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
713 .info = snd_saa7134_volume_info, \
714 .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
715 .private_value = addr }
716
717static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
718{
719 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
720 uinfo->count = 2;
721 uinfo->value.integer.min = 0;
722 uinfo->value.integer.max = 20;
723 return 0;
724}
725
726static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
727{
728 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
729 int addr = kcontrol->private_value;
730
731 ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
732 ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
733 return 0;
734}
735
736static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
737{
738 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
739 unsigned long flags;
740 int change, addr = kcontrol->private_value;
741 int left, right;
742
743 left = ucontrol->value.integer.value[0];
744 if (left < 0)
745 left = 0;
746 if (left > 20)
747 left = 20;
748 right = ucontrol->value.integer.value[1];
749 if (right < 0)
750 right = 0;
751 if (right > 20)
752 right = 20;
753 spin_lock_irqsave(&chip->mixer_lock, flags);
754 change = chip->mixer_volume[addr][0] != left ||
755 chip->mixer_volume[addr][1] != right;
756 chip->mixer_volume[addr][0] = left;
757 chip->mixer_volume[addr][1] = right;
758 spin_unlock_irqrestore(&chip->mixer_lock, flags);
759 return change;
760}
761
762#define SAA713x_CAPSRC(xname, xindex, addr) \
763{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
764 .info = snd_saa7134_capsrc_info, \
765 .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
766 .private_value = addr }
767
768static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
769{
770 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
771 uinfo->count = 2;
772 uinfo->value.integer.min = 0;
773 uinfo->value.integer.max = 1;
774 return 0;
775}
776
777static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
778{
779 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
780 unsigned long flags;
781 int addr = kcontrol->private_value;
782
783 spin_lock_irqsave(&chip->mixer_lock, flags);
784 ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
785 ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
786 spin_unlock_irqrestore(&chip->mixer_lock, flags);
787 return 0;
788}
789
790static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
791{
792 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
793 unsigned long flags;
794 int change, addr = kcontrol->private_value;
795 int left, right;
796 u32 anabar, xbarin;
797 int analog_io, rate;
798 struct saa7134_dev *dev;
799
800 dev = chip->saadev;
801
802 left = ucontrol->value.integer.value[0] & 1;
803 right = ucontrol->value.integer.value[1] & 1;
804 spin_lock_irqsave(&chip->mixer_lock, flags);
805
806 change = chip->capture_source[addr][0] != left ||
807 chip->capture_source[addr][1] != right;
808 chip->capture_source[addr][0] = left;
809 chip->capture_source[addr][1] = right;
810 dev->dmasound.input=addr;
811 spin_unlock_irqrestore(&chip->mixer_lock, flags);
812
813
814 if (change) {
815 switch (dev->pci->device) {
816
817 case PCI_DEVICE_ID_PHILIPS_SAA7134:
818 switch (addr) {
819 case MIXER_ADDR_TVTUNER:
820 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
821 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
822 break;
823 case MIXER_ADDR_LINE1:
824 case MIXER_ADDR_LINE2:
825 analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
826 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
827 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
828 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
829 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
830 break;
831 }
832
833 break;
834 case PCI_DEVICE_ID_PHILIPS_SAA7133:
835 case PCI_DEVICE_ID_PHILIPS_SAA7135:
836 xbarin = 0x03; // adc
837 anabar = 0;
838 switch (addr) {
839 case MIXER_ADDR_TVTUNER:
840 xbarin = 0; // Demodulator
841 anabar = 2; // DACs
842 break;
843 case MIXER_ADDR_LINE1:
844 anabar = 0; // aux1, aux1
845 break;
846 case MIXER_ADDR_LINE2:
847 anabar = 9; // aux2, aux2
848 break;
849 }
850
851 /* output xbar always main channel */
852 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
853
854 if (left || right) { // We've got data, turn the input on
855 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
856 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
857 } else {
858 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
859 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
860 }
861 break;
862 }
863 }
864
865 return change;
866}
867
868static snd_kcontrol_new_t snd_saa7134_controls[] = {
869SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
870SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
871SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
872SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
873SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
874SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
875};
876
877/*
878 * ALSA mixer setup
879 *
880 * Called when initializing the board. Sets up the name and hooks up
881 * the callbacks
882 *
883 */
884
885static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
886{
887 snd_card_t *card = chip->card;
888 unsigned int idx;
889 int err;
890
891 snd_assert(chip != NULL, return -EINVAL);
892 strcpy(card->mixername, "SAA7134 Mixer");
893
894 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
895 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
896 return err;
897 }
898 return 0;
899}
900
901static int snd_saa7134_free(snd_card_saa7134_t *chip)
902{
903 return 0;
904}
905
906static int snd_saa7134_dev_free(snd_device_t *device)
907{
908 snd_card_saa7134_t *chip = device->device_data;
909 return snd_saa7134_free(chip);
910}
911
912/*
913 * ALSA initialization
914 *
915 * Called by saa7134-core, it creates the basic structures and registers
916 * the ALSA devices
917 *
918 */
919
920int alsa_card_saa7134_create (struct saa7134_dev *saadev)
921{
922 static int dev;
923
924 snd_card_t *card;
925 snd_card_saa7134_t *chip;
926 int err;
927 static snd_device_ops_t ops = {
928 .dev_free = snd_saa7134_dev_free,
929 };
930
931
932 if (dev >= SNDRV_CARDS)
933 return -ENODEV;
934 if (!enable[dev])
935 return -ENODEV;
936
937 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
938
939 if (card == NULL)
940 return -ENOMEM;
941
942 strcpy(card->driver, "SAA7134");
943
944 /* Card "creation" */
945
946 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
947 if (chip == NULL) {
948 return -ENOMEM;
949 }
950
951 spin_lock_init(&chip->lock);
952 spin_lock_init(&chip->mixer_lock);
953
954 chip->saadev = saadev;
955
956 chip->card = card;
957
958 chip->pci = saadev->pci;
959 chip->irq = saadev->pci->irq;
960 chip->iobase = pci_resource_start(saadev->pci, 0);
961
962 err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
963 SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
964
965 if (err < 0) {
966 printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
967 saadev->name, saadev->pci->irq);
968 goto __nodev;
969 }
970
971 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
972 goto __nodev;
973 }
974
975 if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
976 goto __nodev;
977
978 if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
979 goto __nodev;
980
981 snd_card_set_dev(card, &chip->pci->dev);
982
983 /* End of "creation" */
984
985 strcpy(card->shortname, "SAA7134");
986 sprintf(card->longname, "%s at 0x%lx irq %d",
987 chip->saadev->name, chip->iobase, chip->irq);
988
989 if ((err = snd_card_register(card)) == 0) {
990 snd_saa7134_cards[dev] = card;
991 return 0;
992 }
993
994__nodev:
995 snd_card_free(card);
996 kfree(chip);
997 return err;
998}
999
1000/*
1001 * Module initializer
1002 *
1003 * Loops through present saa7134 cards, and assigns an ALSA device
1004 * to each one
1005 *
1006 */
1007
1008static int saa7134_alsa_init(void)
1009{
1010 struct saa7134_dev *saadev = NULL;
1011 struct list_head *list;
1012
1013 printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
1014
1015 list_for_each(list,&saa7134_devlist) {
1016 saadev = list_entry(list, struct saa7134_dev, devlist);
1017 alsa_card_saa7134_create(saadev);
1018 }
1019
1020 if (saadev == NULL)
1021 printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
1022
1023 return 0;
1024
1025}
1026
1027/*
1028 * Module destructor
1029 */
1030
1031void saa7134_alsa_exit(void)
1032{
1033 int idx;
1034
1035 for (idx = 0; idx < SNDRV_CARDS; idx++) {
1036 snd_card_free(snd_saa7134_cards[idx]);
1037 }
1038
1039 printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
1040
1041 return;
1042}
1043
1044module_init(saa7134_alsa_init);
1045module_exit(saa7134_alsa_exit);
1046MODULE_LICENSE("GPL");
1047MODULE_AUTHOR("Ricardo Cerqueira");
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index acc7a4335e23..663d03e5bc67 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -191,10 +191,14 @@ struct saa7134_board saa7134_boards[] = {
191 .amux = TV, 191 .amux = TV,
192 .tv = 1, 192 .tv = 1,
193 },{ 193 },{
194 .name = name_comp1, 194 .name = name_comp1, /* Composite signal on S-Video input */
195 .vmux = 0, 195 .vmux = 0,
196 .amux = LINE2, 196 .amux = LINE2,
197 },{ 197 },{
198 .name = name_comp2, /* Composite input */
199 .vmux = 3,
200 .amux = LINE2,
201 },{
198 .name = name_svideo, 202 .name = name_svideo,
199 .vmux = 8, 203 .vmux = 8,
200 .amux = LINE2, 204 .amux = LINE2,
@@ -2109,8 +2113,423 @@ struct saa7134_board saa7134_boards[] = {
2109 .gpio = 0x01, 2113 .gpio = 0x01,
2110 }, 2114 },
2111 }, 2115 },
2112}; 2116 [SAA7134_BOARD_BEHOLD_409FM] = {
2117 /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */
2118 .name = "Beholder BeholdTV 409 FM",
2119 .audio_clock = 0x00187de7,
2120 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2121 .radio_type = UNSET,
2122 .tuner_addr = ADDR_UNSET,
2123 .radio_addr = ADDR_UNSET,
2124 .tda9887_conf = TDA9887_PRESENT,
2125 .inputs = {{
2126 .name = name_tv,
2127 .vmux = 3,
2128 .amux = TV,
2129 .tv = 1,
2130 },{
2131 .name = name_comp1,
2132 .vmux = 1,
2133 .amux = LINE1,
2134 },{
2135 .name = name_svideo,
2136 .vmux = 8,
2137 .amux = LINE1,
2138 }},
2139 .radio = {
2140 .name = name_radio,
2141 .amux = LINE2,
2142 },
2143 },
2144 [SAA7134_BOARD_GOTVIEW_7135] = {
2145 /* Mike Baikov <mike@baikov.com> */
2146 /* Andrey Cvetcov <ays14@yandex.ru> */
2147 .name = "GoTView 7135 PCI",
2148 .audio_clock = 0x00187de7,
2149 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2150 .radio_type = UNSET,
2151 .tuner_addr = ADDR_UNSET,
2152 .radio_addr = ADDR_UNSET,
2153 .tda9887_conf = TDA9887_PRESENT,
2154 .gpiomask = 0x00200003,
2155 .inputs = {{
2156 .name = name_tv,
2157 .vmux = 1,
2158 .amux = TV,
2159 .tv = 1,
2160 .gpio = 0x00200003,
2161 },{
2162 .name = name_tv_mono,
2163 .vmux = 1,
2164 .amux = LINE2,
2165 .gpio = 0x00200003,
2166 },{
2167 .name = name_comp1,
2168 .vmux = 3,
2169 .amux = LINE1,
2170 .gpio = 0x00200003,
2171 },{
2172 .name = name_svideo,
2173 .vmux = 8,
2174 .amux = LINE1,
2175 .gpio = 0x00200003,
2176 }},
2177 .radio = {
2178 .name = name_radio,
2179 .amux = LINE2,
2180 .gpio = 0x00200003,
2181 },
2182 .mute = {
2183 .name = name_mute,
2184 .amux = TV,
2185 .gpio = 0x00200003,
2186 },
2187 },
2188 [SAA7134_BOARD_PHILIPS_EUROPA] = {
2189 .name = "Philips EUROPA V3 reference design",
2190 .audio_clock = 0x00187de7,
2191 .tuner_type = TUNER_PHILIPS_TD1316,
2192 .radio_type = UNSET,
2193 .tuner_addr = 0x61,
2194 .radio_addr = ADDR_UNSET,
2195 .tda9887_conf = TDA9887_PRESENT,
2196 .mpeg = SAA7134_MPEG_DVB,
2197 .inputs = {{
2198 .name = name_tv,
2199 .vmux = 3,
2200 .amux = TV,
2201 .tv = 1,
2202 },{
2203 .name = name_comp1,
2204 .vmux = 0,
2205 .amux = LINE2,
2206 },{
2207 .name = name_svideo,
2208 .vmux = 8,
2209 .amux = LINE2,
2210 }},
2211 },
2212 [SAA7134_BOARD_VIDEOMATE_DVBT_300] = {
2213 .name = "Compro Videomate DVB-T300",
2214 .audio_clock = 0x00187de7,
2215 .tuner_type = TUNER_PHILIPS_TD1316,
2216 .radio_type = UNSET,
2217 .tuner_addr = 0x61,
2218 .radio_addr = ADDR_UNSET,
2219 .tda9887_conf = TDA9887_PRESENT,
2220 .mpeg = SAA7134_MPEG_DVB,
2221 .inputs = {{
2222 .name = name_tv,
2223 .vmux = 3,
2224 .amux = TV,
2225 .tv = 1,
2226 },{
2227 .name = name_comp1,
2228 .vmux = 1,
2229 .amux = LINE2,
2230 },{
2231 .name = name_svideo,
2232 .vmux = 8,
2233 .amux = LINE2,
2234 }},
2235 },
2236 [SAA7134_BOARD_VIDEOMATE_DVBT_200] = {
2237 .name = "Compro Videomate DVB-T200",
2238 .tuner_type = TUNER_ABSENT,
2239 .audio_clock = 0x00187de7,
2240 .radio_type = UNSET,
2241 .tuner_addr = ADDR_UNSET,
2242 .radio_addr = ADDR_UNSET,
2243 .mpeg = SAA7134_MPEG_DVB,
2244 .inputs = {{
2245 .name = name_comp1,
2246 .vmux = 0,
2247 .amux = LINE1,
2248 },{
2249 .name = name_svideo,
2250 .vmux = 8,
2251 .amux = LINE1,
2252 }},
2253 },
2254 [SAA7134_BOARD_RTD_VFG7350] = {
2255 .name = "RTD Embedded Technologies VFG7350",
2256 .audio_clock = 0x00200000,
2257 .tuner_type = TUNER_ABSENT,
2258 .radio_type = UNSET,
2259 .tuner_addr = ADDR_UNSET,
2260 .radio_addr = ADDR_UNSET,
2261 .inputs = {{
2262 .name = "Composite 0",
2263 .vmux = 0,
2264 .amux = LINE1,
2265 },{
2266 .name = "Composite 1",
2267 .vmux = 1,
2268 .amux = LINE2,
2269 },{
2270 .name = "Composite 2",
2271 .vmux = 2,
2272 .amux = LINE1,
2273 },{
2274 .name = "Composite 3",
2275 .vmux = 3,
2276 .amux = LINE2,
2277 },{
2278 .name = "S-Video 0",
2279 .vmux = 8,
2280 .amux = LINE1,
2281 },{
2282 .name = "S-Video 1",
2283 .vmux = 9,
2284 .amux = LINE2,
2285 }},
2286 .mpeg = SAA7134_MPEG_EMPRESS,
2287 .video_out = CCIR656,
2288 .vid_port_opts = ( SET_T_CODE_POLARITY_NON_INVERTED |
2289 SET_CLOCK_NOT_DELAYED |
2290 SET_CLOCK_INVERTED |
2291 SET_VSYNC_OFF ),
2292 },
2293 [SAA7134_BOARD_RTD_VFG7330] = {
2294 .name = "RTD Embedded Technologies VFG7330",
2295 .audio_clock = 0x00200000,
2296 .tuner_type = TUNER_ABSENT,
2297 .radio_type = UNSET,
2298 .tuner_addr = ADDR_UNSET,
2299 .radio_addr = ADDR_UNSET,
2300 .inputs = {{
2301 .name = "Composite 0",
2302 .vmux = 0,
2303 .amux = LINE1,
2304 },{
2305 .name = "Composite 1",
2306 .vmux = 1,
2307 .amux = LINE2,
2308 },{
2309 .name = "Composite 2",
2310 .vmux = 2,
2311 .amux = LINE1,
2312 },{
2313 .name = "Composite 3",
2314 .vmux = 3,
2315 .amux = LINE2,
2316 },{
2317 .name = "S-Video 0",
2318 .vmux = 8,
2319 .amux = LINE1,
2320 },{
2321 .name = "S-Video 1",
2322 .vmux = 9,
2323 .amux = LINE2,
2324 }},
2325 },
2326 [SAA7134_BOARD_FLYTVPLATINUM_MINI2] = {
2327 .name = "LifeView FlyTV Platinum Mini2",
2328 .audio_clock = 0x00200000,
2329 .tuner_type = TUNER_PHILIPS_TDA8290,
2330 .radio_type = UNSET,
2331 .tuner_addr = ADDR_UNSET,
2332 .radio_addr = ADDR_UNSET,
2113 2333
2334 .inputs = {{
2335 .name = name_tv,
2336 .vmux = 1,
2337 .amux = TV,
2338 .tv = 1,
2339 },{
2340 .name = name_comp1, /* Composite signal on S-Video input */
2341 .vmux = 0,
2342 .amux = LINE2,
2343 },{
2344 .name = name_comp2, /* Composite input */
2345 .vmux = 3,
2346 .amux = LINE2,
2347 },{
2348 .name = name_svideo,
2349 .vmux = 8,
2350 .amux = LINE2,
2351 }},
2352 },
2353 [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = {
2354 /* Michael Krufky <mkrufky@m1k.net>
2355 * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder
2356 * AFAIK, there is no analog demod, thus,
2357 * no support for analog television.
2358 */
2359 .name = "AVerMedia AVerTVHD MCE A180",
2360 .audio_clock = 0x00187de7,
2361 .tuner_type = TUNER_ABSENT,
2362 .radio_type = UNSET,
2363 .tuner_addr = ADDR_UNSET,
2364 .radio_addr = ADDR_UNSET,
2365 .mpeg = SAA7134_MPEG_DVB,
2366 .inputs = {{
2367 .name = name_comp1,
2368 .vmux = 3,
2369 .amux = LINE2,
2370 },{
2371 .name = name_svideo,
2372 .vmux = 8,
2373 .amux = LINE2,
2374 }},
2375 },
2376 [SAA7134_BOARD_MONSTERTV_MOBILE] = {
2377 .name = "SKNet MonsterTV Mobile",
2378 .audio_clock = 0x00187de7,
2379 .tuner_type = TUNER_PHILIPS_TDA8290,
2380 .radio_type = UNSET,
2381 .tuner_addr = ADDR_UNSET,
2382 .radio_addr = ADDR_UNSET,
2383
2384 .inputs = {{
2385 .name = name_tv,
2386 .vmux = 1,
2387 .amux = TV,
2388 .tv = 1,
2389 },{
2390 .name = name_comp1,
2391 .vmux = 3,
2392 .amux = LINE1,
2393 },{
2394 .name = name_svideo,
2395 .vmux = 6,
2396 .amux = LINE1,
2397 }},
2398 },
2399 [SAA7134_BOARD_PINNACLE_PCTV_110i] = {
2400 .name = "Pinnacle PCTV 110i (saa7133)",
2401 .audio_clock = 0x00187de7,
2402 .tuner_type = TUNER_PHILIPS_TDA8290,
2403 .radio_type = UNSET,
2404 .tuner_addr = ADDR_UNSET,
2405 .radio_addr = ADDR_UNSET,
2406 .gpiomask = 0x080200000,
2407 .inputs = {{
2408 .name = name_tv,
2409 .vmux = 4,
2410 .amux = TV,
2411 .tv = 1,
2412 },{
2413 .name = name_comp1,
2414 .vmux = 1,
2415 .amux = LINE2,
2416 },{
2417 .name = name_svideo,
2418 .vmux = 8,
2419 .amux = LINE2,
2420 }},
2421 .radio = {
2422 .name = name_radio,
2423 .amux = LINE1,
2424 },
2425 },
2426 [SAA7134_BOARD_ASUSTeK_P7131_DUAL] = {
2427 .name = "ASUSTeK P7131 Dual",
2428 .audio_clock = 0x00187de7,
2429 .tuner_type = TUNER_PHILIPS_TDA8290,
2430 .radio_type = UNSET,
2431 .tuner_addr = ADDR_UNSET,
2432 .radio_addr = ADDR_UNSET,
2433 .gpiomask = 1 << 21,
2434 .mpeg = SAA7134_MPEG_DVB,
2435 .inputs = {{
2436 .name = name_tv,
2437 .vmux = 1,
2438 .amux = TV,
2439 .tv = 1,
2440 },{
2441 .name = name_comp1,
2442 .vmux = 3,
2443 .amux = LINE2,
2444 },{
2445 .name = name_svideo,
2446 .vmux = 8,
2447 .amux = LINE2,
2448 }},
2449 .radio = {
2450 .name = name_radio,
2451 .amux = TV,
2452 .gpio = 0x0200000,
2453 },
2454 },
2455 [SAA7134_BOARD_SEDNA_PC_TV_CARDBUS] = {
2456 /* Paul Tom Zalac <pzalac@gmail.com> */
2457 /* Pavel Mihaylov <bin@bash.info> */
2458 .name = "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)",
2459 /* Sedna/MuchTV (OEM) Cardbus TV Tuner */
2460 .audio_clock = 0x00187de7,
2461 .tuner_type = TUNER_PHILIPS_TDA8290,
2462 .radio_type = UNSET,
2463 .tuner_addr = ADDR_UNSET,
2464 .radio_addr = ADDR_UNSET,
2465 .gpiomask = 0xe880c0,
2466 .inputs = {{
2467 .name = name_tv,
2468 .vmux = 3,
2469 .amux = TV,
2470 .tv = 1,
2471 },{
2472 .name = name_comp1,
2473 .vmux = 1,
2474 .amux = LINE1,
2475 },{
2476 .name = name_svideo,
2477 .vmux = 6,
2478 .amux = LINE1,
2479 }},
2480 .radio = {
2481 .name = name_radio,
2482 .amux = LINE2,
2483 },
2484 },
2485 [SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV] = {
2486 /* "Cyril Lacoux (Yack)" <clacoux@ifeelgood.org> */
2487 .name = "ASUS Digimatrix TV",
2488 .audio_clock = 0x00200000,
2489 .tuner_type = TUNER_PHILIPS_FQ1216ME,
2490 .tda9887_conf = TDA9887_PRESENT,
2491 .radio_type = UNSET,
2492 .tuner_addr = ADDR_UNSET,
2493 .radio_addr = ADDR_UNSET,
2494 .inputs = {{
2495 .name = name_tv,
2496 .vmux = 1,
2497 .amux = TV,
2498 .tv = 1,
2499 },{
2500 .name = name_comp1,
2501 .vmux = 3,
2502 .amux = LINE1,
2503 },{
2504 .name = name_svideo,
2505 .vmux = 8,
2506 .amux = LINE1,
2507 }},
2508 },
2509 [SAA7134_BOARD_PHILIPS_TIGER] = {
2510 .name = "Philips Tiger reference design",
2511 .audio_clock = 0x00187de7,
2512 .tuner_type = TUNER_PHILIPS_TDA8290,
2513 .radio_type = UNSET,
2514 .tuner_addr = ADDR_UNSET,
2515 .radio_addr = ADDR_UNSET,
2516 .mpeg = SAA7134_MPEG_DVB,
2517 .inputs = {{
2518 .name = name_tv,
2519 .vmux = 1,
2520 .amux = TV,
2521 .tv = 1,
2522 },{
2523 .name = name_comp1,
2524 .vmux = 3,
2525 .amux = LINE1,
2526 },{
2527 .name = name_svideo,
2528 .vmux = 8,
2529 .amux = LINE1,
2530 }},
2531 },
2532};
2114 2533
2115const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 2534const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
2116 2535
@@ -2145,19 +2564,19 @@ struct pci_device_id saa7134_pci_tbl[] = {
2145 },{ 2564 },{
2146 .vendor = PCI_VENDOR_ID_PHILIPS, 2565 .vendor = PCI_VENDOR_ID_PHILIPS,
2147 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2566 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2148 .subvendor = 0x153B, 2567 .subvendor = 0x153b,
2149 .subdevice = 0x1142, 2568 .subdevice = 0x1142,
2150 .driver_data = SAA7134_BOARD_CINERGY400, 2569 .driver_data = SAA7134_BOARD_CINERGY400,
2151 },{ 2570 },{
2152 .vendor = PCI_VENDOR_ID_PHILIPS, 2571 .vendor = PCI_VENDOR_ID_PHILIPS,
2153 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2572 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2154 .subvendor = 0x153B, 2573 .subvendor = 0x153b,
2155 .subdevice = 0x1143, 2574 .subdevice = 0x1143,
2156 .driver_data = SAA7134_BOARD_CINERGY600, 2575 .driver_data = SAA7134_BOARD_CINERGY600,
2157 },{ 2576 },{
2158 .vendor = PCI_VENDOR_ID_PHILIPS, 2577 .vendor = PCI_VENDOR_ID_PHILIPS,
2159 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2578 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2160 .subvendor = 0x153B, 2579 .subvendor = 0x153b,
2161 .subdevice = 0x1158, 2580 .subdevice = 0x1158,
2162 .driver_data = SAA7134_BOARD_CINERGY600_MK3, 2581 .driver_data = SAA7134_BOARD_CINERGY600_MK3,
2163 },{ 2582 },{
@@ -2193,6 +2612,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2193 },{ 2612 },{
2194 .vendor = PCI_VENDOR_ID_PHILIPS, 2613 .vendor = PCI_VENDOR_ID_PHILIPS,
2195 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2614 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2615 .subvendor = 0x14c0,
2616 .subdevice = 0x1212, /* minipci, LR1212 */
2617 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
2618 },{
2619 .vendor = PCI_VENDOR_ID_PHILIPS,
2620 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2621 .subvendor = 0x4e42,
2622 .subdevice = 0x0212, /* OEM minipci, LR212 */
2623 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
2624 },{
2625 .vendor = PCI_VENDOR_ID_PHILIPS,
2626 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2196 .subvendor = 0x5168, /* Animation Technologies (LifeView) */ 2627 .subvendor = 0x5168, /* Animation Technologies (LifeView) */
2197 .subdevice = 0x0214, /* Standard PCI, LR214WF */ 2628 .subdevice = 0x0214, /* Standard PCI, LR214WF */
2198 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, 2629 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
@@ -2369,7 +2800,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
2369 },{ 2800 },{
2370 .vendor = PCI_VENDOR_ID_PHILIPS, 2801 .vendor = PCI_VENDOR_ID_PHILIPS,
2371 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 2802 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2372 .subvendor = 0x153B, 2803 .subvendor = 0x153b,
2373 .subdevice = 0x1152, 2804 .subdevice = 0x1152,
2374 .driver_data = SAA7134_BOARD_CINERGY200, 2805 .driver_data = SAA7134_BOARD_CINERGY200,
2375 },{ 2806 },{
@@ -2434,13 +2865,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2434 .subvendor = 0x1421, 2865 .subvendor = 0x1421,
2435 .subdevice = 0x0350, /* PCI version */ 2866 .subdevice = 0x0350, /* PCI version */
2436 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2867 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2437
2438 },{ 2868 },{
2439 .vendor = PCI_VENDOR_ID_PHILIPS, 2869 .vendor = PCI_VENDOR_ID_PHILIPS,
2440 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2870 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2441 .subvendor = 0x1421, 2871 .subvendor = 0x1421,
2442 .subdevice = 0x0370, /* cardbus version */ 2872 .subdevice = 0x0370, /* cardbus version */
2443 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2873 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2874 },{
2875 .vendor = PCI_VENDOR_ID_PHILIPS,
2876 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2877 .subvendor = 0x1421,
2878 .subdevice = 0x1370, /* cardbus version */
2879 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2444 2880
2445 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ 2881 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */
2446 .vendor = PCI_VENDOR_ID_PHILIPS, 2882 .vendor = PCI_VENDOR_ID_PHILIPS,
@@ -2459,9 +2895,81 @@ struct pci_device_id saa7134_pci_tbl[] = {
2459 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2895 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2460 .subvendor = 0x1043, 2896 .subvendor = 0x1043,
2461 .subdevice = 0x0210, /* mini pci PAL/SECAM version */ 2897 .subdevice = 0x0210, /* mini pci PAL/SECAM version */
2462 .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX, 2898 .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
2463 2899
2464 },{ 2900 },{
2901 .vendor = PCI_VENDOR_ID_PHILIPS,
2902 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2903 .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */
2904 .subdevice = 0x4091,
2905 .driver_data = SAA7134_BOARD_BEHOLD_409FM,
2906 },{
2907 .vendor = PCI_VENDOR_ID_PHILIPS,
2908 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2909 .subvendor = 0x5456, /* GoTView */
2910 .subdevice = 0x7135,
2911 .driver_data = SAA7134_BOARD_GOTVIEW_7135,
2912 },{
2913 .vendor = PCI_VENDOR_ID_PHILIPS,
2914 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2915 .subvendor = PCI_VENDOR_ID_PHILIPS,
2916 .subdevice = 0x2004,
2917 .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
2918 },{
2919 .vendor = PCI_VENDOR_ID_PHILIPS,
2920 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2921 .subvendor = 0x185b,
2922 .subdevice = 0xc900,
2923 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
2924 },{
2925 .vendor = PCI_VENDOR_ID_PHILIPS,
2926 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2927 .subvendor = 0x185b,
2928 .subdevice = 0xc901,
2929 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
2930 },{
2931 .vendor = PCI_VENDOR_ID_PHILIPS,
2932 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2933 .subvendor = 0x1435,
2934 .subdevice = 0x7350,
2935 .driver_data = SAA7134_BOARD_RTD_VFG7350,
2936 },{
2937 .vendor = PCI_VENDOR_ID_PHILIPS,
2938 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2939 .subvendor = 0x1435,
2940 .subdevice = 0x7330,
2941 .driver_data = SAA7134_BOARD_RTD_VFG7330,
2942 },{
2943 .vendor = PCI_VENDOR_ID_PHILIPS,
2944 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2945 .subvendor = 0x1461,
2946 .subdevice = 0x1044,
2947 .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
2948 },{
2949 .vendor = PCI_VENDOR_ID_PHILIPS,
2950 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2951 .subvendor = 0x1131,
2952 .subdevice = 0x4ee9,
2953 .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
2954 },{
2955 .vendor = PCI_VENDOR_ID_PHILIPS,
2956 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2957 .subvendor = 0x11bd,
2958 .subdevice = 0x002e,
2959 .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
2960 },{
2961 .vendor = PCI_VENDOR_ID_PHILIPS,
2962 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2963 .subvendor = 0x1043,
2964 .subdevice = 0x4862,
2965 .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
2966 },{
2967 .vendor = PCI_VENDOR_ID_PHILIPS,
2968 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2969 .subvendor = PCI_VENDOR_ID_PHILIPS,
2970 .subdevice = 0x2018,
2971 .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
2972 },{
2465 /* --- boards without eeprom + subsystem ID --- */ 2973 /* --- boards without eeprom + subsystem ID --- */
2466 .vendor = PCI_VENDOR_ID_PHILIPS, 2974 .vendor = PCI_VENDOR_ID_PHILIPS,
2467 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2975 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -2530,9 +3038,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2530 switch (dev->board) { 3038 switch (dev->board) {
2531 case SAA7134_BOARD_FLYVIDEO2000: 3039 case SAA7134_BOARD_FLYVIDEO2000:
2532 case SAA7134_BOARD_FLYVIDEO3000: 3040 case SAA7134_BOARD_FLYVIDEO3000:
2533 dev->has_remote = 1; 3041 dev->has_remote = SAA7134_REMOTE_GPIO;
2534 board_flyvideo(dev); 3042 board_flyvideo(dev);
2535 break; 3043 break;
3044 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
2536 case SAA7134_BOARD_FLYTVPLATINUM_FM: 3045 case SAA7134_BOARD_FLYTVPLATINUM_FM:
2537 case SAA7134_BOARD_CINERGY400: 3046 case SAA7134_BOARD_CINERGY400:
2538 case SAA7134_BOARD_CINERGY600: 3047 case SAA7134_BOARD_CINERGY600:
@@ -2550,10 +3059,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2550/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ 3059/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
2551 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 3060 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
2552 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 3061 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
3062 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3063 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
2553 case SAA7134_BOARD_MANLI_MTV001: 3064 case SAA7134_BOARD_MANLI_MTV001:
2554 case SAA7134_BOARD_MANLI_MTV002: 3065 case SAA7134_BOARD_MANLI_MTV002:
3066 case SAA7134_BOARD_BEHOLD_409FM:
2555 case SAA7134_BOARD_AVACSSMARTTV: 3067 case SAA7134_BOARD_AVACSSMARTTV:
2556 dev->has_remote = 1; 3068 case SAA7134_BOARD_GOTVIEW_7135:
3069 case SAA7134_BOARD_KWORLD_TERMINATOR:
3070 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
3071 dev->has_remote = SAA7134_REMOTE_GPIO;
2557 break; 3072 break;
2558 case SAA7134_BOARD_MD5044: 3073 case SAA7134_BOARD_MD5044:
2559 printk("%s: seems there are two different versions of the MD5044\n" 3074 printk("%s: seems there are two different versions of the MD5044\n"
@@ -2565,11 +3080,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2565 /* power-up tuner chip */ 3080 /* power-up tuner chip */
2566 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); 3081 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
2567 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); 3082 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
2568 msleep(1); 3083 case SAA7134_BOARD_MONSTERTV_MOBILE:
3084 /* power-up tuner chip */
3085 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
3086 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
2569 break; 3087 break;
2570 case SAA7134_BOARD_FLYDVBTDUO: 3088 case SAA7134_BOARD_FLYDVBTDUO:
2571 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: 3089 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
2572 /* turn the fan on Hac: static for the time being */ 3090 /* turn the fan on */
2573 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); 3091 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
2574 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); 3092 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
2575 break; 3093 break;
@@ -2579,6 +3097,22 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2579 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); 3097 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
2580 msleep(1); 3098 msleep(1);
2581 break; 3099 break;
3100 case SAA7134_BOARD_RTD_VFG7350:
3101
3102 /*
3103 * Make sure Production Test Register at offset 0x1D1 is cleared
3104 * to take chip out of test mode. Clearing bit 4 (TST_EN_AOUT)
3105 * prevents pin 105 from remaining low; keeping pin 105 low
3106 * continually resets the SAA6752 chip.
3107 */
3108
3109 saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
3110 break;
3111 /* i2c remotes */
3112 case SAA7134_BOARD_PINNACLE_PCTV_110i:
3113 case SAA7134_BOARD_UPMOST_PURPLE_TV:
3114 dev->has_remote = SAA7134_REMOTE_I2C;
3115 break;
2582 } 3116 }
2583 return 0; 3117 return 0;
2584} 3118}
@@ -2613,7 +3147,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
2613 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup); 3147 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
2614 } 3148 }
2615 break; 3149 break;
2616case SAA7134_BOARD_MD7134: 3150 case SAA7134_BOARD_MD7134:
2617 { 3151 {
2618 struct tuner_setup tun_setup; 3152 struct tuner_setup tun_setup;
2619 u8 subaddr; 3153 u8 subaddr;
@@ -2680,6 +3214,33 @@ case SAA7134_BOARD_MD7134:
2680 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); 3214 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
2681 } 3215 }
2682 break; 3216 break;
3217 case SAA7134_BOARD_PHILIPS_EUROPA:
3218 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3219 /* The Philips EUROPA based hybrid boards have the tuner connected through
3220 * the channel decoder. We have to make it transparent to find it
3221 */
3222 {
3223 struct tuner_setup tun_setup;
3224 u8 data[] = { 0x07, 0x02};
3225 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3226 i2c_transfer(&dev->i2c_adap, &msg, 1);
3227
3228 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
3229 tun_setup.type = dev->tuner_type;
3230 tun_setup.addr = dev->tuner_addr;
3231
3232 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
3233 }
3234 break;
3235 case SAA7134_BOARD_PHILIPS_TIGER:
3236 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
3237 /* this is a hybrid board, initialize to analog mode */
3238 {
3239 u8 data[] = { 0x3c, 0x33, 0x68};
3240 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3241 i2c_transfer(&dev->i2c_adap, &msg, 1);
3242 }
3243 break;
2683 } 3244 }
2684 return 0; 3245 return 0;
2685} 3246}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index e5e36f3c6250..19b88744fb31 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -57,6 +57,10 @@ static unsigned int oss = 0;
57module_param(oss, int, 0444); 57module_param(oss, int, 0444);
58MODULE_PARM_DESC(oss,"register oss devices (default: no)"); 58MODULE_PARM_DESC(oss,"register oss devices (default: no)");
59 59
60static unsigned int alsa = 0;
61module_param(alsa, int, 0444);
62MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
63
60static unsigned int latency = UNSET; 64static unsigned int latency = UNSET;
61module_param(latency, int, 0444); 65module_param(latency, int, 0444);
62MODULE_PARM_DESC(latency,"pci latency timer"); 66MODULE_PARM_DESC(latency,"pci latency timer");
@@ -190,6 +194,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
190 194
191static int need_empress; 195static int need_empress;
192static int need_dvb; 196static int need_dvb;
197static int need_alsa;
193 198
194static int pending_call(struct notifier_block *self, unsigned long state, 199static int pending_call(struct notifier_block *self, unsigned long state,
195 void *module) 200 void *module)
@@ -197,10 +202,12 @@ static int pending_call(struct notifier_block *self, unsigned long state,
197 if (module != THIS_MODULE || state != MODULE_STATE_LIVE) 202 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
198 return NOTIFY_DONE; 203 return NOTIFY_DONE;
199 204
200 if (need_empress) 205 if (need_empress)
201 request_module("saa7134-empress"); 206 request_module("saa7134-empress");
202 if (need_dvb) 207 if (need_dvb)
203 request_module("saa7134-dvb"); 208 request_module("saa7134-dvb");
209 if (need_alsa)
210 request_module("saa7134-alsa");
204 return NOTIFY_DONE; 211 return NOTIFY_DONE;
205} 212}
206 213
@@ -275,8 +282,8 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
275 282
276int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) 283int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
277{ 284{
278 __le32 *cpu; 285 __le32 *cpu;
279 dma_addr_t dma_addr; 286 dma_addr_t dma_addr;
280 287
281 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); 288 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
282 if (NULL == cpu) 289 if (NULL == cpu)
@@ -436,7 +443,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
436 ctrl |= SAA7134_MAIN_CTRL_TE0; 443 ctrl |= SAA7134_MAIN_CTRL_TE0;
437 irq |= SAA7134_IRQ1_INTE_RA0_1 | 444 irq |= SAA7134_IRQ1_INTE_RA0_1 |
438 SAA7134_IRQ1_INTE_RA0_0; 445 SAA7134_IRQ1_INTE_RA0_0;
439 cap = dev->video_q.curr->vb.field; 446 cap = dev->video_q.curr->vb.field;
440 } 447 }
441 448
442 /* video capture -- dma 1+2 (planar modes) */ 449 /* video capture -- dma 1+2 (planar modes) */
@@ -465,7 +472,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
465 } 472 }
466 473
467 /* audio capture -- dma 3 */ 474 /* audio capture -- dma 3 */
468 if (dev->oss.dma_running) { 475 if (dev->dmasound.dma_running) {
469 ctrl |= SAA7134_MAIN_CTRL_TE6; 476 ctrl |= SAA7134_MAIN_CTRL_TE6;
470 irq |= SAA7134_IRQ1_INTE_RA3_1 | 477 irq |= SAA7134_IRQ1_INTE_RA3_1 |
471 SAA7134_IRQ1_INTE_RA3_0; 478 SAA7134_IRQ1_INTE_RA3_0;
@@ -570,6 +577,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
570 dev->name); 577 dev->name);
571 goto out; 578 goto out;
572 } 579 }
580
581 /* If alsa support is active and we get a sound report, exit
582 and let the saa7134-alsa module deal with it */
583
584 if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
585 if (irq_debug > 1)
586 printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
587 dev->name);
588 goto out;
589 }
590
573 handled = 1; 591 handled = 1;
574 saa_writel(SAA7134_IRQ_REPORT,report); 592 saa_writel(SAA7134_IRQ_REPORT,report);
575 if (irq_debug) 593 if (irq_debug)
@@ -591,13 +609,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
591 card_has_mpeg(dev)) 609 card_has_mpeg(dev))
592 saa7134_irq_ts_done(dev,status); 610 saa7134_irq_ts_done(dev,status);
593 611
594 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) 612 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
595 saa7134_irq_oss_done(dev,status); 613 if (oss) {
614 saa7134_irq_oss_done(dev,status);
615 }
616 }
596 617
597 if ((report & (SAA7134_IRQ_REPORT_GPIO16 | 618 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
598 SAA7134_IRQ_REPORT_GPIO18)) && 619 SAA7134_IRQ_REPORT_GPIO18)) &&
599 dev->remote) 620 dev->remote)
600 saa7134_input_irq(dev); 621 saa7134_input_irq(dev);
622
601 } 623 }
602 624
603 if (10 == loop) { 625 if (10 == loop) {
@@ -636,7 +658,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
636 658
637 saa_writel(SAA7134_IRQ1, 0); 659 saa_writel(SAA7134_IRQ1, 0);
638 saa_writel(SAA7134_IRQ2, 0); 660 saa_writel(SAA7134_IRQ2, 0);
639 init_MUTEX(&dev->lock); 661 init_MUTEX(&dev->lock);
640 spin_lock_init(&dev->slock); 662 spin_lock_init(&dev->slock);
641 663
642 saa7134_track_gpio(dev,"pre-init"); 664 saa7134_track_gpio(dev,"pre-init");
@@ -646,14 +668,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
646 saa7134_ts_init1(dev); 668 saa7134_ts_init1(dev);
647 saa7134_input_init1(dev); 669 saa7134_input_init1(dev);
648 670
649 switch (dev->pci->device) {
650 case PCI_DEVICE_ID_PHILIPS_SAA7134:
651 case PCI_DEVICE_ID_PHILIPS_SAA7133:
652 case PCI_DEVICE_ID_PHILIPS_SAA7135:
653 saa7134_oss_init1(dev);
654 break;
655 }
656
657 /* RAM FIFO config */ 671 /* RAM FIFO config */
658 saa_writel(SAA7134_FIFO_SIZE, 0x08070503); 672 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
659 saa_writel(SAA7134_THRESHOULD,0x02020202); 673 saa_writel(SAA7134_THRESHOULD,0x02020202);
@@ -668,6 +682,21 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
668 SAA7134_MAIN_CTRL_ESFE | 682 SAA7134_MAIN_CTRL_ESFE |
669 SAA7134_MAIN_CTRL_EBDAC); 683 SAA7134_MAIN_CTRL_EBDAC);
670 684
685 /*
686 * Initialize OSS _after_ enabling audio clock PLL and audio processing.
687 * OSS initialization writes to registers via the audio DSP; these
688 * writes will fail unless the audio clock has been started. At worst,
689 * audio will not work.
690 */
691
692 switch (dev->pci->device) {
693 case PCI_DEVICE_ID_PHILIPS_SAA7134:
694 case PCI_DEVICE_ID_PHILIPS_SAA7133:
695 case PCI_DEVICE_ID_PHILIPS_SAA7135:
696 saa7134_oss_init1(dev);
697 break;
698 }
699
671 /* enable peripheral devices */ 700 /* enable peripheral devices */
672 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 701 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
673 702
@@ -687,7 +716,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
687 saa7134_tvaudio_init2(dev); 716 saa7134_tvaudio_init2(dev);
688 717
689 /* enable IRQ's */ 718 /* enable IRQ's */
690 irq2_mask = 719 irq2_mask =
691 SAA7134_IRQ2_INTE_DEC3 | 720 SAA7134_IRQ2_INTE_DEC3 |
692 SAA7134_IRQ2_INTE_DEC2 | 721 SAA7134_IRQ2_INTE_DEC2 |
693 SAA7134_IRQ2_INTE_DEC1 | 722 SAA7134_IRQ2_INTE_DEC1 |
@@ -695,10 +724,12 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
695 SAA7134_IRQ2_INTE_PE | 724 SAA7134_IRQ2_INTE_PE |
696 SAA7134_IRQ2_INTE_AR; 725 SAA7134_IRQ2_INTE_AR;
697 726
698 if (dev->has_remote) 727 if (dev->has_remote == SAA7134_REMOTE_GPIO)
699 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | 728 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
700 SAA7134_IRQ2_INTE_GPIO18A | 729 SAA7134_IRQ2_INTE_GPIO18A |
701 SAA7134_IRQ2_INTE_GPIO16 ); 730 SAA7134_IRQ2_INTE_GPIO16 );
731 else if (dev->has_remote == SAA7134_REMOTE_I2C)
732 request_module("ir-kbd-i2c");
702 733
703 saa_writel(SAA7134_IRQ1, 0); 734 saa_writel(SAA7134_IRQ1, 0);
704 saa_writel(SAA7134_IRQ2, irq2_mask); 735 saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -872,8 +903,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
872 903
873 /* print pci info */ 904 /* print pci info */
874 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 905 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
875 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 906 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
876 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " 907 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
877 "latency: %d, mmio: 0x%lx\n", dev->name, 908 "latency: %d, mmio: 0x%lx\n", dev->name,
878 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 909 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
879 dev->pci_lat,pci_resource_start(pci_dev,0)); 910 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -897,7 +928,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
897 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; 928 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
898 if (UNSET != tuner[dev->nr]) 929 if (UNSET != tuner[dev->nr])
899 dev->tuner_type = tuner[dev->nr]; 930 dev->tuner_type = tuner[dev->nr];
900 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 931 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
901 dev->name,pci_dev->subsystem_vendor, 932 dev->name,pci_dev->subsystem_vendor,
902 pci_dev->subsystem_device,saa7134_boards[dev->board].name, 933 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
903 dev->board, card[dev->nr] == dev->board ? 934 dev->board, card[dev->nr] == dev->board ?
@@ -947,14 +978,20 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
947 request_module("tuner"); 978 request_module("tuner");
948 if (dev->tda9887_conf) 979 if (dev->tda9887_conf)
949 request_module("tda9887"); 980 request_module("tda9887");
950 if (card_is_empress(dev)) { 981 if (card_is_empress(dev)) {
951 request_module("saa6752hs"); 982 request_module("saa6752hs");
952 request_module_depend("saa7134-empress",&need_empress); 983 request_module_depend("saa7134-empress",&need_empress);
953 } 984 }
954 985
955 if (card_is_dvb(dev)) 986 if (card_is_dvb(dev))
956 request_module_depend("saa7134-dvb",&need_dvb); 987 request_module_depend("saa7134-dvb",&need_dvb);
957 988
989 if (!oss && alsa) {
990 dprintk("Requesting ALSA module\n");
991 request_module_depend("saa7134-alsa",&need_alsa);
992 }
993
994
958 v4l2_prio_init(&dev->prio); 995 v4l2_prio_init(&dev->prio);
959 996
960 /* register v4l devices */ 997 /* register v4l devices */
@@ -993,22 +1030,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
993 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1030 case PCI_DEVICE_ID_PHILIPS_SAA7133:
994 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1031 case PCI_DEVICE_ID_PHILIPS_SAA7135:
995 if (oss) { 1032 if (oss) {
996 err = dev->oss.minor_dsp = 1033 err = dev->dmasound.minor_dsp =
997 register_sound_dsp(&saa7134_dsp_fops, 1034 register_sound_dsp(&saa7134_dsp_fops,
998 dsp_nr[dev->nr]); 1035 dsp_nr[dev->nr]);
999 if (err < 0) { 1036 if (err < 0) {
1000 goto fail4; 1037 goto fail4;
1001 } 1038 }
1002 printk(KERN_INFO "%s: registered device dsp%d\n", 1039 printk(KERN_INFO "%s: registered device dsp%d\n",
1003 dev->name,dev->oss.minor_dsp >> 4); 1040 dev->name,dev->dmasound.minor_dsp >> 4);
1004 1041
1005 err = dev->oss.minor_mixer = 1042 err = dev->dmasound.minor_mixer =
1006 register_sound_mixer(&saa7134_mixer_fops, 1043 register_sound_mixer(&saa7134_mixer_fops,
1007 mixer_nr[dev->nr]); 1044 mixer_nr[dev->nr]);
1008 if (err < 0) 1045 if (err < 0)
1009 goto fail5; 1046 goto fail5;
1010 printk(KERN_INFO "%s: registered device mixer%d\n", 1047 printk(KERN_INFO "%s: registered device mixer%d\n",
1011 dev->name,dev->oss.minor_mixer >> 4); 1048 dev->name,dev->dmasound.minor_mixer >> 4);
1012 } 1049 }
1013 break; 1050 break;
1014 } 1051 }
@@ -1035,7 +1072,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1035 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1072 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1036 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1073 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1037 if (oss) 1074 if (oss)
1038 unregister_sound_dsp(dev->oss.minor_dsp); 1075 unregister_sound_dsp(dev->dmasound.minor_dsp);
1039 break; 1076 break;
1040 } 1077 }
1041 fail4: 1078 fail4:
@@ -1055,7 +1092,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1055 1092
1056static void __devexit saa7134_finidev(struct pci_dev *pci_dev) 1093static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1057{ 1094{
1058 struct saa7134_dev *dev = pci_get_drvdata(pci_dev); 1095 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
1059 struct list_head *item; 1096 struct list_head *item;
1060 struct saa7134_mpeg_ops *mops; 1097 struct saa7134_mpeg_ops *mops;
1061 1098
@@ -1093,8 +1130,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1093 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1130 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1094 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1131 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1095 if (oss) { 1132 if (oss) {
1096 unregister_sound_mixer(dev->oss.minor_mixer); 1133 unregister_sound_mixer(dev->dmasound.minor_mixer);
1097 unregister_sound_dsp(dev->oss.minor_dsp); 1134 unregister_sound_dsp(dev->dmasound.minor_dsp);
1098 } 1135 }
1099 break; 1136 break;
1100 } 1137 }
@@ -1149,10 +1186,10 @@ EXPORT_SYMBOL(saa7134_ts_unregister);
1149/* ----------------------------------------------------------- */ 1186/* ----------------------------------------------------------- */
1150 1187
1151static struct pci_driver saa7134_pci_driver = { 1188static struct pci_driver saa7134_pci_driver = {
1152 .name = "saa7134", 1189 .name = "saa7134",
1153 .id_table = saa7134_pci_tbl, 1190 .id_table = saa7134_pci_tbl,
1154 .probe = saa7134_initdev, 1191 .probe = saa7134_initdev,
1155 .remove = __devexit_p(saa7134_finidev), 1192 .remove = __devexit_p(saa7134_finidev),
1156}; 1193};
1157 1194
1158static int saa7134_init(void) 1195static int saa7134_init(void)
@@ -1188,6 +1225,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
1188EXPORT_SYMBOL(saa7134_devlist); 1225EXPORT_SYMBOL(saa7134_devlist);
1189EXPORT_SYMBOL(saa7134_boards); 1226EXPORT_SYMBOL(saa7134_boards);
1190 1227
1228/* ----------------- For ALSA -------------------------------- */
1229
1230EXPORT_SYMBOL(saa7134_pgtable_free);
1231EXPORT_SYMBOL(saa7134_pgtable_build);
1232EXPORT_SYMBOL(saa7134_pgtable_alloc);
1233EXPORT_SYMBOL(saa7134_set_dmabits);
1234
1191/* ----------------------------------------------------------- */ 1235/* ----------------------------------------------------------- */
1192/* 1236/*
1193 * Local variables: 1237 * Local variables:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 639ae51a052d..e016480c3468 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/kthread.h> 29#include <linux/kthread.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "saa7134-reg.h" 32#include "saa7134-reg.h"
34#include "saa7134.h" 33#include "saa7134.h"
35 34
@@ -40,6 +39,10 @@
40#ifdef HAVE_TDA1004X 39#ifdef HAVE_TDA1004X
41# include "tda1004x.h" 40# include "tda1004x.h"
42#endif 41#endif
42#ifdef HAVE_NXT200X
43# include "nxt200x.h"
44# include "dvb-pll.h"
45#endif
43 46
44MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 47MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
45MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
@@ -151,25 +154,12 @@ static struct mt352_config pinnacle_300i = {
151/* ------------------------------------------------------------------ */ 154/* ------------------------------------------------------------------ */
152 155
153#ifdef HAVE_TDA1004X 156#ifdef HAVE_TDA1004X
154static int philips_tu1216_pll_init(struct dvb_frontend *fe)
155{
156 struct saa7134_dev *dev = fe->dvb->priv;
157 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
158 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
159
160 /* setup PLL configuration */
161 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
162 return -EIO;
163 msleep(1);
164 157
165 return 0; 158static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
166}
167
168static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
169{ 159{
170 struct saa7134_dev *dev = fe->dvb->priv; 160 struct saa7134_dev *dev = fe->dvb->priv;
171 u8 tuner_buf[4]; 161 u8 tuner_buf[4];
172 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = 162 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
173 sizeof(tuner_buf) }; 163 sizeof(tuner_buf) };
174 int tuner_frequency = 0; 164 int tuner_frequency = 0;
175 u8 band, cp, filter; 165 u8 band, cp, filter;
@@ -242,11 +232,36 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
242 232
243 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 233 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
244 return -EIO; 234 return -EIO;
235 msleep(1);
236 return 0;
237}
245 238
239static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
240{
241 struct saa7134_dev *dev = fe->dvb->priv;
242 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
243 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
244
245 /* setup PLL configuration */
246 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
247 return -EIO;
246 msleep(1); 248 msleep(1);
249
247 return 0; 250 return 0;
248} 251}
249 252
253/* ------------------------------------------------------------------ */
254
255static int philips_tu1216_pll_60_init(struct dvb_frontend *fe)
256{
257 return philips_tda6651_pll_init(0x60, fe);
258}
259
260static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
261{
262 return philips_tda6651_pll_set(0x60, fe, params);
263}
264
250static int philips_tu1216_request_firmware(struct dvb_frontend *fe, 265static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
251 const struct firmware **fw, char *name) 266 const struct firmware **fw, char *name)
252{ 267{
@@ -254,22 +269,108 @@ static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
254 return request_firmware(fw, name, &dev->pci->dev); 269 return request_firmware(fw, name, &dev->pci->dev);
255} 270}
256 271
257static struct tda1004x_config philips_tu1216_config = { 272static struct tda1004x_config philips_tu1216_60_config = {
273
274 .demod_address = 0x8,
275 .invert = 1,
276 .invert_oclk = 0,
277 .xtal_freq = TDA10046_XTAL_4M,
278 .agc_config = TDA10046_AGC_DEFAULT,
279 .if_freq = TDA10046_FREQ_3617,
280 .pll_init = philips_tu1216_pll_60_init,
281 .pll_set = philips_tu1216_pll_60_set,
282 .pll_sleep = NULL,
283 .request_firmware = philips_tu1216_request_firmware,
284};
285
286/* ------------------------------------------------------------------ */
287
288static int philips_tu1216_pll_61_init(struct dvb_frontend *fe)
289{
290 return philips_tda6651_pll_init(0x61, fe);
291}
292
293static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
294{
295 return philips_tda6651_pll_set(0x61, fe, params);
296}
297
298static struct tda1004x_config philips_tu1216_61_config = {
258 299
259 .demod_address = 0x8, 300 .demod_address = 0x8,
260 .invert = 1, 301 .invert = 1,
261 .invert_oclk = 1, 302 .invert_oclk = 0,
262 .xtal_freq = TDA10046_XTAL_4M, 303 .xtal_freq = TDA10046_XTAL_4M,
263 .agc_config = TDA10046_AGC_DEFAULT, 304 .agc_config = TDA10046_AGC_DEFAULT,
264 .if_freq = TDA10046_FREQ_3617, 305 .if_freq = TDA10046_FREQ_3617,
265 .pll_init = philips_tu1216_pll_init, 306 .pll_init = philips_tu1216_pll_61_init,
266 .pll_set = philips_tu1216_pll_set, 307 .pll_set = philips_tu1216_pll_61_set,
267 .pll_sleep = NULL, 308 .pll_sleep = NULL,
268 .request_firmware = philips_tu1216_request_firmware, 309 .request_firmware = philips_tu1216_request_firmware,
269}; 310};
270 311
271/* ------------------------------------------------------------------ */ 312/* ------------------------------------------------------------------ */
272 313
314static int philips_europa_pll_init(struct dvb_frontend *fe)
315{
316 struct saa7134_dev *dev = fe->dvb->priv;
317 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
318 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
319
320 /* setup PLL configuration */
321 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
322 return -EIO;
323 msleep(1);
324
325 /* switch the board to dvb mode */
326 init_msg.addr = 0x43;
327 init_msg.len = 0x02;
328 msg[0] = 0x00;
329 msg[1] = 0x40;
330 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
331 return -EIO;
332
333 return 0;
334}
335
336static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
337{
338 return philips_tda6651_pll_set(0x61, fe, params);
339}
340
341static void philips_europa_analog(struct dvb_frontend *fe)
342{
343 struct saa7134_dev *dev = fe->dvb->priv;
344 /* this message actually turns the tuner back to analog mode */
345 static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
346 struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
347
348 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
349 msleep(1);
350
351 /* switch the board to analog mode */
352 analog_msg.addr = 0x43;
353 analog_msg.len = 0x02;
354 msg[0] = 0x00;
355 msg[1] = 0x14;
356 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
357}
358
359static struct tda1004x_config philips_europa_config = {
360
361 .demod_address = 0x8,
362 .invert = 0,
363 .invert_oclk = 0,
364 .xtal_freq = TDA10046_XTAL_4M,
365 .agc_config = TDA10046_AGC_IFO_AUTO_POS,
366 .if_freq = TDA10046_FREQ_052,
367 .pll_init = philips_europa_pll_init,
368 .pll_set = philips_td1316_pll_set,
369 .pll_sleep = philips_europa_analog,
370 .request_firmware = NULL,
371};
372
373/* ------------------------------------------------------------------ */
273 374
274static int philips_fmd1216_pll_init(struct dvb_frontend *fe) 375static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
275{ 376{
@@ -382,7 +483,6 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
382 return 0; 483 return 0;
383} 484}
384 485
385#ifdef HAVE_TDA1004X
386static struct tda1004x_config medion_cardbus = { 486static struct tda1004x_config medion_cardbus = {
387 .demod_address = 0x08, 487 .demod_address = 0x08,
388 .invert = 1, 488 .invert = 1,
@@ -395,7 +495,6 @@ static struct tda1004x_config medion_cardbus = {
395 .pll_sleep = philips_fmd1216_analog, 495 .pll_sleep = philips_fmd1216_analog,
396 .request_firmware = NULL, 496 .request_firmware = NULL,
397}; 497};
398#endif
399 498
400/* ------------------------------------------------------------------ */ 499/* ------------------------------------------------------------------ */
401 500
@@ -452,7 +551,7 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
452 u8 tuner_buf[14]; 551 u8 tuner_buf[14];
453 552
454 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf, 553 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
455 .len = sizeof(tuner_buf) }; 554 .len = sizeof(tuner_buf) };
456 int i, tuner_freq, if_freq; 555 int i, tuner_freq, if_freq;
457 u32 N; 556 u32 N;
458 switch (params->u.ofdm.bandwidth) { 557 switch (params->u.ofdm.bandwidth) {
@@ -511,7 +610,7 @@ static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
511 struct saa7134_dev *dev = fe->dvb->priv; 610 struct saa7134_dev *dev = fe->dvb->priv;
512 static u8 tda827x_sleep[] = { 0x30, 0xd0}; 611 static u8 tda827x_sleep[] = { 0x30, 0xd0};
513 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, 612 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
514 .len = sizeof(tda827x_sleep) }; 613 .len = sizeof(tda827x_sleep) };
515 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 614 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
516} 615}
517 616
@@ -527,6 +626,202 @@ static struct tda1004x_config tda827x_lifeview_config = {
527 .pll_sleep = philips_tda827x_pll_sleep, 626 .pll_sleep = philips_tda827x_pll_sleep,
528 .request_firmware = NULL, 627 .request_firmware = NULL,
529}; 628};
629
630/* ------------------------------------------------------------------ */
631
632struct tda827xa_data {
633 u32 lomax;
634 u8 svco;
635 u8 spd;
636 u8 scr;
637 u8 sbs;
638 u8 gc3;
639};
640
641static struct tda827xa_data tda827xa_dvbt[] = {
642 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
643 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
644 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
645 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
646 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
647 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
648 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
649 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
650 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
651 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
652 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
653 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
654 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
655 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
656 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
657 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
658 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
659 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
660 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
661 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
662 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
663 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
664 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
665 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
666 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
667 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
668 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}};
669
670
671static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
672{
673 struct saa7134_dev *dev = fe->dvb->priv;
674 u8 tuner_buf[14];
675 unsigned char reg2[2];
676
677 struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf};
678 int i, tuner_freq, if_freq;
679 u32 N;
680
681 switch (params->u.ofdm.bandwidth) {
682 case BANDWIDTH_6_MHZ:
683 if_freq = 4000000;
684 break;
685 case BANDWIDTH_7_MHZ:
686 if_freq = 4500000;
687 break;
688 default: /* 8 MHz or Auto */
689 if_freq = 5000000;
690 break;
691 }
692 tuner_freq = params->frequency + if_freq;
693
694 i = 0;
695 while (tda827xa_dvbt[i].lomax < tuner_freq) {
696 if(tda827xa_dvbt[i + 1].lomax == 0)
697 break;
698 i++;
699 }
700
701 N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
702 tuner_buf[0] = 0; // subaddress
703 tuner_buf[1] = N >> 8;
704 tuner_buf[2] = N & 0xff;
705 tuner_buf[3] = 0;
706 tuner_buf[4] = 0x16;
707 tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
708 tda827xa_dvbt[i].sbs;
709 tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
710 tuner_buf[7] = 0x0c;
711 tuner_buf[8] = 0x06;
712 tuner_buf[9] = 0x24;
713 tuner_buf[10] = 0xff;
714 tuner_buf[11] = 0x60;
715 tuner_buf[12] = 0x00;
716 tuner_buf[13] = 0x39; // lpsel
717 msg.len = 14;
718 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
719 return -EIO;
720
721 msg.buf= reg2;
722 msg.len = 2;
723 reg2[0] = 0x60;
724 reg2[1] = 0x3c;
725 i2c_transfer(&dev->i2c_adap, &msg, 1);
726
727 reg2[0] = 0xa0;
728 reg2[1] = 0x40;
729 i2c_transfer(&dev->i2c_adap, &msg, 1);
730
731 msleep(2);
732 /* correct CP value */
733 reg2[0] = 0x30;
734 reg2[1] = 0x10 + tda827xa_dvbt[i].scr;
735 msg.len = 2;
736 i2c_transfer(&dev->i2c_adap, &msg, 1);
737
738 msleep(550);
739 reg2[0] = 0x50;
740 reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
741 i2c_transfer(&dev->i2c_adap, &msg, 1);
742
743 return 0;
744
745}
746
747static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe)
748{
749 struct saa7134_dev *dev = fe->dvb->priv;
750 static u8 tda827xa_sleep[] = { 0x30, 0x90};
751 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep,
752 .len = sizeof(tda827xa_sleep) };
753 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
754
755}
756
757/* ------------------------------------------------------------------ */
758
759static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
760{
761 int ret;
762 struct saa7134_dev *dev = fe->dvb->priv;
763 static u8 tda8290_close[] = { 0x21, 0xc0};
764 static u8 tda8290_open[] = { 0x21, 0x80};
765 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2};
766 /* close tda8290 i2c bridge */
767 tda8290_msg.buf = tda8290_close;
768 ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
769 if (ret != 1)
770 return -EIO;
771 msleep(20);
772 ret = philips_tda827xa_pll_set(0x61, fe, params);
773 if (ret != 0)
774 return ret;
775 /* open tda8290 i2c bridge */
776 tda8290_msg.buf = tda8290_open;
777 i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
778 return ret;
779};
780
781static int philips_tiger_dvb_mode(struct dvb_frontend *fe)
782{
783 struct saa7134_dev *dev = fe->dvb->priv;
784 static u8 data[] = { 0x3c, 0x33, 0x6a};
785 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
786
787 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
788 return -EIO;
789 return 0;
790}
791
792static void philips_tiger_analog_mode(struct dvb_frontend *fe)
793{
794 struct saa7134_dev *dev = fe->dvb->priv;
795 static u8 data[] = { 0x3c, 0x33, 0x68};
796 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
797
798 i2c_transfer(&dev->i2c_adap, &msg, 1);
799 philips_tda827xa_pll_sleep( 0x61, fe);
800}
801
802static struct tda1004x_config philips_tiger_config = {
803 .demod_address = 0x08,
804 .invert = 1,
805 .invert_oclk = 0,
806 .xtal_freq = TDA10046_XTAL_16M,
807 .agc_config = TDA10046_AGC_TDA827X,
808 .if_freq = TDA10046_FREQ_045,
809 .pll_init = philips_tiger_dvb_mode,
810 .pll_set = philips_tiger_pll_set,
811 .pll_sleep = philips_tiger_analog_mode,
812 .request_firmware = NULL,
813};
814
815#endif
816
817/* ------------------------------------------------------------------ */
818
819#ifdef HAVE_NXT200X
820static struct nxt200x_config avertvhda180 = {
821 .demod_address = 0x0a,
822 .pll_address = 0x61,
823 .pll_desc = &dvb_pll_tdhu2,
824};
530#endif 825#endif
531 826
532/* ------------------------------------------------------------------ */ 827/* ------------------------------------------------------------------ */
@@ -558,7 +853,7 @@ static int dvb_init(struct saa7134_dev *dev)
558 &dev->i2c_adap); 853 &dev->i2c_adap);
559 break; 854 break;
560 case SAA7134_BOARD_PHILIPS_TOUGH: 855 case SAA7134_BOARD_PHILIPS_TOUGH:
561 dev->dvb.frontend = tda10046_attach(&philips_tu1216_config, 856 dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
562 &dev->i2c_adap); 857 &dev->i2c_adap);
563 break; 858 break;
564 case SAA7134_BOARD_FLYDVBTDUO: 859 case SAA7134_BOARD_FLYDVBTDUO:
@@ -569,6 +864,31 @@ static int dvb_init(struct saa7134_dev *dev)
569 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, 864 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
570 &dev->i2c_adap); 865 &dev->i2c_adap);
571 break; 866 break;
867 case SAA7134_BOARD_PHILIPS_EUROPA:
868 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
869 &dev->i2c_adap);
870 break;
871 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
872 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
873 &dev->i2c_adap);
874 break;
875 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
876 dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
877 &dev->i2c_adap);
878 break;
879 case SAA7134_BOARD_PHILIPS_TIGER:
880 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
881 &dev->i2c_adap);
882 break;
883 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
884 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
885 &dev->i2c_adap);
886 break;
887#endif
888#ifdef HAVE_NXT200X
889 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
890 dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
891 break;
572#endif 892#endif
573 default: 893 default:
574 printk("%s: Huh? unknown DVB card?\n",dev->name); 894 printk("%s: Huh? unknown DVB card?\n",dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 77b627eb6483..e9ec69efb4c9 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -55,7 +55,7 @@ static void ts_reset_encoder(struct saa7134_dev* dev)
55 55
56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00); 56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
57 msleep(10); 57 msleep(10);
58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
59 msleep(100); 59 msleep(100);
60 dev->empress_started = 0; 60 dev->empress_started = 0;
61} 61}
@@ -65,7 +65,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
65 ts_reset_encoder(dev); 65 ts_reset_encoder(dev);
66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); 66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
67 dev->empress_started = 1; 67 dev->empress_started = 1;
68 return 0; 68 return 0;
69} 69}
70 70
71/* ------------------------------------------------------------------ */ 71/* ------------------------------------------------------------------ */
@@ -169,7 +169,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
169 struct v4l2_capability *cap = arg; 169 struct v4l2_capability *cap = arg;
170 170
171 memset(cap,0,sizeof(*cap)); 171 memset(cap,0,sizeof(*cap));
172 strcpy(cap->driver, "saa7134"); 172 strcpy(cap->driver, "saa7134");
173 strlcpy(cap->card, saa7134_boards[dev->board].name, 173 strlcpy(cap->card, saa7134_boards[dev->board].name,
174 sizeof(cap->card)); 174 sizeof(cap->card));
175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 711aa8e85fac..7575043f0874 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -239,7 +239,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
239 unsigned char data; 239 unsigned char data;
240 int addr,rc,i,byte; 240 int addr,rc,i,byte;
241 241
242 status = i2c_get_status(dev); 242 status = i2c_get_status(dev);
243 if (!i2c_is_idle(status)) 243 if (!i2c_is_idle(status))
244 if (!i2c_reset(dev)) 244 if (!i2c_reset(dev))
245 return -EIO; 245 return -EIO;
@@ -296,7 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
296 rc = -EIO; 296 rc = -EIO;
297 if (!i2c_is_busy_wait(dev)) 297 if (!i2c_is_busy_wait(dev))
298 goto err; 298 goto err;
299 status = i2c_get_status(dev); 299 status = i2c_get_status(dev);
300 if (i2c_is_error(status)) 300 if (i2c_is_error(status))
301 goto err; 301 goto err;
302 /* ensure that the bus is idle for at least one bit slot */ 302 /* ensure that the bus is idle for at least one bit slot */
@@ -335,6 +335,20 @@ static int attach_inform(struct i2c_client *client)
335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", 335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
336 client->driver->name, client->addr, client->name); 336 client->driver->name, client->addr, client->name);
337 337
338 /* Am I an i2c remote control? */
339
340 switch (client->addr) {
341 case 0x7a:
342 case 0x47:
343 {
344 struct IR_i2c *ir = i2c_get_clientdata(client);
345 d1printk("%s i2c IR detected (%s).\n",
346 client->driver->name,ir->phys);
347 saa7134_set_i2c_ir(dev,ir);
348 break;
349 }
350 }
351
338 if (!client->driver->command) 352 if (!client->driver->command)
339 return 0; 353 return 0;
340 354
@@ -348,12 +362,12 @@ static int attach_inform(struct i2c_client *client)
348 362
349 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup); 363 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
350 } 364 }
351 } 365 }
352 366
353 if (tuner != UNSET) { 367 if (tuner != UNSET) {
354 368
355 tun_setup.type = tuner; 369 tun_setup.type = tuner;
356 tun_setup.addr = saa7134_boards[dev->board].tuner_addr; 370 tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
357 371
358 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) { 372 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
359 373
@@ -361,11 +375,11 @@ static int attach_inform(struct i2c_client *client)
361 375
362 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup); 376 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
363 } 377 }
364 } 378 }
365 379
366 client->driver->command(client, TDA9887_SET_CONFIG, &conf); 380 client->driver->command(client, TDA9887_SET_CONFIG, &conf);
367 381
368 return 0; 382 return 0;
369} 383}
370 384
371static struct i2c_algorithm saa7134_algo = { 385static struct i2c_algorithm saa7134_algo = {
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 242cb235cf92..329accda6d45 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -39,6 +39,8 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39 39
40#define dprintk(fmt, arg...) if (ir_debug) \ 40#define dprintk(fmt, arg...) if (ir_debug) \
41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) 41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
42#define i2cdprintk(fmt, arg...) if (ir_debug) \
43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
42 44
43/* ---------------------------------------------------------------------- */ 45/* ---------------------------------------------------------------------- */
44 46
@@ -114,24 +116,24 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
114/* Alfons Geser <a.geser@cox.net> 116/* Alfons Geser <a.geser@cox.net>
115 * updates from Job D. R. Borges <jobdrb@ig.com.br> */ 117 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
116static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { 118static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
117 [ 18 ] = KEY_POWER, 119 [ 18 ] = KEY_POWER,
118 [ 1 ] = KEY_TV, // DVR 120 [ 1 ] = KEY_TV, // DVR
119 [ 21 ] = KEY_DVD, // DVD 121 [ 21 ] = KEY_DVD, // DVD
120 [ 23 ] = KEY_AUDIO, // music 122 [ 23 ] = KEY_AUDIO, // music
121 // DVR mode / DVD mode / music mode 123 // DVR mode / DVD mode / music mode
122 124
123 [ 27 ] = KEY_MUTE, // mute 125 [ 27 ] = KEY_MUTE, // mute
124 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek 126 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
125 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek 127 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
126 [ 22 ] = KEY_ZOOM, // full screen 128 [ 22 ] = KEY_ZOOM, // full screen
127 [ 28 ] = KEY_VIDEO, // video source / eject / delall 129 [ 28 ] = KEY_VIDEO, // video source / eject / delall
128 [ 29 ] = KEY_RESTART, // playback / angle / del 130 [ 29 ] = KEY_RESTART, // playback / angle / del
129 [ 47 ] = KEY_SEARCH, // scan / menu / playlist 131 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
130 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo 132 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
131 133
132 [ 49 ] = KEY_HELP, // help 134 [ 49 ] = KEY_HELP, // help
133 [ 50 ] = KEY_MODE, // num/memo 135 [ 50 ] = KEY_MODE, // num/memo
134 [ 51 ] = KEY_ESC, // cancel 136 [ 51 ] = KEY_ESC, // cancel
135 137
136 [ 12 ] = KEY_UP, // up 138 [ 12 ] = KEY_UP, // up
137 [ 16 ] = KEY_DOWN, // down 139 [ 16 ] = KEY_DOWN, // down
@@ -148,24 +150,24 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
148 [ 45 ] = KEY_PLAY, // play 150 [ 45 ] = KEY_PLAY, // play
149 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle 151 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
150 152
151 [ 0 ] = KEY_KP0, 153 [ 0 ] = KEY_KP0,
152 [ 5 ] = KEY_KP1, 154 [ 5 ] = KEY_KP1,
153 [ 6 ] = KEY_KP2, 155 [ 6 ] = KEY_KP2,
154 [ 7 ] = KEY_KP3, 156 [ 7 ] = KEY_KP3,
155 [ 9 ] = KEY_KP4, 157 [ 9 ] = KEY_KP4,
156 [ 10 ] = KEY_KP5, 158 [ 10 ] = KEY_KP5,
157 [ 11 ] = KEY_KP6, 159 [ 11 ] = KEY_KP6,
158 [ 13 ] = KEY_KP7, 160 [ 13 ] = KEY_KP7,
159 [ 14 ] = KEY_KP8, 161 [ 14 ] = KEY_KP8,
160 [ 15 ] = KEY_KP9, 162 [ 15 ] = KEY_KP9,
161 163
162 [ 42 ] = KEY_VOLUMEUP, 164 [ 42 ] = KEY_VOLUMEUP,
163 [ 17 ] = KEY_VOLUMEDOWN, 165 [ 17 ] = KEY_VOLUMEDOWN,
164 [ 24 ] = KEY_CHANNELUP, // CH.tracking up 166 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
165 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down 167 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
166 168
167 [ 19 ] = KEY_KPENTER, // enter 169 [ 19 ] = KEY_KPENTER, // enter
168 [ 33 ] = KEY_KPDOT, // . (decimal dot) 170 [ 33 ] = KEY_KPDOT, // . (decimal dot)
169}; 171};
170 172
171static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { 173static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
@@ -401,7 +403,183 @@ static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
401 403
402 // 0x1d unused ? 404 // 0x1d unused ?
403}; 405};
404/* ---------------------------------------------------------------------- */ 406
407
408/* Mike Baikov <mike@baikov.com> */
409static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
410
411 [ 33 ] = KEY_POWER,
412 [ 105] = KEY_TV,
413 [ 51 ] = KEY_KP0,
414 [ 81 ] = KEY_KP1,
415 [ 49 ] = KEY_KP2,
416 [ 113] = KEY_KP3,
417 [ 59 ] = KEY_KP4,
418 [ 88 ] = KEY_KP5,
419 [ 65 ] = KEY_KP6,
420 [ 72 ] = KEY_KP7,
421 [ 48 ] = KEY_KP8,
422 [ 83 ] = KEY_KP9,
423 [ 115] = KEY_AGAIN, /* LOOP */
424 [ 10 ] = KEY_AUDIO,
425 [ 97 ] = KEY_PRINT, /* PREVIEW */
426 [ 122] = KEY_VIDEO,
427 [ 32 ] = KEY_CHANNELUP,
428 [ 64 ] = KEY_CHANNELDOWN,
429 [ 24 ] = KEY_VOLUMEDOWN,
430 [ 80 ] = KEY_VOLUMEUP,
431 [ 16 ] = KEY_MUTE,
432 [ 74 ] = KEY_SEARCH,
433 [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
434 [ 34 ] = KEY_RECORD,
435 [ 98 ] = KEY_STOP,
436 [ 120] = KEY_PLAY,
437 [ 57 ] = KEY_REWIND,
438 [ 89 ] = KEY_PAUSE,
439 [ 25 ] = KEY_FORWARD,
440 [ 9 ] = KEY_ZOOM,
441
442 [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
443 [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
444 [ 58 ] = KEY_F23, /* TIMESHIFT */
445 [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
446};
447
448static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
449 [ 0x3 ] = KEY_POWER,
450 [ 0x6f ] = KEY_MUTE,
451 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
452
453 [ 0x11 ] = KEY_KP0,
454 [ 0x4 ] = KEY_KP1,
455 [ 0x5 ] = KEY_KP2,
456 [ 0x6 ] = KEY_KP3,
457 [ 0x8 ] = KEY_KP4,
458 [ 0x9 ] = KEY_KP5,
459 [ 0xa ] = KEY_KP6,
460 [ 0xc ] = KEY_KP7,
461 [ 0xd ] = KEY_KP8,
462 [ 0xe ] = KEY_KP9,
463 [ 0x12 ] = KEY_KPDOT, /* 100+ */
464
465 [ 0x7 ] = KEY_VOLUMEUP,
466 [ 0xb ] = KEY_VOLUMEDOWN,
467 [ 0x1a ] = KEY_KPPLUS,
468 [ 0x18 ] = KEY_KPMINUS,
469 [ 0x15 ] = KEY_UP,
470 [ 0x1d ] = KEY_DOWN,
471 [ 0xf ] = KEY_CHANNELUP,
472 [ 0x13 ] = KEY_CHANNELDOWN,
473 [ 0x48 ] = KEY_ZOOM,
474
475 [ 0x1b ] = KEY_VIDEO, /* Video source */
476 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
477 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
478
479 [ 0x4b ] = KEY_RECORD,
480 [ 0x46 ] = KEY_PLAY,
481 [ 0x45 ] = KEY_PAUSE, /* Pause */
482 [ 0x44 ] = KEY_STOP,
483 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
484 [ 0x42 ] = KEY_REWIND, /* Backward ? */
485
486};
487
488static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
489 [ 0x59 ] = KEY_MUTE,
490 [ 0x4a ] = KEY_POWER,
491
492 [ 0x18 ] = KEY_TEXT,
493 [ 0x26 ] = KEY_TV,
494 [ 0x3d ] = KEY_PRINT,
495
496 [ 0x48 ] = KEY_RED,
497 [ 0x04 ] = KEY_GREEN,
498 [ 0x11 ] = KEY_YELLOW,
499 [ 0x00 ] = KEY_BLUE,
500
501 [ 0x2d ] = KEY_VOLUMEUP,
502 [ 0x1e ] = KEY_VOLUMEDOWN,
503
504 [ 0x49 ] = KEY_MENU,
505
506 [ 0x16 ] = KEY_CHANNELUP,
507 [ 0x17 ] = KEY_CHANNELDOWN,
508
509 [ 0x20 ] = KEY_UP,
510 [ 0x21 ] = KEY_DOWN,
511 [ 0x22 ] = KEY_LEFT,
512 [ 0x23 ] = KEY_RIGHT,
513 [ 0x0d ] = KEY_SELECT,
514
515
516
517 [ 0x08 ] = KEY_BACK,
518 [ 0x07 ] = KEY_REFRESH,
519
520 [ 0x2f ] = KEY_ZOOM,
521 [ 0x29 ] = KEY_RECORD,
522
523 [ 0x4b ] = KEY_PAUSE,
524 [ 0x4d ] = KEY_REWIND,
525 [ 0x2e ] = KEY_PLAY,
526 [ 0x4e ] = KEY_FORWARD,
527 [ 0x53 ] = KEY_PREVIOUS,
528 [ 0x4c ] = KEY_STOP,
529 [ 0x54 ] = KEY_NEXT,
530
531 [ 0x69 ] = KEY_KP0,
532 [ 0x6a ] = KEY_KP1,
533 [ 0x6b ] = KEY_KP2,
534 [ 0x6c ] = KEY_KP3,
535 [ 0x6d ] = KEY_KP4,
536 [ 0x6e ] = KEY_KP5,
537 [ 0x6f ] = KEY_KP6,
538 [ 0x70 ] = KEY_KP7,
539 [ 0x71 ] = KEY_KP8,
540 [ 0x72 ] = KEY_KP9,
541
542 [ 0x74 ] = KEY_CHANNEL,
543 [ 0x0a ] = KEY_BACKSPACE,
544};
545
546/* Mapping for the 28 key remote control as seen at
547 http://www.sednacomputer.com/photo/cardbus-tv.jpg
548 Pavel Mihaylov <bin@bash.info> */
549static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
550 [ 0 ] = KEY_KP0,
551 [ 1 ] = KEY_KP1,
552 [ 2 ] = KEY_KP2,
553 [ 3 ] = KEY_KP3,
554 [ 4 ] = KEY_KP4,
555 [ 5 ] = KEY_KP5,
556 [ 6 ] = KEY_KP6,
557 [ 7 ] = KEY_KP7,
558 [ 8 ] = KEY_KP8,
559 [ 9 ] = KEY_KP9,
560
561 [ 0x0a ] = KEY_AGAIN, /* Recall */
562 [ 0x0b ] = KEY_CHANNELUP,
563 [ 0x0c ] = KEY_VOLUMEUP,
564 [ 0x0d ] = KEY_MODE, /* Stereo */
565 [ 0x0e ] = KEY_STOP,
566 [ 0x0f ] = KEY_PREVIOUSSONG,
567 [ 0x10 ] = KEY_ZOOM,
568 [ 0x11 ] = KEY_TUNER, /* Source */
569 [ 0x12 ] = KEY_POWER,
570 [ 0x13 ] = KEY_MUTE,
571 [ 0x15 ] = KEY_CHANNELDOWN,
572 [ 0x18 ] = KEY_VOLUMEDOWN,
573 [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */
574 [ 0x1a ] = KEY_NEXTSONG,
575 [ 0x1b ] = KEY_TEXT, /* Time Shift */
576 [ 0x1c ] = KEY_RADIO, /* FM Radio */
577 [ 0x1d ] = KEY_RECORD,
578 [ 0x1e ] = KEY_PAUSE,
579};
580
581
582/* -------------------- GPIO generic keycode builder -------------------- */
405 583
406static int build_key(struct saa7134_dev *dev) 584static int build_key(struct saa7134_dev *dev)
407{ 585{
@@ -413,13 +591,13 @@ static int build_key(struct saa7134_dev *dev)
413 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); 591 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
414 592
415 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); 593 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
416 if (ir->polling) { 594 if (ir->polling) {
417 if (ir->last_gpio == gpio) 595 if (ir->last_gpio == gpio)
418 return 0; 596 return 0;
419 ir->last_gpio = gpio; 597 ir->last_gpio = gpio;
420 } 598 }
421 599
422 data = ir_extract_bits(gpio, ir->mask_keycode); 600 data = ir_extract_bits(gpio, ir->mask_keycode);
423 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", 601 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
424 gpio, ir->mask_keycode, data); 602 gpio, ir->mask_keycode, data);
425 603
@@ -432,13 +610,87 @@ static int build_key(struct saa7134_dev *dev)
432 return 0; 610 return 0;
433} 611}
434 612
435/* ---------------------------------------------------------------------- */ 613/* --------------------- Chip specific I2C key builders ----------------- */
614
615static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
616{
617 unsigned char b;
618
619 /* poll IR chip */
620 if (1 != i2c_master_recv(&ir->c,&b,1)) {
621 i2cdprintk("read error\n");
622 return -EIO;
623 }
624
625 /* no button press */
626 if (b==0)
627 return 0;
628
629 /* repeating */
630 if (b & 0x80)
631 return 1;
632
633 *ir_key = b;
634 *ir_raw = b;
635 return 1;
636}
637
638/* The new pinnacle PCTV remote (with the colored buttons)
639 *
640 * Ricardo Cerqueira <v4l@cerqueira.org>
641 */
642
643static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
644{
645 unsigned char b[4];
646 unsigned int start = 0,parity = 0,code = 0;
647
648 /* poll IR chip */
649 if (4 != i2c_master_recv(&ir->c,b,4)) {
650 i2cdprintk("read error\n");
651 return -EIO;
652 }
653
654 for (start = 0; start<4; start++) {
655 if (b[start] == 0x80) {
656 code=b[(start+3)%4];
657 parity=b[(start+2)%4];
658 }
659 }
660
661 /* Empty Request */
662 if (parity==0)
663 return 0;
664
665 /* Repeating... */
666 if (ir->old == parity)
667 return 0;
668
669
670 ir->old = parity;
671
672 /* Reduce code value to fit inside IR_KEYTAB_SIZE
673 *
674 * this is the only value that results in 42 unique
675 * codes < 128
676 */
677
678 code %= 0x88;
679
680 *ir_raw = code;
681 *ir_key = code;
682
683 i2cdprintk("Pinnacle PCTV key %02x\n", code);
684
685 return 1;
686}
687
436 688
437void saa7134_input_irq(struct saa7134_dev *dev) 689void saa7134_input_irq(struct saa7134_dev *dev)
438{ 690{
439 struct saa7134_ir *ir = dev->remote; 691 struct saa7134_ir *ir = dev->remote;
440 692
441 if (!ir->polling) 693 if (!ir->polling)
442 build_key(dev); 694 build_key(dev);
443} 695}
444 696
@@ -464,7 +716,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
464 int polling = 0; 716 int polling = 0;
465 int ir_type = IR_TYPE_OTHER; 717 int ir_type = IR_TYPE_OTHER;
466 718
467 if (!dev->has_remote) 719 if (dev->has_remote != SAA7134_REMOTE_GPIO)
468 return -ENODEV; 720 return -ENODEV;
469 if (disable_ir) 721 if (disable_ir)
470 return -ENODEV; 722 return -ENODEV;
@@ -473,7 +725,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
473 switch (dev->board) { 725 switch (dev->board) {
474 case SAA7134_BOARD_FLYVIDEO2000: 726 case SAA7134_BOARD_FLYVIDEO2000:
475 case SAA7134_BOARD_FLYVIDEO3000: 727 case SAA7134_BOARD_FLYVIDEO3000:
476 case SAA7134_BOARD_FLYTVPLATINUM_FM: 728 case SAA7134_BOARD_FLYTVPLATINUM_FM:
729 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
477 ir_codes = flyvideo_codes; 730 ir_codes = flyvideo_codes;
478 mask_keycode = 0xEC00000; 731 mask_keycode = 0xEC00000;
479 mask_keydown = 0x0040000; 732 mask_keydown = 0x0040000;
@@ -514,14 +767,33 @@ int saa7134_input_init1(struct saa7134_dev *dev)
514 saa_setb(SAA7134_GPIO_GPMODE0, 0x4); 767 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
515 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 768 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
516 break; 769 break;
770 case SAA7134_BOARD_KWORLD_TERMINATOR:
771 ir_codes = avacssmart_codes;
772 mask_keycode = 0x00001f;
773 mask_keyup = 0x000060;
774 polling = 50; // ms
775 break;
517 case SAA7134_BOARD_MANLI_MTV001: 776 case SAA7134_BOARD_MANLI_MTV001:
518 case SAA7134_BOARD_MANLI_MTV002: 777 case SAA7134_BOARD_MANLI_MTV002:
778 case SAA7134_BOARD_BEHOLD_409FM:
519 ir_codes = manli_codes; 779 ir_codes = manli_codes;
520 mask_keycode = 0x001f00; 780 mask_keycode = 0x001f00;
521 mask_keyup = 0x004000; 781 mask_keyup = 0x004000;
522 mask_keydown = 0x002000;
523 polling = 50; // ms 782 polling = 50; // ms
524 break; 783 break;
784 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
785 ir_codes = pctv_sedna_codes;
786 mask_keycode = 0x001f00;
787 mask_keyup = 0x004000;
788 polling = 50; // ms
789 break;
790 case SAA7134_BOARD_GOTVIEW_7135:
791 ir_codes = gotview7135_codes;
792 mask_keycode = 0x0003EC;
793 mask_keyup = 0x008000;
794 mask_keydown = 0x000010;
795 polling = 50; // ms
796 break;
525 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 797 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
526 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 798 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
527 ir_codes = videomate_tv_pvr_codes; 799 ir_codes = videomate_tv_pvr_codes;
@@ -529,6 +801,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
529 mask_keyup = 0x400000; 801 mask_keyup = 0x400000;
530 polling = 50; // ms 802 polling = 50; // ms
531 break; 803 break;
804 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
805 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
806 ir_codes = videomate_tv_pvr_codes;
807 mask_keycode = 0x003F00;
808 mask_keyup = 0x040000;
809 break;
532 } 810 }
533 if (NULL == ir_codes) { 811 if (NULL == ir_codes) {
534 printk("%s: Oops: IR config error [card=%d]\n", 812 printk("%s: Oops: IR config error [card=%d]\n",
@@ -548,7 +826,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
548 ir->mask_keycode = mask_keycode; 826 ir->mask_keycode = mask_keycode;
549 ir->mask_keydown = mask_keydown; 827 ir->mask_keydown = mask_keydown;
550 ir->mask_keyup = mask_keyup; 828 ir->mask_keyup = mask_keyup;
551 ir->polling = polling; 829 ir->polling = polling;
552 830
553 /* init input device */ 831 /* init input device */
554 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", 832 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -596,6 +874,31 @@ void saa7134_input_fini(struct saa7134_dev *dev)
596 dev->remote = NULL; 874 dev->remote = NULL;
597} 875}
598 876
877void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
878{
879 if (disable_ir) {
880 dprintk("Found supported i2c remote, but IR has been disabled\n");
881 ir->get_key=NULL;
882 return;
883 }
884
885 switch (dev->board) {
886 case SAA7134_BOARD_PINNACLE_PCTV_110i:
887 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
888 ir->get_key = get_key_pinnacle;
889 ir->ir_codes = ir_codes_pinnacle;
890 break;
891 case SAA7134_BOARD_UPMOST_PURPLE_TV:
892 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
893 ir->get_key = get_key_purpletv;
894 ir->ir_codes = ir_codes_purpletv;
895 break;
896 default:
897 dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
898 break;
899 }
900
901}
599/* ---------------------------------------------------------------------- 902/* ----------------------------------------------------------------------
600 * Local variables: 903 * Local variables:
601 * c-basic-offset: 8 904 * c-basic-offset: 8
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index c20630c82f1c..fd53dfcc1644 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44#define dprintk(fmt, arg...) if (oss_debug) \ 44#define dprintk(fmt, arg...) if (oss_debug) \
45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) 45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
46 46
47
47/* ------------------------------------------------------------------ */ 48/* ------------------------------------------------------------------ */
48 49
49static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) 50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
@@ -58,12 +59,12 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
58 if ((blksize * blocks) > 1024*1024) 59 if ((blksize * blocks) > 1024*1024)
59 blocks = 1024*1024 / blksize; 60 blocks = 1024*1024 / blksize;
60 61
61 dev->oss.blocks = blocks; 62 dev->dmasound.blocks = blocks;
62 dev->oss.blksize = blksize; 63 dev->dmasound.blksize = blksize;
63 dev->oss.bufsize = blksize * blocks; 64 dev->dmasound.bufsize = blksize * blocks;
64 65
65 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", 66 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
66 blocks,blksize,blksize * blocks / 1024); 67 blocks,blksize,blksize * blocks / 1024);
67 return 0; 68 return 0;
68} 69}
69 70
@@ -71,11 +72,11 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
71{ 72{
72 int err; 73 int err;
73 74
74 if (!dev->oss.bufsize) 75 if (!dev->dmasound.bufsize)
75 BUG(); 76 BUG();
76 videobuf_dma_init(&dev->oss.dma); 77 videobuf_dma_init(&dev->dmasound.dma);
77 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, 78 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
78 (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT); 79 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
79 if (0 != err) 80 if (0 != err)
80 return err; 81 return err;
81 return 0; 82 return 0;
@@ -83,26 +84,26 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
83 84
84static int dsp_buffer_free(struct saa7134_dev *dev) 85static int dsp_buffer_free(struct saa7134_dev *dev)
85{ 86{
86 if (!dev->oss.blksize) 87 if (!dev->dmasound.blksize)
87 BUG(); 88 BUG();
88 videobuf_dma_free(&dev->oss.dma); 89 videobuf_dma_free(&dev->dmasound.dma);
89 dev->oss.blocks = 0; 90 dev->dmasound.blocks = 0;
90 dev->oss.blksize = 0; 91 dev->dmasound.blksize = 0;
91 dev->oss.bufsize = 0; 92 dev->dmasound.bufsize = 0;
92 return 0; 93 return 0;
93} 94}
94 95
95static void dsp_dma_start(struct saa7134_dev *dev) 96static void dsp_dma_start(struct saa7134_dev *dev)
96{ 97{
97 dev->oss.dma_blk = 0; 98 dev->dmasound.dma_blk = 0;
98 dev->oss.dma_running = 1; 99 dev->dmasound.dma_running = 1;
99 saa7134_set_dmabits(dev); 100 saa7134_set_dmabits(dev);
100} 101}
101 102
102static void dsp_dma_stop(struct saa7134_dev *dev) 103static void dsp_dma_stop(struct saa7134_dev *dev)
103{ 104{
104 dev->oss.dma_blk = -1; 105 dev->dmasound.dma_blk = -1;
105 dev->oss.dma_running = 0; 106 dev->dmasound.dma_running = 0;
106 saa7134_set_dmabits(dev); 107 saa7134_set_dmabits(dev);
107} 108}
108 109
@@ -113,18 +114,18 @@ static int dsp_rec_start(struct saa7134_dev *dev)
113 unsigned long flags; 114 unsigned long flags;
114 115
115 /* prepare buffer */ 116 /* prepare buffer */
116 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma))) 117 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
117 return err; 118 return err;
118 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt))) 119 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
119 goto fail1; 120 goto fail1;
120 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt, 121 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
121 dev->oss.dma.sglist, 122 dev->dmasound.dma.sglist,
122 dev->oss.dma.sglen, 123 dev->dmasound.dma.sglen,
123 0))) 124 0)))
124 goto fail2; 125 goto fail2;
125 126
126 /* sample format */ 127 /* sample format */
127 switch (dev->oss.afmt) { 128 switch (dev->dmasound.afmt) {
128 case AFMT_U8: 129 case AFMT_U8:
129 case AFMT_S8: fmt = 0x00; break; 130 case AFMT_S8: fmt = 0x00; break;
130 case AFMT_U16_LE: 131 case AFMT_U16_LE:
@@ -136,14 +137,14 @@ static int dsp_rec_start(struct saa7134_dev *dev)
136 goto fail2; 137 goto fail2;
137 } 138 }
138 139
139 switch (dev->oss.afmt) { 140 switch (dev->dmasound.afmt) {
140 case AFMT_S8: 141 case AFMT_S8:
141 case AFMT_S16_LE: 142 case AFMT_S16_LE:
142 case AFMT_S16_BE: sign = 1; break; 143 case AFMT_S16_BE: sign = 1; break;
143 default: sign = 0; break; 144 default: sign = 0; break;
144 } 145 }
145 146
146 switch (dev->oss.afmt) { 147 switch (dev->dmasound.afmt) {
147 case AFMT_U16_BE: 148 case AFMT_U16_BE:
148 case AFMT_S16_BE: bswap = 1; break; 149 case AFMT_S16_BE: bswap = 1; break;
149 default: bswap = 0; break; 150 default: bswap = 0; break;
@@ -151,58 +152,58 @@ static int dsp_rec_start(struct saa7134_dev *dev)
151 152
152 switch (dev->pci->device) { 153 switch (dev->pci->device) {
153 case PCI_DEVICE_ID_PHILIPS_SAA7134: 154 case PCI_DEVICE_ID_PHILIPS_SAA7134:
154 if (1 == dev->oss.channels) 155 if (1 == dev->dmasound.channels)
155 fmt |= (1 << 3); 156 fmt |= (1 << 3);
156 if (2 == dev->oss.channels) 157 if (2 == dev->dmasound.channels)
157 fmt |= (3 << 3); 158 fmt |= (3 << 3);
158 if (sign) 159 if (sign)
159 fmt |= 0x04; 160 fmt |= 0x04;
160 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; 161 fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80;
161 162
162 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff)); 163 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
163 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8); 164 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
164 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16); 165 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
165 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); 166 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
166 167
167 break; 168 break;
168 case PCI_DEVICE_ID_PHILIPS_SAA7133: 169 case PCI_DEVICE_ID_PHILIPS_SAA7133:
169 case PCI_DEVICE_ID_PHILIPS_SAA7135: 170 case PCI_DEVICE_ID_PHILIPS_SAA7135:
170 if (1 == dev->oss.channels) 171 if (1 == dev->dmasound.channels)
171 fmt |= (1 << 4); 172 fmt |= (1 << 4);
172 if (2 == dev->oss.channels) 173 if (2 == dev->dmasound.channels)
173 fmt |= (2 << 4); 174 fmt |= (2 << 4);
174 if (!sign) 175 if (!sign)
175 fmt |= 0x04; 176 fmt |= 0x04;
176 saa_writel(0x588 >> 2, dev->oss.blksize -4); 177 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4);
177 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24)); 178 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
178 break; 179 break;
179 } 180 }
180 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", 181 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
181 dev->oss.afmt, dev->oss.channels, fmt, 182 dev->dmasound.afmt, dev->dmasound.channels, fmt,
182 bswap ? 'b' : '-'); 183 bswap ? 'b' : '-');
183 184
184 /* dma: setup channel 6 (= AUDIO) */ 185 /* dma: setup channel 6 (= AUDIO) */
185 control = SAA7134_RS_CONTROL_BURST_16 | 186 control = SAA7134_RS_CONTROL_BURST_16 |
186 SAA7134_RS_CONTROL_ME | 187 SAA7134_RS_CONTROL_ME |
187 (dev->oss.pt.dma >> 12); 188 (dev->dmasound.pt.dma >> 12);
188 if (bswap) 189 if (bswap)
189 control |= SAA7134_RS_CONTROL_BSWAP; 190 control |= SAA7134_RS_CONTROL_BSWAP;
190 saa_writel(SAA7134_RS_BA1(6),0); 191 saa_writel(SAA7134_RS_BA1(6),0);
191 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize); 192 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
192 saa_writel(SAA7134_RS_PITCH(6),0); 193 saa_writel(SAA7134_RS_PITCH(6),0);
193 saa_writel(SAA7134_RS_CONTROL(6),control); 194 saa_writel(SAA7134_RS_CONTROL(6),control);
194 195
195 /* start dma */ 196 /* start dma */
196 dev->oss.recording_on = 1; 197 dev->dmasound.recording_on = 1;
197 spin_lock_irqsave(&dev->slock,flags); 198 spin_lock_irqsave(&dev->slock,flags);
198 dsp_dma_start(dev); 199 dsp_dma_start(dev);
199 spin_unlock_irqrestore(&dev->slock,flags); 200 spin_unlock_irqrestore(&dev->slock,flags);
200 return 0; 201 return 0;
201 202
202 fail2: 203 fail2:
203 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 204 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
204 fail1: 205 fail1:
205 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 206 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
206 return err; 207 return err;
207} 208}
208 209
@@ -210,17 +211,17 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
210{ 211{
211 unsigned long flags; 212 unsigned long flags;
212 213
213 dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk); 214 dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk);
214 215
215 /* stop dma */ 216 /* stop dma */
216 dev->oss.recording_on = 0; 217 dev->dmasound.recording_on = 0;
217 spin_lock_irqsave(&dev->slock,flags); 218 spin_lock_irqsave(&dev->slock,flags);
218 dsp_dma_stop(dev); 219 dsp_dma_stop(dev);
219 spin_unlock_irqrestore(&dev->slock,flags); 220 spin_unlock_irqrestore(&dev->slock,flags);
220 221
221 /* unlock buffer */ 222 /* unlock buffer */
222 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 223 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
223 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 224 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
224 return 0; 225 return 0;
225} 226}
226 227
@@ -235,35 +236,35 @@ static int dsp_open(struct inode *inode, struct file *file)
235 236
236 list_for_each(list,&saa7134_devlist) { 237 list_for_each(list,&saa7134_devlist) {
237 h = list_entry(list, struct saa7134_dev, devlist); 238 h = list_entry(list, struct saa7134_dev, devlist);
238 if (h->oss.minor_dsp == minor) 239 if (h->dmasound.minor_dsp == minor)
239 dev = h; 240 dev = h;
240 } 241 }
241 if (NULL == dev) 242 if (NULL == dev)
242 return -ENODEV; 243 return -ENODEV;
243 244
244 down(&dev->oss.lock); 245 down(&dev->dmasound.lock);
245 err = -EBUSY; 246 err = -EBUSY;
246 if (dev->oss.users_dsp) 247 if (dev->dmasound.users_dsp)
247 goto fail1; 248 goto fail1;
248 dev->oss.users_dsp++; 249 dev->dmasound.users_dsp++;
249 file->private_data = dev; 250 file->private_data = dev;
250 251
251 dev->oss.afmt = AFMT_U8; 252 dev->dmasound.afmt = AFMT_U8;
252 dev->oss.channels = 1; 253 dev->dmasound.channels = 1;
253 dev->oss.read_count = 0; 254 dev->dmasound.read_count = 0;
254 dev->oss.read_offset = 0; 255 dev->dmasound.read_offset = 0;
255 dsp_buffer_conf(dev,PAGE_SIZE,64); 256 dsp_buffer_conf(dev,PAGE_SIZE,64);
256 err = dsp_buffer_init(dev); 257 err = dsp_buffer_init(dev);
257 if (0 != err) 258 if (0 != err)
258 goto fail2; 259 goto fail2;
259 260
260 up(&dev->oss.lock); 261 up(&dev->dmasound.lock);
261 return 0; 262 return 0;
262 263
263 fail2: 264 fail2:
264 dev->oss.users_dsp--; 265 dev->dmasound.users_dsp--;
265 fail1: 266 fail1:
266 up(&dev->oss.lock); 267 up(&dev->dmasound.lock);
267 return err; 268 return err;
268} 269}
269 270
@@ -271,13 +272,13 @@ static int dsp_release(struct inode *inode, struct file *file)
271{ 272{
272 struct saa7134_dev *dev = file->private_data; 273 struct saa7134_dev *dev = file->private_data;
273 274
274 down(&dev->oss.lock); 275 down(&dev->dmasound.lock);
275 if (dev->oss.recording_on) 276 if (dev->dmasound.recording_on)
276 dsp_rec_stop(dev); 277 dsp_rec_stop(dev);
277 dsp_buffer_free(dev); 278 dsp_buffer_free(dev);
278 dev->oss.users_dsp--; 279 dev->dmasound.users_dsp--;
279 file->private_data = NULL; 280 file->private_data = NULL;
280 up(&dev->oss.lock); 281 up(&dev->dmasound.lock);
281 return 0; 282 return 0;
282} 283}
283 284
@@ -290,12 +291,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
290 unsigned long flags; 291 unsigned long flags;
291 int err,ret = 0; 292 int err,ret = 0;
292 293
293 add_wait_queue(&dev->oss.wq, &wait); 294 add_wait_queue(&dev->dmasound.wq, &wait);
294 down(&dev->oss.lock); 295 down(&dev->dmasound.lock);
295 while (count > 0) { 296 while (count > 0) {
296 /* wait for data if needed */ 297 /* wait for data if needed */
297 if (0 == dev->oss.read_count) { 298 if (0 == dev->dmasound.read_count) {
298 if (!dev->oss.recording_on) { 299 if (!dev->dmasound.recording_on) {
299 err = dsp_rec_start(dev); 300 err = dsp_rec_start(dev);
300 if (err < 0) { 301 if (err < 0) {
301 if (0 == ret) 302 if (0 == ret)
@@ -303,8 +304,8 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
303 break; 304 break;
304 } 305 }
305 } 306 }
306 if (dev->oss.recording_on && 307 if (dev->dmasound.recording_on &&
307 !dev->oss.dma_running) { 308 !dev->dmasound.dma_running) {
308 /* recover from overruns */ 309 /* recover from overruns */
309 spin_lock_irqsave(&dev->slock,flags); 310 spin_lock_irqsave(&dev->slock,flags);
310 dsp_dma_start(dev); 311 dsp_dma_start(dev);
@@ -315,12 +316,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
315 ret = -EAGAIN; 316 ret = -EAGAIN;
316 break; 317 break;
317 } 318 }
318 up(&dev->oss.lock); 319 up(&dev->dmasound.lock);
319 set_current_state(TASK_INTERRUPTIBLE); 320 set_current_state(TASK_INTERRUPTIBLE);
320 if (0 == dev->oss.read_count) 321 if (0 == dev->dmasound.read_count)
321 schedule(); 322 schedule();
322 set_current_state(TASK_RUNNING); 323 set_current_state(TASK_RUNNING);
323 down(&dev->oss.lock); 324 down(&dev->dmasound.lock);
324 if (signal_pending(current)) { 325 if (signal_pending(current)) {
325 if (0 == ret) 326 if (0 == ret)
326 ret = -EINTR; 327 ret = -EINTR;
@@ -330,12 +331,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
330 331
331 /* copy data to userspace */ 332 /* copy data to userspace */
332 bytes = count; 333 bytes = count;
333 if (bytes > dev->oss.read_count) 334 if (bytes > dev->dmasound.read_count)
334 bytes = dev->oss.read_count; 335 bytes = dev->dmasound.read_count;
335 if (bytes > dev->oss.bufsize - dev->oss.read_offset) 336 if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset)
336 bytes = dev->oss.bufsize - dev->oss.read_offset; 337 bytes = dev->dmasound.bufsize - dev->dmasound.read_offset;
337 if (copy_to_user(buffer + ret, 338 if (copy_to_user(buffer + ret,
338 dev->oss.dma.vmalloc + dev->oss.read_offset, 339 dev->dmasound.dma.vmalloc + dev->dmasound.read_offset,
339 bytes)) { 340 bytes)) {
340 if (0 == ret) 341 if (0 == ret)
341 ret = -EFAULT; 342 ret = -EFAULT;
@@ -344,13 +345,13 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
344 345
345 ret += bytes; 346 ret += bytes;
346 count -= bytes; 347 count -= bytes;
347 dev->oss.read_count -= bytes; 348 dev->dmasound.read_count -= bytes;
348 dev->oss.read_offset += bytes; 349 dev->dmasound.read_offset += bytes;
349 if (dev->oss.read_offset == dev->oss.bufsize) 350 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
350 dev->oss.read_offset = 0; 351 dev->dmasound.read_offset = 0;
351 } 352 }
352 up(&dev->oss.lock); 353 up(&dev->dmasound.lock);
353 remove_wait_queue(&dev->oss.wq, &wait); 354 remove_wait_queue(&dev->dmasound.wq, &wait);
354 return ret; 355 return ret;
355} 356}
356 357
@@ -370,53 +371,53 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
370 371
371 if (oss_debug > 1) 372 if (oss_debug > 1)
372 saa7134_print_ioctl(dev->name,cmd); 373 saa7134_print_ioctl(dev->name,cmd);
373 switch (cmd) { 374 switch (cmd) {
374 case OSS_GETVERSION: 375 case OSS_GETVERSION:
375 return put_user(SOUND_VERSION, p); 376 return put_user(SOUND_VERSION, p);
376 case SNDCTL_DSP_GETCAPS: 377 case SNDCTL_DSP_GETCAPS:
377 return 0; 378 return 0;
378 379
379 case SNDCTL_DSP_SPEED: 380 case SNDCTL_DSP_SPEED:
380 if (get_user(val, p)) 381 if (get_user(val, p))
381 return -EFAULT; 382 return -EFAULT;
382 /* fall through */ 383 /* fall through */
383 case SOUND_PCM_READ_RATE: 384 case SOUND_PCM_READ_RATE:
384 return put_user(dev->oss.rate, p); 385 return put_user(dev->dmasound.rate, p);
385 386
386 case SNDCTL_DSP_STEREO: 387 case SNDCTL_DSP_STEREO:
387 if (get_user(val, p)) 388 if (get_user(val, p))
388 return -EFAULT; 389 return -EFAULT;
389 down(&dev->oss.lock); 390 down(&dev->dmasound.lock);
390 dev->oss.channels = val ? 2 : 1; 391 dev->dmasound.channels = val ? 2 : 1;
391 if (dev->oss.recording_on) { 392 if (dev->dmasound.recording_on) {
392 dsp_rec_stop(dev); 393 dsp_rec_stop(dev);
393 dsp_rec_start(dev); 394 dsp_rec_start(dev);
394 } 395 }
395 up(&dev->oss.lock); 396 up(&dev->dmasound.lock);
396 return put_user(dev->oss.channels-1, p); 397 return put_user(dev->dmasound.channels-1, p);
397 398
398 case SNDCTL_DSP_CHANNELS: 399 case SNDCTL_DSP_CHANNELS:
399 if (get_user(val, p)) 400 if (get_user(val, p))
400 return -EFAULT; 401 return -EFAULT;
401 if (val != 1 && val != 2) 402 if (val != 1 && val != 2)
402 return -EINVAL; 403 return -EINVAL;
403 down(&dev->oss.lock); 404 down(&dev->dmasound.lock);
404 dev->oss.channels = val; 405 dev->dmasound.channels = val;
405 if (dev->oss.recording_on) { 406 if (dev->dmasound.recording_on) {
406 dsp_rec_stop(dev); 407 dsp_rec_stop(dev);
407 dsp_rec_start(dev); 408 dsp_rec_start(dev);
408 } 409 }
409 up(&dev->oss.lock); 410 up(&dev->dmasound.lock);
410 /* fall through */ 411 /* fall through */
411 case SOUND_PCM_READ_CHANNELS: 412 case SOUND_PCM_READ_CHANNELS:
412 return put_user(dev->oss.channels, p); 413 return put_user(dev->dmasound.channels, p);
413 414
414 case SNDCTL_DSP_GETFMTS: /* Returns a mask */ 415 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
415 return put_user(AFMT_U8 | AFMT_S8 | 416 return put_user(AFMT_U8 | AFMT_S8 |
416 AFMT_U16_LE | AFMT_U16_BE | 417 AFMT_U16_LE | AFMT_U16_BE |
417 AFMT_S16_LE | AFMT_S16_BE, p); 418 AFMT_S16_LE | AFMT_S16_BE, p);
418 419
419 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ 420 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
420 if (get_user(val, p)) 421 if (get_user(val, p))
421 return -EFAULT; 422 return -EFAULT;
422 switch (val) { 423 switch (val) {
@@ -429,20 +430,20 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
429 case AFMT_U16_BE: 430 case AFMT_U16_BE:
430 case AFMT_S16_LE: 431 case AFMT_S16_LE:
431 case AFMT_S16_BE: 432 case AFMT_S16_BE:
432 down(&dev->oss.lock); 433 down(&dev->dmasound.lock);
433 dev->oss.afmt = val; 434 dev->dmasound.afmt = val;
434 if (dev->oss.recording_on) { 435 if (dev->dmasound.recording_on) {
435 dsp_rec_stop(dev); 436 dsp_rec_stop(dev);
436 dsp_rec_start(dev); 437 dsp_rec_start(dev);
437 } 438 }
438 up(&dev->oss.lock); 439 up(&dev->dmasound.lock);
439 return put_user(dev->oss.afmt, p); 440 return put_user(dev->dmasound.afmt, p);
440 default: 441 default:
441 return -EINVAL; 442 return -EINVAL;
442 } 443 }
443 444
444 case SOUND_PCM_READ_BITS: 445 case SOUND_PCM_READ_BITS:
445 switch (dev->oss.afmt) { 446 switch (dev->dmasound.afmt) {
446 case AFMT_U8: 447 case AFMT_U8:
447 case AFMT_S8: 448 case AFMT_S8:
448 return put_user(8, p); 449 return put_user(8, p);
@@ -455,23 +456,23 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
455 return -EINVAL; 456 return -EINVAL;
456 } 457 }
457 458
458 case SNDCTL_DSP_NONBLOCK: 459 case SNDCTL_DSP_NONBLOCK:
459 file->f_flags |= O_NONBLOCK; 460 file->f_flags |= O_NONBLOCK;
460 return 0; 461 return 0;
461 462
462 case SNDCTL_DSP_RESET: 463 case SNDCTL_DSP_RESET:
463 down(&dev->oss.lock); 464 down(&dev->dmasound.lock);
464 if (dev->oss.recording_on) 465 if (dev->dmasound.recording_on)
465 dsp_rec_stop(dev); 466 dsp_rec_stop(dev);
466 up(&dev->oss.lock); 467 up(&dev->dmasound.lock);
467 return 0; 468 return 0;
468 case SNDCTL_DSP_GETBLKSIZE: 469 case SNDCTL_DSP_GETBLKSIZE:
469 return put_user(dev->oss.blksize, p); 470 return put_user(dev->dmasound.blksize, p);
470 471
471 case SNDCTL_DSP_SETFRAGMENT: 472 case SNDCTL_DSP_SETFRAGMENT:
472 if (get_user(val, p)) 473 if (get_user(val, p))
473 return -EFAULT; 474 return -EFAULT;
474 if (dev->oss.recording_on) 475 if (dev->dmasound.recording_on)
475 return -EBUSY; 476 return -EBUSY;
476 dsp_buffer_free(dev); 477 dsp_buffer_free(dev);
477 /* used to be arg >> 16 instead of val >> 16; fixed */ 478 /* used to be arg >> 16 instead of val >> 16; fixed */
@@ -479,16 +480,16 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
479 dsp_buffer_init(dev); 480 dsp_buffer_init(dev);
480 return 0; 481 return 0;
481 482
482 case SNDCTL_DSP_SYNC: 483 case SNDCTL_DSP_SYNC:
483 /* NOP */ 484 /* NOP */
484 return 0; 485 return 0;
485 486
486 case SNDCTL_DSP_GETISPACE: 487 case SNDCTL_DSP_GETISPACE:
487 { 488 {
488 audio_buf_info info; 489 audio_buf_info info;
489 info.fragsize = dev->oss.blksize; 490 info.fragsize = dev->dmasound.blksize;
490 info.fragstotal = dev->oss.blocks; 491 info.fragstotal = dev->dmasound.blocks;
491 info.bytes = dev->oss.read_count; 492 info.bytes = dev->dmasound.read_count;
492 info.fragments = info.bytes / info.fragsize; 493 info.fragments = info.bytes / info.fragsize;
493 if (copy_to_user(argp, &info, sizeof(info))) 494 if (copy_to_user(argp, &info, sizeof(info)))
494 return -EFAULT; 495 return -EFAULT;
@@ -504,13 +505,13 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
504 struct saa7134_dev *dev = file->private_data; 505 struct saa7134_dev *dev = file->private_data;
505 unsigned int mask = 0; 506 unsigned int mask = 0;
506 507
507 poll_wait(file, &dev->oss.wq, wait); 508 poll_wait(file, &dev->dmasound.wq, wait);
508 509
509 if (0 == dev->oss.read_count) { 510 if (0 == dev->dmasound.read_count) {
510 down(&dev->oss.lock); 511 down(&dev->dmasound.lock);
511 if (!dev->oss.recording_on) 512 if (!dev->dmasound.recording_on)
512 dsp_rec_start(dev); 513 dsp_rec_start(dev);
513 up(&dev->oss.lock); 514 up(&dev->dmasound.lock);
514 } else 515 } else
515 mask |= (POLLIN | POLLRDNORM); 516 mask |= (POLLIN | POLLRDNORM);
516 return mask; 517 return mask;
@@ -534,7 +535,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
534{ 535{
535 int analog_io,rate; 536 int analog_io,rate;
536 537
537 switch (dev->oss.input) { 538 switch (dev->dmasound.input) {
538 case TV: 539 case TV:
539 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); 540 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
540 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); 541 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
@@ -542,8 +543,8 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
542 case LINE1: 543 case LINE1:
543 case LINE2: 544 case LINE2:
544 case LINE2_LEFT: 545 case LINE2_LEFT:
545 analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08; 546 analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08;
546 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03; 547 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
547 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); 548 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
548 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); 549 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
549 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); 550 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
@@ -559,10 +560,10 @@ mixer_recsrc_7133(struct saa7134_dev *dev)
559 560
560 xbarin = 0x03; // adc 561 xbarin = 0x03; // adc
561 anabar = 0; 562 anabar = 0;
562 switch (dev->oss.input) { 563 switch (dev->dmasound.input) {
563 case TV: 564 case TV:
564 xbarin = 0; // Demodulator 565 xbarin = 0; // Demodulator
565 anabar = 2; // DACs 566 anabar = 2; // DACs
566 break; 567 break;
567 case LINE1: 568 case LINE1:
568 anabar = 0; // aux1, aux1 569 anabar = 0; // aux1, aux1
@@ -585,9 +586,9 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
585{ 586{
586 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" }; 587 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
587 588
588 dev->oss.count++; 589 dev->dmasound.count++;
589 dev->oss.input = src; 590 dev->dmasound.input = src;
590 dprintk("mixer input = %s\n",iname[dev->oss.input]); 591 dprintk("mixer input = %s\n",iname[dev->dmasound.input]);
591 592
592 switch (dev->pci->device) { 593 switch (dev->pci->device) {
593 case PCI_DEVICE_ID_PHILIPS_SAA7134: 594 case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -639,7 +640,7 @@ static int mixer_open(struct inode *inode, struct file *file)
639 640
640 list_for_each(list,&saa7134_devlist) { 641 list_for_each(list,&saa7134_devlist) {
641 h = list_entry(list, struct saa7134_dev, devlist); 642 h = list_entry(list, struct saa7134_dev, devlist);
642 if (h->oss.minor_mixer == minor) 643 if (h->dmasound.minor_mixer == minor)
643 dev = h; 644 dev = h;
644 } 645 }
645 if (NULL == dev) 646 if (NULL == dev)
@@ -666,28 +667,28 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
666 667
667 if (oss_debug > 1) 668 if (oss_debug > 1)
668 saa7134_print_ioctl(dev->name,cmd); 669 saa7134_print_ioctl(dev->name,cmd);
669 switch (cmd) { 670 switch (cmd) {
670 case OSS_GETVERSION: 671 case OSS_GETVERSION:
671 return put_user(SOUND_VERSION, p); 672 return put_user(SOUND_VERSION, p);
672 case SOUND_MIXER_INFO: 673 case SOUND_MIXER_INFO:
673 { 674 {
674 mixer_info info; 675 mixer_info info;
675 memset(&info,0,sizeof(info)); 676 memset(&info,0,sizeof(info));
676 strlcpy(info.id, "TV audio", sizeof(info.id)); 677 strlcpy(info.id, "TV audio", sizeof(info.id));
677 strlcpy(info.name, dev->name, sizeof(info.name)); 678 strlcpy(info.name, dev->name, sizeof(info.name));
678 info.modify_counter = dev->oss.count; 679 info.modify_counter = dev->dmasound.count;
679 if (copy_to_user(argp, &info, sizeof(info))) 680 if (copy_to_user(argp, &info, sizeof(info)))
680 return -EFAULT; 681 return -EFAULT;
681 return 0; 682 return 0;
682 } 683 }
683 case SOUND_OLD_MIXER_INFO: 684 case SOUND_OLD_MIXER_INFO:
684 { 685 {
685 _old_mixer_info info; 686 _old_mixer_info info;
686 memset(&info,0,sizeof(info)); 687 memset(&info,0,sizeof(info));
687 strlcpy(info.id, "TV audio", sizeof(info.id)); 688 strlcpy(info.id, "TV audio", sizeof(info.id));
688 strlcpy(info.name, dev->name, sizeof(info.name)); 689 strlcpy(info.name, dev->name, sizeof(info.name));
689 if (copy_to_user(argp, &info, sizeof(info))) 690 if (copy_to_user(argp, &info, sizeof(info)))
690 return -EFAULT; 691 return -EFAULT;
691 return 0; 692 return 0;
692 } 693 }
693 case MIXER_READ(SOUND_MIXER_CAPS): 694 case MIXER_READ(SOUND_MIXER_CAPS):
@@ -697,26 +698,26 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
697 case MIXER_READ(SOUND_MIXER_RECMASK): 698 case MIXER_READ(SOUND_MIXER_RECMASK):
698 case MIXER_READ(SOUND_MIXER_DEVMASK): 699 case MIXER_READ(SOUND_MIXER_DEVMASK):
699 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2; 700 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
700 if (32000 == dev->oss.rate) 701 if (32000 == dev->dmasound.rate)
701 val |= SOUND_MASK_VIDEO; 702 val |= SOUND_MASK_VIDEO;
702 return put_user(val, p); 703 return put_user(val, p);
703 704
704 case MIXER_WRITE(SOUND_MIXER_RECSRC): 705 case MIXER_WRITE(SOUND_MIXER_RECSRC):
705 if (get_user(val, p)) 706 if (get_user(val, p))
706 return -EFAULT; 707 return -EFAULT;
707 input = dev->oss.input; 708 input = dev->dmasound.input;
708 if (32000 == dev->oss.rate && 709 if (32000 == dev->dmasound.rate &&
709 val & SOUND_MASK_VIDEO && dev->oss.input != TV) 710 val & SOUND_MASK_VIDEO && dev->dmasound.input != TV)
710 input = TV; 711 input = TV;
711 if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1) 712 if (val & SOUND_MASK_LINE1 && dev->dmasound.input != LINE1)
712 input = LINE1; 713 input = LINE1;
713 if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2) 714 if (val & SOUND_MASK_LINE2 && dev->dmasound.input != LINE2)
714 input = LINE2; 715 input = LINE2;
715 if (input != dev->oss.input) 716 if (input != dev->dmasound.input)
716 mixer_recsrc(dev,input); 717 mixer_recsrc(dev,input);
717 /* fall throuth */ 718 /* fall throuth */
718 case MIXER_READ(SOUND_MIXER_RECSRC): 719 case MIXER_READ(SOUND_MIXER_RECSRC):
719 switch (dev->oss.input) { 720 switch (dev->dmasound.input) {
720 case TV: ret = SOUND_MASK_VIDEO; break; 721 case TV: ret = SOUND_MASK_VIDEO; break;
721 case LINE1: ret = SOUND_MASK_LINE1; break; 722 case LINE1: ret = SOUND_MASK_LINE1; break;
722 case LINE2: ret = SOUND_MASK_LINE2; break; 723 case LINE2: ret = SOUND_MASK_LINE2; break;
@@ -726,7 +727,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
726 727
727 case MIXER_WRITE(SOUND_MIXER_VIDEO): 728 case MIXER_WRITE(SOUND_MIXER_VIDEO):
728 case MIXER_READ(SOUND_MIXER_VIDEO): 729 case MIXER_READ(SOUND_MIXER_VIDEO):
729 if (32000 != dev->oss.rate) 730 if (32000 != dev->dmasound.rate)
730 return -EINVAL; 731 return -EINVAL;
731 return put_user(100 | 100 << 8, p); 732 return put_user(100 | 100 << 8, p);
732 733
@@ -735,22 +736,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
735 return -EFAULT; 736 return -EFAULT;
736 val &= 0xff; 737 val &= 0xff;
737 val = (val <= 50) ? 50 : 100; 738 val = (val <= 50) ? 50 : 100;
738 dev->oss.line1 = val; 739 dev->dmasound.line1 = val;
739 mixer_level(dev,LINE1,dev->oss.line1); 740 mixer_level(dev,LINE1,dev->dmasound.line1);
740 /* fall throuth */ 741 /* fall throuth */
741 case MIXER_READ(SOUND_MIXER_LINE1): 742 case MIXER_READ(SOUND_MIXER_LINE1):
742 return put_user(dev->oss.line1 | dev->oss.line1 << 8, p); 743 return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p);
743 744
744 case MIXER_WRITE(SOUND_MIXER_LINE2): 745 case MIXER_WRITE(SOUND_MIXER_LINE2):
745 if (get_user(val, p)) 746 if (get_user(val, p))
746 return -EFAULT; 747 return -EFAULT;
747 val &= 0xff; 748 val &= 0xff;
748 val = (val <= 50) ? 50 : 100; 749 val = (val <= 50) ? 50 : 100;
749 dev->oss.line2 = val; 750 dev->dmasound.line2 = val;
750 mixer_level(dev,LINE2,dev->oss.line2); 751 mixer_level(dev,LINE2,dev->dmasound.line2);
751 /* fall throuth */ 752 /* fall throuth */
752 case MIXER_READ(SOUND_MIXER_LINE2): 753 case MIXER_READ(SOUND_MIXER_LINE2):
753 return put_user(dev->oss.line2 | dev->oss.line2 << 8, p); 754 return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p);
754 755
755 default: 756 default:
756 return -EINVAL; 757 return -EINVAL;
@@ -770,8 +771,8 @@ struct file_operations saa7134_mixer_fops = {
770int saa7134_oss_init1(struct saa7134_dev *dev) 771int saa7134_oss_init1(struct saa7134_dev *dev)
771{ 772{
772 /* general */ 773 /* general */
773 init_MUTEX(&dev->oss.lock); 774 init_MUTEX(&dev->dmasound.lock);
774 init_waitqueue_head(&dev->oss.wq); 775 init_waitqueue_head(&dev->dmasound.wq);
775 776
776 switch (dev->pci->device) { 777 switch (dev->pci->device) {
777 case PCI_DEVICE_ID_PHILIPS_SAA7133: 778 case PCI_DEVICE_ID_PHILIPS_SAA7133:
@@ -783,17 +784,17 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
783 } 784 }
784 785
785 /* dsp */ 786 /* dsp */
786 dev->oss.rate = 32000; 787 dev->dmasound.rate = 32000;
787 if (oss_rate) 788 if (oss_rate)
788 dev->oss.rate = oss_rate; 789 dev->dmasound.rate = oss_rate;
789 dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000; 790 dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
790 791
791 /* mixer */ 792 /* mixer */
792 dev->oss.line1 = 50; 793 dev->dmasound.line1 = 50;
793 dev->oss.line2 = 50; 794 dev->dmasound.line2 = 50;
794 mixer_level(dev,LINE1,dev->oss.line1); 795 mixer_level(dev,LINE1,dev->dmasound.line1);
795 mixer_level(dev,LINE2,dev->oss.line2); 796 mixer_level(dev,LINE2,dev->dmasound.line2);
796 mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2); 797 mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2);
797 798
798 return 0; 799 return 0;
799} 800}
@@ -809,7 +810,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
809 int next_blk, reg = 0; 810 int next_blk, reg = 0;
810 811
811 spin_lock(&dev->slock); 812 spin_lock(&dev->slock);
812 if (UNSET == dev->oss.dma_blk) { 813 if (UNSET == dev->dmasound.dma_blk) {
813 dprintk("irq: recording stopped\n"); 814 dprintk("irq: recording stopped\n");
814 goto done; 815 goto done;
815 } 816 }
@@ -817,11 +818,11 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
817 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); 818 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
818 if (0 == (status & 0x10000000)) { 819 if (0 == (status & 0x10000000)) {
819 /* odd */ 820 /* odd */
820 if (0 == (dev->oss.dma_blk & 0x01)) 821 if (0 == (dev->dmasound.dma_blk & 0x01))
821 reg = SAA7134_RS_BA1(6); 822 reg = SAA7134_RS_BA1(6);
822 } else { 823 } else {
823 /* even */ 824 /* even */
824 if (1 == (dev->oss.dma_blk & 0x01)) 825 if (1 == (dev->dmasound.dma_blk & 0x01))
825 reg = SAA7134_RS_BA2(6); 826 reg = SAA7134_RS_BA2(6);
826 } 827 }
827 if (0 == reg) { 828 if (0 == reg) {
@@ -829,25 +830,25 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
829 (status & 0x10000000) ? "even" : "odd"); 830 (status & 0x10000000) ? "even" : "odd");
830 goto done; 831 goto done;
831 } 832 }
832 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) { 833 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
833 dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count, 834 dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count,
834 dev->oss.bufsize); 835 dev->dmasound.bufsize);
835 dsp_dma_stop(dev); 836 dsp_dma_stop(dev);
836 goto done; 837 goto done;
837 } 838 }
838 839
839 /* next block addr */ 840 /* next block addr */
840 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks; 841 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
841 saa_writel(reg,next_blk * dev->oss.blksize); 842 saa_writel(reg,next_blk * dev->dmasound.blksize);
842 if (oss_debug > 2) 843 if (oss_debug > 2)
843 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", 844 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
844 (status & 0x10000000) ? "even" : "odd ", next_blk, 845 (status & 0x10000000) ? "even" : "odd ", next_blk,
845 next_blk * dev->oss.blksize); 846 next_blk * dev->dmasound.blksize);
846 847
847 /* update status & wake waiting readers */ 848 /* update status & wake waiting readers */
848 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks; 849 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
849 dev->oss.read_count += dev->oss.blksize; 850 dev->dmasound.read_count += dev->dmasound.blksize;
850 wake_up(&dev->oss.wq); 851 wake_up(&dev->dmasound.wq);
851 852
852 done: 853 done:
853 spin_unlock(&dev->slock); 854 spin_unlock(&dev->slock);
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index ae0c7a165390..ac6431ba4fc3 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -27,7 +27,7 @@
27 27
28/* DMA channels, n = 0 ... 6 */ 28/* DMA channels, n = 0 ... 6 */
29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n) 29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n) 30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n) 31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n) 32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25) 33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
@@ -43,16 +43,24 @@
43#define SAA7134_FIFO_SIZE (0x2a0 >> 2) 43#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
44#define SAA7134_THRESHOULD (0x2a4 >> 2) 44#define SAA7134_THRESHOULD (0x2a4 >> 2)
45 45
46#define SAA7133_NUM_SAMPLES (0x588 >> 2)
47#define SAA7133_AUDIO_CHANNEL (0x58c >> 2)
48#define SAA7133_AUDIO_FORMAT (0x58f >> 2)
49#define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2)
50#define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2)
51#define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2)
52#define SAA7133_ANALOG_IO_SELECT (0x594 >> 2)
53
46/* main control */ 54/* main control */
47#define SAA7134_MAIN_CTRL (0x2a8 >> 2) 55#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
48#define SAA7134_MAIN_CTRL_VPLLE (1 << 15) 56#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
49#define SAA7134_MAIN_CTRL_APLLE (1 << 14) 57#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
50#define SAA7134_MAIN_CTRL_EXOSC (1 << 13) 58#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
51#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12) 59#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
52#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11) 60#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
53#define SAA7134_MAIN_CTRL_ESFE (1 << 10) 61#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
54#define SAA7134_MAIN_CTRL_EBADC (1 << 9) 62#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
55#define SAA7134_MAIN_CTRL_EBDAC (1 << 8) 63#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
56#define SAA7134_MAIN_CTRL_TE6 (1 << 6) 64#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
57#define SAA7134_MAIN_CTRL_TE5 (1 << 5) 65#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
58#define SAA7134_MAIN_CTRL_TE4 (1 << 4) 66#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
@@ -348,6 +356,7 @@
348 356
349/* test modes */ 357/* test modes */
350#define SAA7134_SPECIAL_MODE 0x1d0 358#define SAA7134_SPECIAL_MODE 0x1d0
359#define SAA7134_PRODUCTION_TEST_MODE 0x1d1
351 360
352/* audio -- saa7133 + saa7135 only */ 361/* audio -- saa7133 + saa7135 only */
353#define SAA7135_DSP_RWSTATE 0x580 362#define SAA7135_DSP_RWSTATE 0x580
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 463885601ab4..470903e2f5e5 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -46,17 +46,11 @@ static int buffer_activate(struct saa7134_dev *dev,
46 struct saa7134_buf *buf, 46 struct saa7134_buf *buf,
47 struct saa7134_buf *next) 47 struct saa7134_buf *next)
48{ 48{
49 u32 control;
50 49
51 dprintk("buffer_activate [%p]",buf); 50 dprintk("buffer_activate [%p]",buf);
52 buf->vb.state = STATE_ACTIVE; 51 buf->vb.state = STATE_ACTIVE;
53 buf->top_seen = 0; 52 buf->top_seen = 0;
54 53
55 /* dma: setup channel 5 (= TS) */
56 control = SAA7134_RS_CONTROL_BURST_16 |
57 SAA7134_RS_CONTROL_ME |
58 (buf->pt->dma >> 12);
59
60 if (NULL == next) 54 if (NULL == next)
61 next = buf; 55 next = buf;
62 if (V4L2_FIELD_TOP == buf->vb.field) { 56 if (V4L2_FIELD_TOP == buf->vb.field) {
@@ -68,8 +62,6 @@ static int buffer_activate(struct saa7134_dev *dev,
68 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); 62 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
69 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); 63 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
70 } 64 }
71 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
72 saa_writel(SAA7134_RS_CONTROL(5),control);
73 65
74 /* start DMA */ 66 /* start DMA */
75 saa7134_set_dmabits(dev); 67 saa7134_set_dmabits(dev);
@@ -84,6 +76,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
84 struct saa7134_dev *dev = q->priv_data; 76 struct saa7134_dev *dev = q->priv_data;
85 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 77 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
86 unsigned int lines, llength, size; 78 unsigned int lines, llength, size;
79 u32 control;
87 int err; 80 int err;
88 81
89 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); 82 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
@@ -115,6 +108,18 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
115 if (err) 108 if (err)
116 goto oops; 109 goto oops;
117 } 110 }
111
112 /* dma: setup channel 5 (= TS) */
113 control = SAA7134_RS_CONTROL_BURST_16 |
114 SAA7134_RS_CONTROL_ME |
115 (buf->pt->dma >> 12);
116
117 saa_writeb(SAA7134_TS_DMA0, ((lines-1)&0xff));
118 saa_writeb(SAA7134_TS_DMA1, (((lines-1)>>8)&0xff));
119 saa_writeb(SAA7134_TS_DMA2, ((((lines-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
120 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
121 saa_writel(SAA7134_RS_CONTROL(5),control);
122
118 buf->vb.state = STATE_PREPARED; 123 buf->vb.state = STATE_PREPARED;
119 buf->activate = buffer_activate; 124 buf->activate = buffer_activate;
120 buf->vb.field = field; 125 buf->vb.field = field;
@@ -164,11 +169,11 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops);
164/* ----------------------------------------------------------- */ 169/* ----------------------------------------------------------- */
165/* exported stuff */ 170/* exported stuff */
166 171
167static unsigned int tsbufs = 4; 172static unsigned int tsbufs = 8;
168module_param(tsbufs, int, 0444); 173module_param(tsbufs, int, 0444);
169MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); 174MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
170 175
171static unsigned int ts_nr_packets = 30; 176static unsigned int ts_nr_packets = 64;
172module_param(ts_nr_packets, int, 0444); 177module_param(ts_nr_packets, int, 0444);
173MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); 178MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
174 179
@@ -220,10 +225,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
220 if (dev->ts_q.curr) { 225 if (dev->ts_q.curr) {
221 field = dev->ts_q.curr->vb.field; 226 field = dev->ts_q.curr->vb.field;
222 if (field == V4L2_FIELD_TOP) { 227 if (field == V4L2_FIELD_TOP) {
223 if ((status & 0x100000) != 0x100000) 228 if ((status & 0x100000) != 0x000000)
224 goto done; 229 goto done;
225 } else { 230 } else {
226 if ((status & 0x100000) != 0x000000) 231 if ((status & 0x100000) != 0x100000)
227 goto done; 232 goto done;
228 } 233 }
229 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); 234 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 61a2d6b50eef..93268427750d 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -207,6 +207,10 @@ static void tvaudio_setcarrier(struct saa7134_dev *dev,
207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary)); 207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
208} 208}
209 209
210#define SAA7134_MUTE_MASK 0xbb
211#define SAA7134_MUTE_ANALOG 0x04
212#define SAA7134_MUTE_I2S 0x40
213
210static void mute_input_7134(struct saa7134_dev *dev) 214static void mute_input_7134(struct saa7134_dev *dev)
211{ 215{
212 unsigned int mute; 216 unsigned int mute;
@@ -241,7 +245,11 @@ static void mute_input_7134(struct saa7134_dev *dev)
241 245
242 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) 246 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
243 /* 7134 mute */ 247 /* 7134 mute */
244 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb); 248 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ?
249 SAA7134_MUTE_MASK |
250 SAA7134_MUTE_ANALOG |
251 SAA7134_MUTE_I2S :
252 SAA7134_MUTE_MASK);
245 253
246 /* switch internal audio mux */ 254 /* switch internal audio mux */
247 switch (in->amux) { 255 switch (in->amux) {
@@ -753,17 +761,17 @@ static int mute_input_7133(struct saa7134_dev *dev)
753 761
754 762
755 /* switch gpio-connected external audio mux */ 763 /* switch gpio-connected external audio mux */
756 if (0 != card(dev).gpiomask) { 764 if (0 != card(dev).gpiomask) {
757 mask = card(dev).gpiomask; 765 mask = card(dev).gpiomask;
758 766
759 if (card(dev).mute.name && dev->ctl_mute) 767 if (card(dev).mute.name && dev->ctl_mute)
760 in = &card(dev).mute; 768 in = &card(dev).mute;
761 else 769 else
762 in = dev->input; 770 in = dev->input;
763 771
764 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); 772 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
765 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); 773 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
766 saa7134_track_gpio(dev,in->name); 774 saa7134_track_gpio(dev,in->name);
767 } 775 }
768 776
769 return 0; 777 return 0;
@@ -1016,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
1016 return 0; 1024 return 0;
1017} 1025}
1018 1026
1027EXPORT_SYMBOL(saa_dsp_writel);
1028
1019/* ----------------------------------------------------------- */ 1029/* ----------------------------------------------------------- */
1020/* 1030/*
1021 * Local variables: 1031 * Local variables:
1022 * c-basic-offset: 8 1032 * c-basic-offset: 8
1023 * End: 1033 * End:
1024 */ 1034 */
1035
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 35e5e85f669a..45c852df13ed 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,6 +30,9 @@
30#include "saa7134-reg.h" 30#include "saa7134-reg.h"
31#include "saa7134.h" 31#include "saa7134.h"
32 32
33/* Include V4L1 specific functions. Should be removed soon */
34#include <linux/videodev.h>
35
33/* ------------------------------------------------------------------ */ 36/* ------------------------------------------------------------------ */
34 37
35static unsigned int video_debug = 0; 38static unsigned int video_debug = 0;
@@ -48,6 +51,43 @@ MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
48 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) 51 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
49 52
50/* ------------------------------------------------------------------ */ 53/* ------------------------------------------------------------------ */
54/* Defines for Video Output Port Register at address 0x191 */
55
56/* Bit 0: VIP code T bit polarity */
57
58#define VP_T_CODE_P_NON_INVERTED 0x00
59#define VP_T_CODE_P_INVERTED 0x01
60
61/* ------------------------------------------------------------------ */
62/* Defines for Video Output Port Register at address 0x195 */
63
64/* Bit 2: Video output clock delay control */
65
66#define VP_CLK_CTRL2_NOT_DELAYED 0x00
67#define VP_CLK_CTRL2_DELAYED 0x04
68
69/* Bit 1: Video output clock invert control */
70
71#define VP_CLK_CTRL1_NON_INVERTED 0x00
72#define VP_CLK_CTRL1_INVERTED 0x02
73
74/* ------------------------------------------------------------------ */
75/* Defines for Video Output Port Register at address 0x196 */
76
77/* Bits 2 to 0: VSYNC pin video vertical sync type */
78
79#define VP_VS_TYPE_MASK 0x07
80
81#define VP_VS_TYPE_OFF 0x00
82#define VP_VS_TYPE_V123 0x01
83#define VP_VS_TYPE_V_ITU 0x02
84#define VP_VS_TYPE_VGATE_L 0x03
85#define VP_VS_TYPE_RESERVED1 0x04
86#define VP_VS_TYPE_RESERVED2 0x05
87#define VP_VS_TYPE_F_ITU 0x06
88#define VP_VS_TYPE_SC_FID 0x07
89
90/* ------------------------------------------------------------------ */
51/* data structs for video */ 91/* data structs for video */
52 92
53static int video_out[][9] = { 93static int video_out[][9] = {
@@ -273,12 +313,12 @@ static struct saa7134_tvnorm tvnorms[] = {
273 313
274 .h_start = 0, 314 .h_start = 0,
275 .h_stop = 719, 315 .h_stop = 719,
276 .video_v_start = 23, 316 .video_v_start = 23,
277 .video_v_stop = 262, 317 .video_v_stop = 262,
278 .vbi_v_start_0 = 10, 318 .vbi_v_start_0 = 10,
279 .vbi_v_stop_0 = 21, 319 .vbi_v_stop_0 = 21,
280 .vbi_v_start_1 = 273, 320 .vbi_v_start_1 = 273,
281 .src_timing = 7, 321 .src_timing = 7,
282 322
283 .sync_control = 0x18, 323 .sync_control = 0x18,
284 .luma_control = 0x40, 324 .luma_control = 0x40,
@@ -622,7 +662,7 @@ static void set_size(struct saa7134_dev *dev, int task,
622 prescale = 1; 662 prescale = 1;
623 xscale = 1024 * dev->crop_current.width / prescale / width; 663 xscale = 1024 * dev->crop_current.width / prescale / width;
624 yscale = 512 * div * dev->crop_current.height / height; 664 yscale = 512 * div * dev->crop_current.height / height;
625 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); 665 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
626 set_h_prescale(dev,task,prescale); 666 set_h_prescale(dev,task,prescale);
627 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); 667 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
628 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); 668 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
@@ -752,20 +792,20 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
752 maxh = dev->crop_current.height; 792 maxh = dev->crop_current.height;
753 793
754 if (V4L2_FIELD_ANY == field) { 794 if (V4L2_FIELD_ANY == field) {
755 field = (win->w.height > maxh/2) 795 field = (win->w.height > maxh/2)
756 ? V4L2_FIELD_INTERLACED 796 ? V4L2_FIELD_INTERLACED
757 : V4L2_FIELD_TOP; 797 : V4L2_FIELD_TOP;
758 } 798 }
759 switch (field) { 799 switch (field) {
760 case V4L2_FIELD_TOP: 800 case V4L2_FIELD_TOP:
761 case V4L2_FIELD_BOTTOM: 801 case V4L2_FIELD_BOTTOM:
762 maxh = maxh / 2; 802 maxh = maxh / 2;
763 break; 803 break;
764 case V4L2_FIELD_INTERLACED: 804 case V4L2_FIELD_INTERLACED:
765 break; 805 break;
766 default: 806 default:
767 return -EINVAL; 807 return -EINVAL;
768 } 808 }
769 809
770 win->field = field; 810 win->field = field;
771 if (win->w.width > maxw) 811 if (win->w.width > maxw)
@@ -1306,13 +1346,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
1306 if (res_locked(fh->dev,RESOURCE_VIDEO)) { 1346 if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1307 up(&fh->cap.lock); 1347 up(&fh->cap.lock);
1308 return POLLERR; 1348 return POLLERR;
1309 } 1349 }
1310 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { 1350 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1311 up(&fh->cap.lock); 1351 up(&fh->cap.lock);
1312 return POLLERR; 1352 return POLLERR;
1313 } 1353 }
1314 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); 1354 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1315 fh->cap.read_off = 0; 1355 fh->cap.read_off = 0;
1316 } 1356 }
1317 up(&fh->cap.lock); 1357 up(&fh->cap.lock);
1318 buf = fh->cap.read_buf; 1358 buf = fh->cap.read_buf;
@@ -1666,9 +1706,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1666 case VIDIOC_QUERYCAP: 1706 case VIDIOC_QUERYCAP:
1667 { 1707 {
1668 struct v4l2_capability *cap = arg; 1708 struct v4l2_capability *cap = arg;
1709 unsigned int tuner_type = dev->tuner_type;
1669 1710
1670 memset(cap,0,sizeof(*cap)); 1711 memset(cap,0,sizeof(*cap));
1671 strcpy(cap->driver, "saa7134"); 1712 strcpy(cap->driver, "saa7134");
1672 strlcpy(cap->card, saa7134_boards[dev->board].name, 1713 strlcpy(cap->card, saa7134_boards[dev->board].name,
1673 sizeof(cap->card)); 1714 sizeof(cap->card));
1674 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 1715 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -1677,9 +1718,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1677 V4L2_CAP_VIDEO_CAPTURE | 1718 V4L2_CAP_VIDEO_CAPTURE |
1678 V4L2_CAP_VIDEO_OVERLAY | 1719 V4L2_CAP_VIDEO_OVERLAY |
1679 V4L2_CAP_VBI_CAPTURE | 1720 V4L2_CAP_VBI_CAPTURE |
1680 V4L2_CAP_TUNER |
1681 V4L2_CAP_READWRITE | 1721 V4L2_CAP_READWRITE |
1682 V4L2_CAP_STREAMING; 1722 V4L2_CAP_STREAMING |
1723 V4L2_CAP_TUNER;
1724
1725 if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
1726 cap->capabilities &= ~V4L2_CAP_TUNER;
1727
1683 return 0; 1728 return 0;
1684 } 1729 }
1685 1730
@@ -1793,9 +1838,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1793 crop->c.height = b->top - crop->c.top + b->height; 1838 crop->c.height = b->top - crop->c.top + b->height;
1794 1839
1795 if (crop->c.left < b->left) 1840 if (crop->c.left < b->left)
1796 crop->c.top = b->left; 1841 crop->c.left = b->left;
1797 if (crop->c.left > b->left + b->width) 1842 if (crop->c.left > b->left + b->width)
1798 crop->c.top = b->left + b->width; 1843 crop->c.left = b->left + b->width;
1799 if (crop->c.width > b->left - crop->c.left + b->width) 1844 if (crop->c.width > b->left - crop->c.left + b->width)
1800 crop->c.width = b->left - crop->c.left + b->width; 1845 crop->c.width = b->left - crop->c.left + b->width;
1801 1846
@@ -1817,6 +1862,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1817 break; 1862 break;
1818 if (NULL != card_in(dev,n).name) { 1863 if (NULL != card_in(dev,n).name) {
1819 strcpy(t->name, "Television"); 1864 strcpy(t->name, "Television");
1865 t->type = V4L2_TUNER_ANALOG_TV;
1820 t->capability = V4L2_TUNER_CAP_NORM | 1866 t->capability = V4L2_TUNER_CAP_NORM |
1821 V4L2_TUNER_CAP_STEREO | 1867 V4L2_TUNER_CAP_STEREO |
1822 V4L2_TUNER_CAP_LANG1 | 1868 V4L2_TUNER_CAP_LANG1 |
@@ -1892,26 +1938,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1892 } 1938 }
1893 case VIDIOC_S_AUDIO: 1939 case VIDIOC_S_AUDIO:
1894 return 0; 1940 return 0;
1895 case VIDIOC_G_PARM: 1941 case VIDIOC_G_PARM:
1896 { 1942 {
1897 struct v4l2_captureparm *parm = arg; 1943 struct v4l2_captureparm *parm = arg;
1898 memset(parm,0,sizeof(*parm)); 1944 memset(parm,0,sizeof(*parm));
1899 return 0; 1945 return 0;
1900 } 1946 }
1901 1947
1902 case VIDIOC_G_PRIORITY: 1948 case VIDIOC_G_PRIORITY:
1903 { 1949 {
1904 enum v4l2_priority *p = arg; 1950 enum v4l2_priority *p = arg;
1905 1951
1906 *p = v4l2_prio_max(&dev->prio); 1952 *p = v4l2_prio_max(&dev->prio);
1907 return 0; 1953 return 0;
1908 } 1954 }
1909 case VIDIOC_S_PRIORITY: 1955 case VIDIOC_S_PRIORITY:
1910 { 1956 {
1911 enum v4l2_priority *prio = arg; 1957 enum v4l2_priority *prio = arg;
1912 1958
1913 return v4l2_prio_change(&dev->prio, &fh->prio, *prio); 1959 return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
1914 } 1960 }
1915 1961
1916 /* --- preview ioctls ---------------------------------------- */ 1962 /* --- preview ioctls ---------------------------------------- */
1917 case VIDIOC_ENUM_FMT: 1963 case VIDIOC_ENUM_FMT:
@@ -2018,7 +2064,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2018 struct v4l2_format *f = arg; 2064 struct v4l2_format *f = arg;
2019 return saa7134_try_fmt(dev,fh,f); 2065 return saa7134_try_fmt(dev,fh,f);
2020 } 2066 }
2021 2067#ifdef HAVE_V4L1
2022 case VIDIOCGMBUF: 2068 case VIDIOCGMBUF:
2023 { 2069 {
2024 struct video_mbuf *mbuf = arg; 2070 struct video_mbuf *mbuf = arg;
@@ -2043,6 +2089,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2043 } 2089 }
2044 return 0; 2090 return 0;
2045 } 2091 }
2092#endif
2046 case VIDIOC_REQBUFS: 2093 case VIDIOC_REQBUFS:
2047 return videobuf_reqbufs(saa7134_queue(fh),arg); 2094 return videobuf_reqbufs(saa7134_queue(fh),arg);
2048 2095
@@ -2060,7 +2107,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2060 { 2107 {
2061 int res = saa7134_resource(fh); 2108 int res = saa7134_resource(fh);
2062 2109
2063 if (!res_get(dev,fh,res)) 2110 if (!res_get(dev,fh,res))
2064 return -EBUSY; 2111 return -EBUSY;
2065 return videobuf_streamon(saa7134_queue(fh)); 2112 return videobuf_streamon(saa7134_queue(fh));
2066 } 2113 }
@@ -2102,7 +2149,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2102 struct v4l2_capability *cap = arg; 2149 struct v4l2_capability *cap = arg;
2103 2150
2104 memset(cap,0,sizeof(*cap)); 2151 memset(cap,0,sizeof(*cap));
2105 strcpy(cap->driver, "saa7134"); 2152 strcpy(cap->driver, "saa7134");
2106 strlcpy(cap->card, saa7134_boards[dev->board].name, 2153 strlcpy(cap->card, saa7134_boards[dev->board].name,
2107 sizeof(cap->card)); 2154 sizeof(cap->card));
2108 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 2155 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -2119,6 +2166,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2119 2166
2120 memset(t,0,sizeof(*t)); 2167 memset(t,0,sizeof(*t));
2121 strcpy(t->name, "Radio"); 2168 strcpy(t->name, "Radio");
2169 t->type = V4L2_TUNER_RADIO;
2122 2170
2123 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); 2171 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
2124 2172
@@ -2233,7 +2281,7 @@ struct video_device saa7134_video_template =
2233{ 2281{
2234 .name = "saa7134-video", 2282 .name = "saa7134-video",
2235 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| 2283 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
2236 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 2284 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2237 .hardware = 0, 2285 .hardware = 0,
2238 .fops = &video_fops, 2286 .fops = &video_fops,
2239 .minor = -1, 2287 .minor = -1,
@@ -2280,7 +2328,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2280 dev->tda9887_conf |= TDA9887_AUTOMUTE; 2328 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2281 dev->automute = 0; 2329 dev->automute = 0;
2282 2330
2283 INIT_LIST_HEAD(&dev->video_q.queue); 2331 INIT_LIST_HEAD(&dev->video_q.queue);
2284 init_timer(&dev->video_q.timeout); 2332 init_timer(&dev->video_q.timeout);
2285 dev->video_q.timeout.function = saa7134_buffer_timeout; 2333 dev->video_q.timeout.function = saa7134_buffer_timeout;
2286 dev->video_q.timeout.data = (unsigned long)(&dev->video_q); 2334 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
@@ -2289,13 +2337,28 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2289 if (saa7134_boards[dev->board].video_out) { 2337 if (saa7134_boards[dev->board].video_out) {
2290 /* enable video output */ 2338 /* enable video output */
2291 int vo = saa7134_boards[dev->board].video_out; 2339 int vo = saa7134_boards[dev->board].video_out;
2340 int video_reg;
2341 unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
2292 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); 2342 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2293 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]); 2343 video_reg = video_out[vo][1];
2344 if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
2345 video_reg &= ~VP_T_CODE_P_INVERTED;
2346 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
2294 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); 2347 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2295 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); 2348 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2296 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); 2349 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2297 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]); 2350 video_reg = video_out[vo][5];
2298 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]); 2351 if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
2352 video_reg &= ~VP_CLK_CTRL2_DELAYED;
2353 if (vid_port_opts & SET_CLOCK_INVERTED)
2354 video_reg |= VP_CLK_CTRL1_INVERTED;
2355 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
2356 video_reg = video_out[vo][6];
2357 if (vid_port_opts & SET_VSYNC_OFF) {
2358 video_reg &= ~VP_VS_TYPE_MASK;
2359 video_reg |= VP_VS_TYPE_OFF;
2360 }
2361 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
2299 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); 2362 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2300 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); 2363 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2301 } 2364 }
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 860b89530e2a..fb9727471661 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -24,16 +24,18 @@
24 24
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/videodev.h> 27#include <linux/videodev2.h>
28#include <linux/kdev_t.h> 28#include <linux/kdev_t.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/notifier.h>
31#include <linux/delay.h>
30 32
31#include <asm/io.h> 33#include <asm/io.h>
32 34
33#include <media/tuner.h> 35#include <media/tuner.h>
34#include <media/audiochip.h> 36#include <media/audiochip.h>
35#include <media/id.h>
36#include <media/ir-common.h> 37#include <media/ir-common.h>
38#include <media/ir-kbd-i2c.h>
37#include <media/video-buf.h> 39#include <media/video-buf.h>
38#include <media/video-buf-dvb.h> 40#include <media/video-buf-dvb.h>
39 41
@@ -45,6 +47,10 @@
45#endif 47#endif
46#define UNSET (-1U) 48#define UNSET (-1U)
47 49
50#include <sound/driver.h>
51#include <sound/core.h>
52#include <sound/pcm.h>
53
48/* ----------------------------------------------------------- */ 54/* ----------------------------------------------------------- */
49/* enums */ 55/* enums */
50 56
@@ -187,10 +193,39 @@ struct saa7134_format {
187#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64 193#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
188#define SAA7134_BOARD_KWORLD_TERMINATOR 65 194#define SAA7134_BOARD_KWORLD_TERMINATOR 65
189#define SAA7134_BOARD_YUAN_TUN900 66 195#define SAA7134_BOARD_YUAN_TUN900 66
196#define SAA7134_BOARD_BEHOLD_409FM 67
197#define SAA7134_BOARD_GOTVIEW_7135 68
198#define SAA7134_BOARD_PHILIPS_EUROPA 69
199#define SAA7134_BOARD_VIDEOMATE_DVBT_300 70
200#define SAA7134_BOARD_VIDEOMATE_DVBT_200 71
201#define SAA7134_BOARD_RTD_VFG7350 72
202#define SAA7134_BOARD_RTD_VFG7330 73
203#define SAA7134_BOARD_FLYTVPLATINUM_MINI2 74
204#define SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180 75
205#define SAA7134_BOARD_MONSTERTV_MOBILE 76
206#define SAA7134_BOARD_PINNACLE_PCTV_110i 77
207#define SAA7134_BOARD_ASUSTeK_P7131_DUAL 78
208#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
209#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
210#define SAA7134_BOARD_PHILIPS_TIGER 81
190 211
191#define SAA7134_MAXBOARDS 8 212#define SAA7134_MAXBOARDS 8
192#define SAA7134_INPUT_MAX 8 213#define SAA7134_INPUT_MAX 8
193 214
215/* ----------------------------------------------------------- */
216/* Since we support 2 remote types, lets tell them apart */
217
218#define SAA7134_REMOTE_GPIO 1
219#define SAA7134_REMOTE_I2C 2
220
221/* ----------------------------------------------------------- */
222/* Video Output Port Register Initialization Options */
223
224#define SET_T_CODE_POLARITY_NON_INVERTED (1 << 0)
225#define SET_CLOCK_NOT_DELAYED (1 << 1)
226#define SET_CLOCK_INVERTED (1 << 2)
227#define SET_VSYNC_OFF (1 << 3)
228
194struct saa7134_input { 229struct saa7134_input {
195 char *name; 230 char *name;
196 unsigned int vmux; 231 unsigned int vmux;
@@ -226,6 +261,7 @@ struct saa7134_board {
226 /* peripheral I/O */ 261 /* peripheral I/O */
227 enum saa7134_video_out video_out; 262 enum saa7134_video_out video_out;
228 enum saa7134_mpeg_type mpeg; 263 enum saa7134_mpeg_type mpeg;
264 unsigned int vid_port_opts;
229}; 265};
230 266
231#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name) 267#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
@@ -319,9 +355,9 @@ struct saa7134_fh {
319 struct saa7134_pgtable pt_vbi; 355 struct saa7134_pgtable pt_vbi;
320}; 356};
321 357
322/* oss dsp status */ 358/* dmasound dsp status */
323struct saa7134_oss { 359struct saa7134_dmasound {
324 struct semaphore lock; 360 struct semaphore lock;
325 int minor_mixer; 361 int minor_mixer;
326 int minor_dsp; 362 int minor_dsp;
327 unsigned int users_dsp; 363 unsigned int users_dsp;
@@ -347,6 +383,7 @@ struct saa7134_oss {
347 unsigned int dma_blk; 383 unsigned int dma_blk;
348 unsigned int read_offset; 384 unsigned int read_offset;
349 unsigned int read_count; 385 unsigned int read_count;
386 snd_pcm_substream_t *substream;
350}; 387};
351 388
352/* IR input */ 389/* IR input */
@@ -358,9 +395,9 @@ struct saa7134_ir {
358 u32 mask_keycode; 395 u32 mask_keycode;
359 u32 mask_keydown; 396 u32 mask_keydown;
360 u32 mask_keyup; 397 u32 mask_keyup;
361 int polling; 398 int polling;
362 u32 last_gpio; 399 u32 last_gpio;
363 struct timer_list timer; 400 struct timer_list timer;
364}; 401};
365 402
366/* ts/mpeg status */ 403/* ts/mpeg status */
@@ -383,8 +420,8 @@ struct saa7134_mpeg_ops {
383/* global device status */ 420/* global device status */
384struct saa7134_dev { 421struct saa7134_dev {
385 struct list_head devlist; 422 struct list_head devlist;
386 struct semaphore lock; 423 struct semaphore lock;
387 spinlock_t slock; 424 spinlock_t slock;
388#ifdef VIDIOC_G_PRIORITY 425#ifdef VIDIOC_G_PRIORITY
389 struct v4l2_prio_state prio; 426 struct v4l2_prio_state prio;
390#endif 427#endif
@@ -394,7 +431,7 @@ struct saa7134_dev {
394 struct video_device *video_dev; 431 struct video_device *video_dev;
395 struct video_device *radio_dev; 432 struct video_device *radio_dev;
396 struct video_device *vbi_dev; 433 struct video_device *vbi_dev;
397 struct saa7134_oss oss; 434 struct saa7134_dmasound dmasound;
398 435
399 /* infrared remote */ 436 /* infrared remote */
400 int has_remote; 437 int has_remote;
@@ -421,7 +458,7 @@ struct saa7134_dev {
421 /* i2c i/o */ 458 /* i2c i/o */
422 struct i2c_adapter i2c_adap; 459 struct i2c_adapter i2c_adap;
423 struct i2c_client i2c_client; 460 struct i2c_client i2c_client;
424 unsigned char eedata[64]; 461 unsigned char eedata[128];
425 462
426 /* video overlay */ 463 /* video overlay */
427 struct v4l2_framebuffer ovbuf; 464 struct v4l2_framebuffer ovbuf;
@@ -626,6 +663,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
626int saa7134_input_init1(struct saa7134_dev *dev); 663int saa7134_input_init1(struct saa7134_dev *dev);
627void saa7134_input_fini(struct saa7134_dev *dev); 664void saa7134_input_fini(struct saa7134_dev *dev);
628void saa7134_input_irq(struct saa7134_dev *dev); 665void saa7134_input_irq(struct saa7134_dev *dev);
666void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
629 667
630/* 668/*
631 * Local variables: 669 * Local variables:
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 255b6088ebf9..d32737dd2142 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,7 +50,6 @@
50 50
51#include "bttv.h" 51#include "bttv.h"
52#include <media/audiochip.h> 52#include <media/audiochip.h>
53#include <media/id.h>
54 53
55#ifndef VIDEO_AUDIO_BALANCE 54#ifndef VIDEO_AUDIO_BALANCE
56# define VIDEO_AUDIO_BALANCE 32 55# define VIDEO_AUDIO_BALANCE 32
@@ -310,9 +309,9 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
310 memset(t,0,sizeof *t); 309 memset(t,0,sizeof *t);
311 310
312 client = &t->c; 311 client = &t->c;
313 memcpy(client,&client_template,sizeof(struct i2c_client)); 312 memcpy(client,&client_template,sizeof(struct i2c_client));
314 client->adapter = adap; 313 client->adapter = adap;
315 client->addr = addr; 314 client->addr = addr;
316 i2c_set_clientdata(client, t); 315 i2c_set_clientdata(client, t);
317 316
318 do_tda7432_init(client); 317 do_tda7432_init(client);
@@ -472,7 +471,7 @@ static int tda7432_command(struct i2c_client *client,
472 } 471 }
473 } 472 }
474 473
475 t->muted=(va->flags & VIDEO_AUDIO_MUTE); 474 t->muted=(va->flags & VIDEO_AUDIO_MUTE);
476 if (t->muted) 475 if (t->muted)
477 { 476 {
478 /* Mute & update balance*/ 477 /* Mute & update balance*/
@@ -503,12 +502,12 @@ static int tda7432_command(struct i2c_client *client,
503 502
504static struct i2c_driver driver = { 503static struct i2c_driver driver = {
505 .owner = THIS_MODULE, 504 .owner = THIS_MODULE,
506 .name = "i2c tda7432 driver", 505 .name = "i2c tda7432 driver",
507 .id = I2C_DRIVERID_TDA7432, 506 .id = I2C_DRIVERID_TDA7432,
508 .flags = I2C_DF_NOTIFY, 507 .flags = I2C_DF_NOTIFY,
509 .attach_adapter = tda7432_probe, 508 .attach_adapter = tda7432_probe,
510 .detach_client = tda7432_detach, 509 .detach_client = tda7432_detach,
511 .command = tda7432_command, 510 .command = tda7432_command,
512}; 511};
513 512
514static struct i2c_client client_template = 513static struct i2c_client client_template =
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index c65f0c7680a2..b2dfe07e9f9d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,172 +1,406 @@
1/* 1/*
2 * 2
3 * i2c tv tuner chip device driver 3 i2c tv tuner chip device driver
4 * controls the philips tda8290+75 tuner chip combo. 4 controls the philips tda8290+75 tuner chip combo.
5 */ 5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
6#include <linux/i2c.h> 21#include <linux/i2c.h>
7#include <linux/videodev.h> 22#include <linux/videodev.h>
8#include <linux/delay.h> 23#include <linux/delay.h>
9#include <media/tuner.h> 24#include <media/tuner.h>
10 25
11#define I2C_ADDR_TDA8290 0x4b
12#define I2C_ADDR_TDA8275 0x61
13
14/* ---------------------------------------------------------------------- */ 26/* ---------------------------------------------------------------------- */
15 27
16struct freq_entry { 28struct tda827x_data {
17 u16 freq; 29 u32 lomax;
18 u8 value; 30 u8 spd;
31 u8 bs;
32 u8 bp;
33 u8 cp;
34 u8 gc3;
35 u8 div1p5;
19}; 36};
20 37
21static struct freq_entry band_table[] = { 38 /* Note lomax entry is lo / 62500 */
22 { 0x2DF4, 0x1C }, 39
23 { 0x2574, 0x14 }, 40static struct tda827x_data tda827x_analog[] = {
24 { 0x22B4, 0x0C }, 41 { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */
25 { 0x20D4, 0x0B }, 42 { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */
26 { 0x1E74, 0x3B }, 43 { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */
27 { 0x1C34, 0x33 }, 44 { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */
28 { 0x16F4, 0x5B }, 45 { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */
29 { 0x1454, 0x53 }, 46 { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */
30 { 0x12D4, 0x52 }, 47 { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */
31 { 0x1034, 0x4A }, 48 { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */
32 { 0x0EE4, 0x7A }, 49 { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */
33 { 0x0D34, 0x72 }, 50 { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */
34 { 0x0B54, 0x9A }, 51 { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */
35 { 0x0914, 0x91 }, 52 { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */
36 { 0x07F4, 0x89 }, 53 { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */
37 { 0x0774, 0xB9 }, 54 { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */
38 { 0x067B, 0xB1 }, 55 { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */
39 { 0x0634, 0xD9 }, 56 { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */
40 { 0x05A4, 0xD8 }, // FM radio 57 { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */
41 { 0x0494, 0xD0 }, 58 { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */
42 { 0x03BC, 0xC8 }, 59 { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */
43 { 0x0394, 0xF8 }, // 57250000 Hz 60 { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */
44 { 0x0000, 0xF0 }, // 0 61 { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */
62 { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */
63 { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */
64 { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */
65 { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */
66 { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */
67 { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */
68 { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */
69 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */
45}; 70};
46 71
47static struct freq_entry div_table[] = { 72static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
48 { 0x1C34, 3 }, 73{
49 { 0x0D34, 2 }, 74 unsigned char tuner_reg[8];
50 { 0x067B, 1 }, 75 unsigned char reg2[2];
51 { 0x0000, 0 }, 76 u32 N;
52}; 77 int i;
78 struct tuner *t = i2c_get_clientdata(c);
79 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
53 80
54static struct freq_entry agc_table[] = { 81 if (t->mode == V4L2_TUNER_RADIO)
55 { 0x22B4, 0x8F }, 82 freq = freq / 1000;
56 { 0x0B54, 0x9F },
57 { 0x09A4, 0x8F },
58 { 0x0554, 0x9F },
59 { 0x0000, 0xBF },
60};
61 83
62static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) 84 N = freq + ifc;
63{ 85 i = 0;
64 while(table->freq && table->freq > freq) 86 while (tda827x_analog[i].lomax < N) {
65 table++; 87 if(tda827x_analog[i + 1].lomax == 0)
66 return table->value; 88 break;
67} 89 i++;
90 }
91
92 N = N << tda827x_analog[i].spd;
93
94 tuner_reg[0] = 0;
95 tuner_reg[1] = (unsigned char)(N>>8);
96 tuner_reg[2] = (unsigned char) N;
97 tuner_reg[3] = 0x40;
98 tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5);
99 tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) +
100 (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp;
101 tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4);
102 tuner_reg[7] = 0x8f;
103
104 msg.buf = tuner_reg;
105 msg.len = 8;
106 i2c_transfer(c->adapter, &msg, 1);
107
108 msg.buf= reg2;
109 msg.len = 2;
110 reg2[0] = 0x80;
111 reg2[1] = 0;
112 i2c_transfer(c->adapter, &msg, 1);
113
114 reg2[0] = 0x60;
115 reg2[1] = 0xbf;
116 i2c_transfer(c->adapter, &msg, 1);
117
118 reg2[0] = 0x30;
119 reg2[1] = tuner_reg[4] + 0x80;
120 i2c_transfer(c->adapter, &msg, 1);
121
122 msleep(1);
123 reg2[0] = 0x30;
124 reg2[1] = tuner_reg[4] + 4;
125 i2c_transfer(c->adapter, &msg, 1);
126
127 msleep(1);
128 reg2[0] = 0x30;
129 reg2[1] = tuner_reg[4];
130 i2c_transfer(c->adapter, &msg, 1);
68 131
69/* ---------------------------------------------------------------------- */ 132 msleep(550);
133 reg2[0] = 0x30;
134 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;
135 i2c_transfer(c->adapter, &msg, 1);
70 136
71static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; 137 reg2[0] = 0x60;
72static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; 138 reg2[1] = 0x3f;
73static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, 139 i2c_transfer(c->adapter, &msg, 1);
74 0xfC, 0x04, 0xA3, 0x3F,
75 0x2A, 0x04, 0xFF, 0x00,
76 0x00, 0x40 };
77static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
78static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
79static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
80static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 };
81static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
82static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
83static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
84static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
85static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 };
86static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
87static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
88static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
89static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 };
90static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F };
91static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 };
92
93static struct i2c_msg i2c_msg_init[] = {
94 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 },
95 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
96 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS },
97 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF },
98};
99 140
100static struct i2c_msg i2c_msg_prolog[] = { 141 reg2[0] = 0x80;
101// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode }, 142 reg2[1] = 0x08; // Vsync en
102 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off }, 143 i2c_transfer(c->adapter, &msg, 1);
103 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset }, 144}
104 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
105};
106 145
107static struct i2c_msg i2c_msg_config[] = { 146static void tda827x_agcf(struct i2c_client *c)
108// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq }, 147{
109 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 }, 148 struct tuner *t = i2c_get_clientdata(c);
110 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF }, 149 unsigned char data[] = {0x80, 0x0c};
111 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 }, 150 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
112 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 }, 151 .flags = 0, .len = 2};
113 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 }, 152 i2c_transfer(c->adapter, &msg, 1);
114}; 153}
115 154
116static struct i2c_msg i2c_msg_epilog[] = { 155/* ---------------------------------------------------------------------- */
117 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 }, 156
118 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F }, 157struct tda827xa_data {
119 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 }, 158 u32 lomax;
120 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 159 u8 svco;
121 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on }, 160 u8 spd;
161 u8 scr;
162 u8 sbs;
163 u8 gc3;
122}; 164};
123 165
124static struct i2c_msg i2c_msg_standby[] = { 166static struct tda827xa_data tda827xa_analog[] = {
125 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge }, 167 { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */
126 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 }, 168 { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */
127 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 169 { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */
128 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby }, 170 { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */
171 { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */
172 { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */
173 { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */
174 { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */
175 { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */
176 { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */
177 { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */
178 { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */
179 { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */
180 { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */
181 { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */
182 { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */
183 { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */
184 { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */
185 { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */
186 { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */
187 { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */
188 { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */
189 { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */
190 { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */
191 { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */
192 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
129}; 193};
130 194
131static int tda8290_tune(struct i2c_client *c) 195static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
132{ 196{
197 unsigned char tuner_reg[14];
198 unsigned char reg2[2];
199 u32 N;
200 int i;
133 struct tuner *t = i2c_get_clientdata(c); 201 struct tuner *t = i2c_get_clientdata(c);
134 struct i2c_msg easy_mode = 202 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
135 { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode };
136 struct i2c_msg set_freq =
137 { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq };
138 203
139 i2c_transfer(c->adapter, &easy_mode, 1); 204 if (t->mode == V4L2_TUNER_RADIO)
140 i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog)); 205 freq = freq / 1000;
141 206
142 i2c_transfer(c->adapter, &set_freq, 1); 207 N = freq + ifc;
143 i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config)); 208 i = 0;
209 while (tda827xa_analog[i].lomax < N) {
210 if(tda827xa_analog[i + 1].lomax == 0)
211 break;
212 i++;
213 }
214
215 N = N << tda827xa_analog[i].spd;
216
217 tuner_reg[0] = 0;
218 tuner_reg[1] = (unsigned char)(N>>8);
219 tuner_reg[2] = (unsigned char) N;
220 tuner_reg[3] = 0;
221 tuner_reg[4] = 0x16;
222 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +
223 tda827xa_analog[i].sbs;
224 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
225 tuner_reg[7] = 0x0c;
226 tuner_reg[8] = 4;
227 tuner_reg[9] = 0x20;
228 tuner_reg[10] = 0xff;
229 tuner_reg[11] = 0xe0;
230 tuner_reg[12] = 0;
231 tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1);
232
233 msg.buf = tuner_reg;
234 msg.len = 14;
235 i2c_transfer(c->adapter, &msg, 1);
236
237 msg.buf= reg2;
238 msg.len = 2;
239 reg2[0] = 0x60;
240 reg2[1] = 0x3c;
241 i2c_transfer(c->adapter, &msg, 1);
242
243 reg2[0] = 0xa0;
244 reg2[1] = 0xc0;
245 i2c_transfer(c->adapter, &msg, 1);
246
247 msleep(2);
248 reg2[0] = 0x30;
249 reg2[1] = 0x10 + tda827xa_analog[i].scr;
250 i2c_transfer(c->adapter, &msg, 1);
144 251
145 msleep(550); 252 msleep(550);
146 i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog)); 253 reg2[0] = 0x50;
147 return 0; 254 reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
255 i2c_transfer(c->adapter, &msg, 1);
256
257 reg2[0] = 0x80;
258 reg2[1] = 0x28;
259 i2c_transfer(c->adapter, &msg, 1);
260
261 reg2[0] = 0xb0;
262 reg2[1] = 0x01;
263 i2c_transfer(c->adapter, &msg, 1);
264
265 reg2[0] = 0xc0;
266 reg2[1] = 0x19 + (t->tda827x_lpsel << 1);
267 i2c_transfer(c->adapter, &msg, 1);
148} 268}
149 269
150static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq) 270static void tda827xa_agcf(struct i2c_client *c)
151{ 271{
152 u32 N; 272 struct tuner *t = i2c_get_clientdata(c);
273 unsigned char data[] = {0x80, 0x2c};
274 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
275 .flags = 0, .len = 2};
276 i2c_transfer(c->adapter, &msg, 1);
277}
153 278
154 if (t->mode == V4L2_TUNER_RADIO) 279/*---------------------------------------------------------------------*/
155 freq = freq / 1000;
156 280
157 N = (((freq<<3)+ifc)&0x3fffc); 281static void tda8290_i2c_bridge(struct i2c_client *c, int close)
158 282{
159 N = N >> get_freq_entry(div_table, freq); 283 unsigned char enable[2] = { 0x21, 0xC0 };
160 t->i2c_set_freq[0] = 0; 284 unsigned char disable[2] = { 0x21, 0x80 };
161 t->i2c_set_freq[1] = (unsigned char)(N>>8); 285 unsigned char *msg;
162 t->i2c_set_freq[2] = (unsigned char) N; 286 if(close) {
163 t->i2c_set_freq[3] = 0x40; 287 msg = enable;
164 t->i2c_set_freq[4] = 0x52; 288 i2c_master_send(c, msg, 2);
165 t->i2c_set_freq[5] = get_freq_entry(band_table, freq); 289 /* let the bridge stabilize */
166 t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); 290 msleep(20);
167 t->i2c_set_freq[7] = 0x8f; 291 } else {
292 msg = disable;
293 i2c_master_send(c, msg, 2);
294 }
168} 295}
169 296
297/*---------------------------------------------------------------------*/
298
299static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
300{
301 struct tuner *t = i2c_get_clientdata(c);
302 unsigned char soft_reset[] = { 0x00, 0x00 };
303 unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode };
304 unsigned char expert_mode[] = { 0x01, 0x80 };
305 unsigned char gainset_off[] = { 0x28, 0x14 };
306 unsigned char if_agc_spd[] = { 0x0f, 0x88 };
307 unsigned char adc_head_6[] = { 0x05, 0x04 };
308 unsigned char adc_head_9[] = { 0x05, 0x02 };
309 unsigned char adc_head_12[] = { 0x05, 0x01 };
310 unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
311 unsigned char pll_bw_low[] = { 0x0d, 0x27 };
312 unsigned char gainset_2[] = { 0x28, 0x64 };
313 unsigned char agc_rst_on[] = { 0x0e, 0x0b };
314 unsigned char agc_rst_off[] = { 0x0e, 0x09 };
315 unsigned char if_agc_set[] = { 0x0f, 0x81 };
316 unsigned char addr_adc_sat = 0x1a;
317 unsigned char addr_agc_stat = 0x1d;
318 unsigned char addr_pll_stat = 0x1b;
319 unsigned char adc_sat, agc_stat,
320 pll_stat;
321
322 i2c_master_send(c, easy_mode, 2);
323 i2c_master_send(c, soft_reset, 2);
324 msleep(1);
325
326 expert_mode[1] = t->tda8290_easy_mode + 0x80;
327 i2c_master_send(c, expert_mode, 2);
328 i2c_master_send(c, gainset_off, 2);
329 i2c_master_send(c, if_agc_spd, 2);
330 if (t->tda8290_easy_mode & 0x60)
331 i2c_master_send(c, adc_head_9, 2);
332 else
333 i2c_master_send(c, adc_head_6, 2);
334 i2c_master_send(c, pll_bw_nom, 2);
335
336 tda8290_i2c_bridge(c, 1);
337 if (t->tda827x_ver != 0)
338 tda827xa_tune(c, ifc, freq);
339 else
340 tda827x_tune(c, ifc, freq);
341 /* adjust headroom resp. gain */
342 i2c_master_send(c, &addr_adc_sat, 1);
343 i2c_master_recv(c, &adc_sat, 1);
344 i2c_master_send(c, &addr_agc_stat, 1);
345 i2c_master_recv(c, &agc_stat, 1);
346 i2c_master_send(c, &addr_pll_stat, 1);
347 i2c_master_recv(c, &pll_stat, 1);
348 if (pll_stat & 0x80)
349 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
350 else
351 tuner_dbg("tda8290 not locked, no signal?\n");
352 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
353 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
354 agc_stat, adc_sat, pll_stat & 0x80);
355 i2c_master_send(c, gainset_2, 2);
356 msleep(100);
357 i2c_master_send(c, &addr_agc_stat, 1);
358 i2c_master_recv(c, &agc_stat, 1);
359 i2c_master_send(c, &addr_pll_stat, 1);
360 i2c_master_recv(c, &pll_stat, 1);
361 if ((agc_stat > 115) || !(pll_stat & 0x80)) {
362 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
363 agc_stat, pll_stat & 0x80);
364 if (t->tda827x_ver != 0)
365 tda827xa_agcf(c);
366 else
367 tda827x_agcf(c);
368 msleep(100);
369 i2c_master_send(c, &addr_agc_stat, 1);
370 i2c_master_recv(c, &agc_stat, 1);
371 i2c_master_send(c, &addr_pll_stat, 1);
372 i2c_master_recv(c, &pll_stat, 1);
373 if((agc_stat > 115) || !(pll_stat & 0x80)) {
374 tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
375 i2c_master_send(c, adc_head_12, 2);
376 i2c_master_send(c, pll_bw_low, 2);
377 msleep(100);
378 }
379 }
380 }
381
382 /* l/ l' deadlock? */
383 if(t->tda8290_easy_mode & 0x60) {
384 i2c_master_send(c, &addr_adc_sat, 1);
385 i2c_master_recv(c, &adc_sat, 1);
386 i2c_master_send(c, &addr_pll_stat, 1);
387 i2c_master_recv(c, &pll_stat, 1);
388 if ((adc_sat > 20) || !(pll_stat & 0x80)) {
389 tuner_dbg("trying to resolve SECAM L deadlock\n");
390 i2c_master_send(c, agc_rst_on, 2);
391 msleep(40);
392 i2c_master_send(c, agc_rst_off, 2);
393 }
394 }
395
396 tda8290_i2c_bridge(c, 0);
397 i2c_master_send(c, if_agc_set, 2);
398 return 0;
399}
400
401
402/*---------------------------------------------------------------------*/
403
170#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) 404#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
171#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) 405#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
172#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) 406#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
@@ -174,20 +408,37 @@ static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
174 408
175static void set_audio(struct tuner *t) 409static void set_audio(struct tuner *t)
176{ 410{
177 t->i2c_easy_mode[0] = 0x01; 411 char* mode;
178 412
179 if (t->std & V4L2_STD_MN) 413 t->tda827x_lpsel = 0;
180 t->i2c_easy_mode[1] = 0x01; 414 mode = "xx";
181 else if (t->std & V4L2_STD_B) 415 if (t->std & V4L2_STD_MN) {
182 t->i2c_easy_mode[1] = 0x02; 416 t->sgIF = 92;
183 else if (t->std & V4L2_STD_GH) 417 t->tda8290_easy_mode = 0x01;
184 t->i2c_easy_mode[1] = 0x04; 418 t->tda827x_lpsel = 1;
185 else if (t->std & V4L2_STD_PAL_I) 419 mode = "MN";
186 t->i2c_easy_mode[1] = 0x08; 420 } else if (t->std & V4L2_STD_B) {
187 else if (t->std & V4L2_STD_DK) 421 t->sgIF = 108;
188 t->i2c_easy_mode[1] = 0x10; 422 t->tda8290_easy_mode = 0x02;
189 else if (t->std & V4L2_STD_SECAM_L) 423 mode = "B";
190 t->i2c_easy_mode[1] = 0x20; 424 } else if (t->std & V4L2_STD_GH) {
425 t->sgIF = 124;
426 t->tda8290_easy_mode = 0x04;
427 mode = "GH";
428 } else if (t->std & V4L2_STD_PAL_I) {
429 t->sgIF = 124;
430 t->tda8290_easy_mode = 0x08;
431 mode = "I";
432 } else if (t->std & V4L2_STD_DK) {
433 t->sgIF = 124;
434 t->tda8290_easy_mode = 0x10;
435 mode = "DK";
436 } else if (t->std & V4L2_STD_SECAM_L) {
437 t->sgIF = 124;
438 t->tda8290_easy_mode = 0x20;
439 mode = "L";
440 }
441 tuner_dbg("setting tda8290 to system %s\n", mode);
191} 442}
192 443
193static void set_tv_freq(struct i2c_client *c, unsigned int freq) 444static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -195,15 +446,13 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
195 struct tuner *t = i2c_get_clientdata(c); 446 struct tuner *t = i2c_get_clientdata(c);
196 447
197 set_audio(t); 448 set_audio(t);
198 set_frequency(t, 864, freq); 449 tda8290_tune(c, t->sgIF, freq);
199 tda8290_tune(c);
200} 450}
201 451
202static void set_radio_freq(struct i2c_client *c, unsigned int freq) 452static void set_radio_freq(struct i2c_client *c, unsigned int freq)
203{ 453{
204 struct tuner *t = i2c_get_clientdata(c); 454 /* if frequency is 5.5 MHz */
205 set_frequency(t, 704, freq); 455 tda8290_tune(c, 88, freq);
206 tda8290_tune(c);
207} 456}
208 457
209static int has_signal(struct i2c_client *c) 458static int has_signal(struct i2c_client *c)
@@ -216,27 +465,145 @@ static int has_signal(struct i2c_client *c)
216 return (afc & 0x80)? 65535:0; 465 return (afc & 0x80)? 65535:0;
217} 466}
218 467
468/*---------------------------------------------------------------------*/
469
219static void standby(struct i2c_client *c) 470static void standby(struct i2c_client *c)
220{ 471{
221 i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby)); 472 struct tuner *t = i2c_get_clientdata(c);
473 unsigned char cb1[] = { 0x30, 0xD0 };
474 unsigned char tda8290_standby[] = { 0x00, 0x02 };
475 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
476
477 tda8290_i2c_bridge(c, 1);
478 if (t->tda827x_ver != 0)
479 cb1[1] = 0x90;
480 i2c_transfer(c->adapter, &msg, 1);
481 tda8290_i2c_bridge(c, 0);
482 i2c_master_send(c, tda8290_standby, 2);
222} 483}
223 484
224int tda8290_init(struct i2c_client *c) 485
486static void tda8290_init_if(struct i2c_client *c)
487{
488 unsigned char set_VS[] = { 0x30, 0x6F };
489 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
490
491 i2c_master_send(c, set_VS, 2);
492 i2c_master_send(c, set_GP01_CF, 2);
493}
494
495static void tda8290_init_tuner(struct i2c_client *c)
225{ 496{
226 struct tuner *t = i2c_get_clientdata(c); 497 struct tuner *t = i2c_get_clientdata(c);
498 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
499 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
500 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
501 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
502 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0,
503 .buf=tda8275_init, .len = 14};
504 if (t->tda827x_ver != 0)
505 msg.buf = tda8275a_init;
506
507 tda8290_i2c_bridge(c, 1);
508 i2c_transfer(c->adapter, &msg, 1);
509 tda8290_i2c_bridge(c, 0);
510}
227 511
228 strlcpy(c->name, "tda8290+75", sizeof(c->name)); 512/*---------------------------------------------------------------------*/
513
514int tda8290_init(struct i2c_client *c)
515{
516 struct tuner *t = i2c_get_clientdata(c);
517 u8 data;
518 int i, ret, tuners_found;
519 u32 tuner_addrs;
520 struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1};
521
522 tda8290_i2c_bridge(c, 1);
523 /* probe for tuner chip */
524 tuners_found = 0;
525 tuner_addrs = 0;
526 for (i=0x60; i<= 0x63; i++) {
527 msg.addr = i;
528 ret = i2c_transfer(c->adapter, &msg, 1);
529 if (ret == 1) {
530 tuners_found++;
531 tuner_addrs = (tuner_addrs << 8) + i;
532 }
533 }
534 /* if there is more than one tuner, we expect the right one is
535 behind the bridge and we choose the highest address that doesn't
536 give a response now
537 */
538 tda8290_i2c_bridge(c, 0);
539 if(tuners_found > 1)
540 for (i = 0; i < tuners_found; i++) {
541 msg.addr = tuner_addrs & 0xff;
542 ret = i2c_transfer(c->adapter, &msg, 1);
543 if(ret == 1)
544 tuner_addrs = tuner_addrs >> 8;
545 else
546 break;
547 }
548 if (tuner_addrs == 0) {
549 tuner_addrs = 0x61;
550 tuner_info ("could not clearly identify tuner address, defaulting to %x\n",
551 tuner_addrs);
552 } else {
553 tuner_addrs = tuner_addrs & 0xff;
554 tuner_info ("setting tuner address to %x\n", tuner_addrs);
555 }
556 t->tda827x_addr = tuner_addrs;
557 msg.addr = tuner_addrs;
558
559 tda8290_i2c_bridge(c, 1);
560 ret = i2c_transfer(c->adapter, &msg, 1);
561 if( ret != 1)
562 tuner_warn ("TDA827x access failed!\n");
563 if ((data & 0x3c) == 0) {
564 strlcpy(c->name, "tda8290+75", sizeof(c->name));
565 t->tda827x_ver = 0;
566 } else {
567 strlcpy(c->name, "tda8290+75a", sizeof(c->name));
568 t->tda827x_ver = 2;
569 }
229 tuner_info("tuner: type set to %s\n", c->name); 570 tuner_info("tuner: type set to %s\n", c->name);
571
230 t->tv_freq = set_tv_freq; 572 t->tv_freq = set_tv_freq;
231 t->radio_freq = set_radio_freq; 573 t->radio_freq = set_radio_freq;
232 t->has_signal = has_signal; 574 t->has_signal = has_signal;
233 t->standby = standby; 575 t->standby = standby;
576 t->tda827x_lpsel = 0;
234 577
235 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge)); 578 tda8290_init_tuner(c);
236 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init)); 579 tda8290_init_if(c);
237 return 0; 580 return 0;
238} 581}
239 582
583int tda8290_probe(struct i2c_client *c)
584{
585 unsigned char soft_reset[] = { 0x00, 0x00 };
586 unsigned char easy_mode_b[] = { 0x01, 0x02 };
587 unsigned char easy_mode_g[] = { 0x01, 0x04 };
588 unsigned char addr_dto_lsb = 0x07;
589 unsigned char data;
590
591 i2c_master_send(c, easy_mode_b, 2);
592 i2c_master_send(c, soft_reset, 2);
593 i2c_master_send(c, &addr_dto_lsb, 1);
594 i2c_master_recv(c, &data, 1);
595 if (data == 0) {
596 i2c_master_send(c, easy_mode_g, 2);
597 i2c_master_send(c, soft_reset, 2);
598 i2c_master_send(c, &addr_dto_lsb, 1);
599 i2c_master_recv(c, &data, 1);
600 if (data == 0x7b) {
601 return 0;
602 }
603 }
604 return -1;
605}
606
240/* 607/*
241 * Overrides for Emacs so that we follow Linus's tabbing style. 608 * Overrides for Emacs so that we follow Linus's tabbing style.
242 * --------------------------------------------------------------------------- 609 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 7e3dcdb262b0..a5e37dc91f39 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -32,7 +32,6 @@
32 32
33#include "bttv.h" 33#include "bttv.h"
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36 35
37static int debug; /* insmod parameter */ 36static int debug; /* insmod parameter */
38module_param(debug, int, S_IRUGO | S_IWUSR); 37module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -126,20 +125,20 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v
126 125
127static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) 126static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
128{ 127{
129 unsigned char write[1]; 128 unsigned char write[1];
130 unsigned char read[1]; 129 unsigned char read[1];
131 struct i2c_msg msgs[2] = { 130 struct i2c_msg msgs[2] = {
132 { addr, 0, 1, write }, 131 { addr, 0, 1, write },
133 { addr, I2C_M_RD, 1, read } 132 { addr, I2C_M_RD, 1, read }
134 }; 133 };
135 write[0] = reg; 134 write[0] = reg;
136 135
137 if (2 != i2c_transfer(adap,msgs,2)) { 136 if (2 != i2c_transfer(adap,msgs,2)) {
138 printk(KERN_WARNING "tda9875: I/O error (read2)\n"); 137 printk(KERN_WARNING "tda9875: I/O error (read2)\n");
139 return -1; 138 return -1;
140 } 139 }
141 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); 140 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
142 return read[0]; 141 return read[0];
143} 142}
144 143
145static void tda9875_set(struct i2c_client *client) 144static void tda9875_set(struct i2c_client *client)
@@ -184,7 +183,7 @@ static void do_tda9875_init(struct i2c_client *client)
184 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ 183 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
185 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ 184 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
186 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ 185 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
187 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ 186 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
188 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ 187 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
189 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ 188 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
190 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ 189 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
@@ -200,7 +199,7 @@ static void do_tda9875_init(struct i2c_client *client)
200 199
201 t->mode=AUDIO_UNMUTE; 200 t->mode=AUDIO_UNMUTE;
202 t->lvol=t->rvol =0; /* 0dB */ 201 t->lvol=t->rvol =0; /* 0dB */
203 t->bass=0; /* 0dB */ 202 t->bass=0; /* 0dB */
204 t->treble=0; /* 0dB */ 203 t->treble=0; /* 0dB */
205 tda9875_set(client); 204 tda9875_set(client);
206 205
@@ -239,9 +238,9 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
239 memset(t,0,sizeof *t); 238 memset(t,0,sizeof *t);
240 239
241 client = &t->c; 240 client = &t->c;
242 memcpy(client,&client_template,sizeof(struct i2c_client)); 241 memcpy(client,&client_template,sizeof(struct i2c_client));
243 client->adapter = adap; 242 client->adapter = adap;
244 client->addr = addr; 243 client->addr = addr;
245 i2c_set_clientdata(client, t); 244 i2c_set_clientdata(client, t);
246 245
247 if(!tda9875_checkit(adap,addr)) { 246 if(!tda9875_checkit(adap,addr)) {
@@ -287,7 +286,7 @@ static int tda9875_command(struct i2c_client *client,
287 dprintk("In tda9875_command...\n"); 286 dprintk("In tda9875_command...\n");
288 287
289 switch (cmd) { 288 switch (cmd) {
290 /* --- v4l ioctls --- */ 289 /* --- v4l ioctls --- */
291 /* take care: bttv does userspace copying, we'll get a 290 /* take care: bttv does userspace copying, we'll get a
292 kernel pointer here... */ 291 kernel pointer here... */
293 case VIDIOCGAUDIO: 292 case VIDIOCGAUDIO:
@@ -355,7 +354,7 @@ static int tda9875_command(struct i2c_client *client,
355//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); 354//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
356 355
357 356
358 tda9875_set(client); 357 tda9875_set(client);
359 358
360 break; 359 break;
361 360
@@ -374,18 +373,18 @@ static int tda9875_command(struct i2c_client *client,
374 373
375static struct i2c_driver driver = { 374static struct i2c_driver driver = {
376 .owner = THIS_MODULE, 375 .owner = THIS_MODULE,
377 .name = "i2c tda9875 driver", 376 .name = "i2c tda9875 driver",
378 .id = I2C_DRIVERID_TDA9875, 377 .id = I2C_DRIVERID_TDA9875,
379 .flags = I2C_DF_NOTIFY, 378 .flags = I2C_DF_NOTIFY,
380 .attach_adapter = tda9875_probe, 379 .attach_adapter = tda9875_probe,
381 .detach_client = tda9875_detach, 380 .detach_client = tda9875_detach,
382 .command = tda9875_command, 381 .command = tda9875_command,
383}; 382};
384 383
385static struct i2c_client client_template = 384static struct i2c_client client_template =
386{ 385{
387 .name = "tda9875", 386 .name = "tda9875",
388 .driver = &driver, 387 .driver = &driver,
389}; 388};
390 389
391static int __init tda9875_init(void) 390static int __init tda9875_init(void)
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 94053f149ddf..4249127c0a1d 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -11,7 +11,6 @@
11 11
12#include <media/audiochip.h> 12#include <media/audiochip.h>
13#include <media/tuner.h> 13#include <media/tuner.h>
14#include <media/id.h>
15 14
16/* Chips: 15/* Chips:
17 TDA9885 (PAL, NTSC) 16 TDA9885 (PAL, NTSC)
@@ -44,8 +43,13 @@ MODULE_LICENSE("GPL");
44/* ---------------------------------------------------------------------- */ 43/* ---------------------------------------------------------------------- */
45 44
46#define UNSET (-1U) 45#define UNSET (-1U)
47#define PREFIX "tda9885/6/7: " 46#define tda9887_info(fmt, arg...) do {\
48#define dprintk if (debug) printk 47 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
48 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49#define tda9887_dbg(fmt, arg...) do {\
50 if (debug) \
51 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
52 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49 53
50struct tda9887 { 54struct tda9887 {
51 struct i2c_client client; 55 struct i2c_client client;
@@ -55,6 +59,7 @@ struct tda9887 {
55 unsigned int pinnacle_id; 59 unsigned int pinnacle_id;
56 unsigned int using_v4l2; 60 unsigned int using_v4l2;
57 unsigned int radio_mode; 61 unsigned int radio_mode;
62 unsigned char data[4];
58}; 63};
59 64
60struct tvnorm { 65struct tvnorm {
@@ -180,7 +185,8 @@ static struct tvnorm tvnorms[] = {
180 .name = "SECAM-L", 185 .name = "SECAM-L",
181 .b = ( cPositiveAmTV | 186 .b = ( cPositiveAmTV |
182 cQSS ), 187 cQSS ),
183 .e = ( cAudioIF_6_5 | 188 .e = ( cGating_36 |
189 cAudioIF_6_5 |
184 cVideoIF_38_90 ), 190 cVideoIF_38_90 ),
185 },{ 191 },{
186 .std = V4L2_STD_SECAM_DK, 192 .std = V4L2_STD_SECAM_DK,
@@ -236,7 +242,7 @@ static struct tvnorm radio_mono = {
236 242
237/* ---------------------------------------------------------------------- */ 243/* ---------------------------------------------------------------------- */
238 244
239static void dump_read_message(unsigned char *buf) 245static void dump_read_message(struct tda9887 *t, unsigned char *buf)
240{ 246{
241 static char *afc[16] = { 247 static char *afc[16] = {
242 "- 12.5 kHz", 248 "- 12.5 kHz",
@@ -256,15 +262,15 @@ static void dump_read_message(unsigned char *buf)
256 "+ 37.5 kHz", 262 "+ 37.5 kHz",
257 "+ 12.5 kHz", 263 "+ 12.5 kHz",
258 }; 264 };
259 printk(PREFIX "read: 0x%2x\n", buf[0]); 265 tda9887_info("read: 0x%2x\n", buf[0]);
260 printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); 266 tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
261 printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); 267 tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
262 printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low"); 268 tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
263 printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); 269 tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
264 printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); 270 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
265} 271}
266 272
267static void dump_write_message(unsigned char *buf) 273static void dump_write_message(struct tda9887 *t, unsigned char *buf)
268{ 274{
269 static char *sound[4] = { 275 static char *sound[4] = {
270 "AM/TV", 276 "AM/TV",
@@ -304,58 +310,58 @@ static void dump_write_message(unsigned char *buf)
304 "44 MHz", 310 "44 MHz",
305 }; 311 };
306 312
307 printk(PREFIX "write: byte B 0x%02x\n",buf[1]); 313 tda9887_info("write: byte B 0x%02x\n",buf[1]);
308 printk(" B0 video mode : %s\n", 314 tda9887_info(" B0 video mode : %s\n",
309 (buf[1] & 0x01) ? "video trap" : "sound trap"); 315 (buf[1] & 0x01) ? "video trap" : "sound trap");
310 printk(" B1 auto mute fm : %s\n", 316 tda9887_info(" B1 auto mute fm : %s\n",
311 (buf[1] & 0x02) ? "yes" : "no"); 317 (buf[1] & 0x02) ? "yes" : "no");
312 printk(" B2 carrier mode : %s\n", 318 tda9887_info(" B2 carrier mode : %s\n",
313 (buf[1] & 0x04) ? "QSS" : "Intercarrier"); 319 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
314 printk(" B3-4 tv sound/radio : %s\n", 320 tda9887_info(" B3-4 tv sound/radio : %s\n",
315 sound[(buf[1] & 0x18) >> 3]); 321 sound[(buf[1] & 0x18) >> 3]);
316 printk(" B5 force mute audio: %s\n", 322 tda9887_info(" B5 force mute audio: %s\n",
317 (buf[1] & 0x20) ? "yes" : "no"); 323 (buf[1] & 0x20) ? "yes" : "no");
318 printk(" B6 output port 1 : %s\n", 324 tda9887_info(" B6 output port 1 : %s\n",
319 (buf[1] & 0x40) ? "high (inactive)" : "low (active)"); 325 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
320 printk(" B7 output port 2 : %s\n", 326 tda9887_info(" B7 output port 2 : %s\n",
321 (buf[1] & 0x80) ? "high (inactive)" : "low (active)"); 327 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
322 328
323 printk(PREFIX "write: byte C 0x%02x\n",buf[2]); 329 tda9887_info("write: byte C 0x%02x\n",buf[2]);
324 printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); 330 tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
325 printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); 331 tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
326 printk(" C7 audio gain : %s\n", 332 tda9887_info(" C7 audio gain : %s\n",
327 (buf[2] & 0x80) ? "-6" : "0"); 333 (buf[2] & 0x80) ? "-6" : "0");
328 334
329 printk(PREFIX "write: byte E 0x%02x\n",buf[3]); 335 tda9887_info("write: byte E 0x%02x\n",buf[3]);
330 printk(" E0-1 sound carrier : %s\n", 336 tda9887_info(" E0-1 sound carrier : %s\n",
331 carrier[(buf[3] & 0x03)]); 337 carrier[(buf[3] & 0x03)]);
332 printk(" E6 l pll ganting : %s\n", 338 tda9887_info(" E6 l pll gating : %s\n",
333 (buf[3] & 0x40) ? "36" : "13"); 339 (buf[3] & 0x40) ? "36" : "13");
334 340
335 if (buf[1] & 0x08) { 341 if (buf[1] & 0x08) {
336 /* radio */ 342 /* radio */
337 printk(" E2-4 video if : %s\n", 343 tda9887_info(" E2-4 video if : %s\n",
338 rif[(buf[3] & 0x0c) >> 2]); 344 rif[(buf[3] & 0x0c) >> 2]);
339 printk(" E7 vif agc output : %s\n", 345 tda9887_info(" E7 vif agc output : %s\n",
340 (buf[3] & 0x80) 346 (buf[3] & 0x80)
341 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") 347 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
342 : "fm radio carrier afc"); 348 : "fm radio carrier afc");
343 } else { 349 } else {
344 /* video */ 350 /* video */
345 printk(" E2-4 video if : %s\n", 351 tda9887_info(" E2-4 video if : %s\n",
346 vif[(buf[3] & 0x1c) >> 2]); 352 vif[(buf[3] & 0x1c) >> 2]);
347 printk(" E5 tuner gain : %s\n", 353 tda9887_info(" E5 tuner gain : %s\n",
348 (buf[3] & 0x80) 354 (buf[3] & 0x80)
349 ? ((buf[3] & 0x20) ? "external" : "normal") 355 ? ((buf[3] & 0x20) ? "external" : "normal")
350 : ((buf[3] & 0x20) ? "minimum" : "normal")); 356 : ((buf[3] & 0x20) ? "minimum" : "normal"));
351 printk(" E7 vif agc output : %s\n", 357 tda9887_info(" E7 vif agc output : %s\n",
352 (buf[3] & 0x80) 358 (buf[3] & 0x80)
353 ? ((buf[3] & 0x20) 359 ? ((buf[3] & 0x20)
354 ? "pin3 port, pin22 vif agc out" 360 ? "pin3 port, pin22 vif agc out"
355 : "pin22 port, pin3 vif acg ext in") 361 : "pin22 port, pin3 vif acg ext in")
356 : "pin3+pin22 port"); 362 : "pin3+pin22 port");
357 } 363 }
358 printk("--\n"); 364 tda9887_info("--\n");
359} 365}
360 366
361/* ---------------------------------------------------------------------- */ 367/* ---------------------------------------------------------------------- */
@@ -379,11 +385,11 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
379 } 385 }
380 } 386 }
381 if (NULL == norm) { 387 if (NULL == norm) {
382 dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n"); 388 tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
383 return -1; 389 return -1;
384 } 390 }
385 391
386 dprintk(PREFIX "configure for: %s\n",norm->name); 392 tda9887_dbg("configure for: %s\n",norm->name);
387 buf[1] = norm->b; 393 buf[1] = norm->b;
388 buf[2] = norm->c; 394 buf[2] = norm->c;
389 buf[3] = norm->e; 395 buf[3] = norm->e;
@@ -458,6 +464,8 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
458 break; 464 break;
459 } 465 }
460 } 466 }
467 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
468 buf[1] &= ~cQSS;
461 return 0; 469 return 0;
462} 470}
463 471
@@ -475,11 +483,11 @@ static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
475 } 483 }
476 } 484 }
477 if (t->std & V4L2_STD_525_60) { 485 if (t->std & V4L2_STD_525_60) {
478 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { 486 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
479 bCarrierMode = cIntercarrier; 487 bCarrierMode = cIntercarrier;
480 } else { 488 } else {
481 bCarrierMode = cQSS; 489 bCarrierMode = cQSS;
482 } 490 }
483 } 491 }
484 492
485 if (bCarrierMode != UNSET) { 493 if (bCarrierMode != UNSET) {
@@ -505,26 +513,26 @@ static int tda9887_fixup_std(struct tda9887 *t)
505 case 'B': 513 case 'B':
506 case 'g': 514 case 'g':
507 case 'G': 515 case 'G':
508 dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n"); 516 tda9887_dbg("insmod fixup: PAL => PAL-BG\n");
509 t->std = V4L2_STD_PAL_BG; 517 t->std = V4L2_STD_PAL_BG;
510 break; 518 break;
511 case 'i': 519 case 'i':
512 case 'I': 520 case 'I':
513 dprintk(PREFIX "insmod fixup: PAL => PAL-I\n"); 521 tda9887_dbg("insmod fixup: PAL => PAL-I\n");
514 t->std = V4L2_STD_PAL_I; 522 t->std = V4L2_STD_PAL_I;
515 break; 523 break;
516 case 'd': 524 case 'd':
517 case 'D': 525 case 'D':
518 case 'k': 526 case 'k':
519 case 'K': 527 case 'K':
520 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n"); 528 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
521 t->std = V4L2_STD_PAL_DK; 529 t->std = V4L2_STD_PAL_DK;
522 break; 530 break;
523 case '-': 531 case '-':
524 /* default parameter, do nothing */ 532 /* default parameter, do nothing */
525 break; 533 break;
526 default: 534 default:
527 printk(PREFIX "pal= argument not recognised\n"); 535 tda9887_info("pal= argument not recognised\n");
528 break; 536 break;
529 } 537 }
530 } 538 }
@@ -534,19 +542,19 @@ static int tda9887_fixup_std(struct tda9887 *t)
534 case 'D': 542 case 'D':
535 case 'k': 543 case 'k':
536 case 'K': 544 case 'K':
537 dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n"); 545 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
538 t->std = V4L2_STD_SECAM_DK; 546 t->std = V4L2_STD_SECAM_DK;
539 break; 547 break;
540 case 'l': 548 case 'l':
541 case 'L': 549 case 'L':
542 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n"); 550 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
543 t->std = V4L2_STD_SECAM_L; 551 t->std = V4L2_STD_SECAM_L;
544 break; 552 break;
545 case '-': 553 case '-':
546 /* default parameter, do nothing */ 554 /* default parameter, do nothing */
547 break; 555 break;
548 default: 556 default:
549 printk(PREFIX "secam= argument not recognised\n"); 557 tda9887_info("secam= argument not recognised\n");
550 break; 558 break;
551 } 559 }
552 } 560 }
@@ -559,41 +567,40 @@ static int tda9887_status(struct tda9887 *t)
559 int rc; 567 int rc;
560 568
561 memset(buf,0,sizeof(buf)); 569 memset(buf,0,sizeof(buf));
562 if (1 != (rc = i2c_master_recv(&t->client,buf,1))) 570 if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
563 printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); 571 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
564 dump_read_message(buf); 572 dump_read_message(t, buf);
565 return 0; 573 return 0;
566} 574}
567 575
568static int tda9887_configure(struct tda9887 *t) 576static int tda9887_configure(struct tda9887 *t)
569{ 577{
570 unsigned char buf[4];
571 int rc; 578 int rc;
572 579
573 memset(buf,0,sizeof(buf)); 580 memset(t->data,0,sizeof(t->data));
574 tda9887_set_tvnorm(t,buf); 581 tda9887_set_tvnorm(t,t->data);
575 582
576 buf[1] |= cOutputPort1Inactive; 583 t->data[1] |= cOutputPort1Inactive;
577 buf[1] |= cOutputPort2Inactive; 584 t->data[1] |= cOutputPort2Inactive;
578 585
579 if (UNSET != t->pinnacle_id) { 586 if (UNSET != t->pinnacle_id) {
580 tda9887_set_pinnacle(t,buf); 587 tda9887_set_pinnacle(t,t->data);
581 } 588 }
582 tda9887_set_config(t,buf); 589 tda9887_set_config(t,t->data);
583 tda9887_set_insmod(t,buf); 590 tda9887_set_insmod(t,t->data);
584 591
585 if (t->mode == T_STANDBY) { 592 if (t->mode == T_STANDBY) {
586 buf[1] |= cForcedMuteAudioON; 593 t->data[1] |= cForcedMuteAudioON;
587 } 594 }
588 595
589 596
590 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", 597 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
591 buf[1],buf[2],buf[3]); 598 t->data[1],t->data[2],t->data[3]);
592 if (debug > 1) 599 if (debug > 1)
593 dump_write_message(buf); 600 dump_write_message(t, t->data);
594 601
595 if (4 != (rc = i2c_master_send(&t->client,buf,4))) 602 if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
596 printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc); 603 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
597 604
598 if (debug > 2) { 605 if (debug > 2) {
599 msleep_interruptible(1000); 606 msleep_interruptible(1000);
@@ -608,13 +615,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
608{ 615{
609 struct tda9887 *t; 616 struct tda9887 *t;
610 617
611 client_template.adapter = adap; 618 client_template.adapter = adap;
612 client_template.addr = addr; 619 client_template.addr = addr;
613
614 printk(PREFIX "chip found @ 0x%x\n", addr<<1);
615 620
616 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 621 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
617 return -ENOMEM; 622 return -ENOMEM;
618 memset(t,0,sizeof(*t)); 623 memset(t,0,sizeof(*t));
619 624
620 t->client = client_template; 625 t->client = client_template;
@@ -622,6 +627,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
622 t->pinnacle_id = UNSET; 627 t->pinnacle_id = UNSET;
623 t->radio_mode = V4L2_TUNER_MODE_STEREO; 628 t->radio_mode = V4L2_TUNER_MODE_STEREO;
624 629
630 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
631
625 i2c_set_clientdata(&t->client, t); 632 i2c_set_clientdata(&t->client, t);
626 i2c_attach_client(&t->client); 633 i2c_attach_client(&t->client);
627 634
@@ -655,18 +662,18 @@ static int tda9887_detach(struct i2c_client *client)
655} 662}
656 663
657#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ 664#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
658 printk(PREFIX "switching to v4l2\n"); \ 665 tda9887_info("switching to v4l2\n"); \
659 t->using_v4l2 = 1; 666 t->using_v4l2 = 1;
660#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ 667#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
661 printk(PREFIX "ignore v4l1 call\n"); \ 668 tda9887_info("ignore v4l1 call\n"); \
662 return 0; } 669 return 0; }
663 670
664static int 671static int
665tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) 672tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
666{ 673{
667 struct tda9887 *t = i2c_get_clientdata(client); 674 struct tda9887 *t = i2c_get_clientdata(client);
668 675
669 switch (cmd) { 676 switch (cmd) {
670 677
671 /* --- configuration --- */ 678 /* --- configuration --- */
672 case AUDC_SET_RADIO: 679 case AUDC_SET_RADIO:
@@ -777,6 +784,11 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
777 } 784 }
778 break; 785 break;
779 } 786 }
787 case VIDIOC_LOG_STATUS:
788 {
789 tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]);
790 break;
791 }
780 default: 792 default:
781 /* nothing */ 793 /* nothing */
782 break; 794 break;
@@ -786,7 +798,10 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
786 798
787static int tda9887_suspend(struct device * dev, pm_message_t state) 799static int tda9887_suspend(struct device * dev, pm_message_t state)
788{ 800{
789 dprintk("tda9887: suspend\n"); 801 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
802 struct tda9887 *t = i2c_get_clientdata(c);
803
804 tda9887_dbg("suspend\n");
790 return 0; 805 return 0;
791} 806}
792 807
@@ -795,7 +810,7 @@ static int tda9887_resume(struct device * dev)
795 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 810 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
796 struct tda9887 *t = i2c_get_clientdata(c); 811 struct tda9887 *t = i2c_get_clientdata(c);
797 812
798 dprintk("tda9887: resume\n"); 813 tda9887_dbg("resume\n");
799 tda9887_configure(t); 814 tda9887_configure(t);
800 return 0; 815 return 0;
801} 816}
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index 38bf50943798..a9375ef05de1 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -117,10 +117,10 @@
117#define TEA5767_RESERVED_MASK 0xff 117#define TEA5767_RESERVED_MASK 0xff
118 118
119enum tea5767_xtal_freq { 119enum tea5767_xtal_freq {
120 TEA5767_LOW_LO_32768 = 0, 120 TEA5767_LOW_LO_32768 = 0,
121 TEA5767_HIGH_LO_32768 = 1, 121 TEA5767_HIGH_LO_32768 = 1,
122 TEA5767_LOW_LO_13MHz = 2, 122 TEA5767_LOW_LO_13MHz = 2,
123 TEA5767_HIGH_LO_13MHz = 3, 123 TEA5767_HIGH_LO_13MHz = 3,
124}; 124};
125 125
126 126
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index ad85bef1c3d5..73c4041c35d7 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -28,7 +28,7 @@
28 28
29/* standard i2c insmod options */ 29/* standard i2c insmod options */
30static unsigned short normal_i2c[] = { 30static unsigned short normal_i2c[] = {
31 0x4b, /* tda8290 */ 31 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
34 I2C_CLIENT_END 34 I2C_CLIENT_END
@@ -189,6 +189,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
189 i2c_master_send(c, buffer, 4); 189 i2c_master_send(c, buffer, 4);
190 default_tuner_init(c); 190 default_tuner_init(c);
191 break; 191 break;
192 case TUNER_PHILIPS_TD1316:
193 buffer[0] = 0x0b;
194 buffer[1] = 0xdc;
195 buffer[2] = 0x86;
196 buffer[3] = 0xa4;
197 i2c_master_send(c,buffer,4);
198 default_tuner_init(c);
192 default: 199 default:
193 default_tuner_init(c); 200 default_tuner_init(c);
194 break; 201 break;
@@ -215,9 +222,9 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
215{ 222{
216 struct tuner *t = i2c_get_clientdata(c); 223 struct tuner *t = i2c_get_clientdata(c);
217 224
218 if ((tun_setup->addr == ADDR_UNSET && 225 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
219 (t->mode_mask & tun_setup->mode_mask)) || 226 (t->mode_mask & tun_setup->mode_mask)) ||
220 tun_setup->addr == c->addr) { 227 tun_setup->addr == c->addr)) {
221 set_type(c, tun_setup->type, tun_setup->mode_mask); 228 set_type(c, tun_setup->type, tun_setup->mode_mask);
222 } 229 }
223} 230}
@@ -341,23 +348,33 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
341 t->audmode = V4L2_TUNER_MODE_STEREO; 348 t->audmode = V4L2_TUNER_MODE_STEREO;
342 t->mode_mask = T_UNINITIALIZED; 349 t->mode_mask = T_UNINITIALIZED;
343 350
344
345 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
346
347 if (show_i2c) { 351 if (show_i2c) {
348 unsigned char buffer[16]; 352 unsigned char buffer[16];
349 int i,rc; 353 int i,rc;
350 354
351 memset(buffer, 0, sizeof(buffer)); 355 memset(buffer, 0, sizeof(buffer));
352 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer)); 356 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
353 printk("tuner-%04x I2C RECV = ",addr); 357 tuner_info("I2C RECV = ");
354 for (i=0;i<rc;i++) 358 for (i=0;i<rc;i++)
355 printk("%02x ",buffer[i]); 359 printk("%02x ",buffer[i]);
356 printk("\n"); 360 printk("\n");
357 } 361 }
358 /* TEA5767 autodetection code - only for addr = 0xc0 */ 362 /* TEA5767 autodetection code - only for addr = 0xc0 */
359 if (!no_autodetect) { 363 if (!no_autodetect) {
360 if (addr == 0x60) { 364 switch (addr) {
365 case 0x42:
366 case 0x43:
367 case 0x4a:
368 case 0x4b:
369 /* If chip is not tda8290, don't register.
370 since it can be tda9887*/
371 if (tda8290_probe(&t->i2c) != 0) {
372 tuner_dbg("chip at addr %x is not a tda8290\n", addr);
373 kfree(t);
374 return 0;
375 }
376 break;
377 case 0x60:
361 if (tea5767_autodetection(&t->i2c) != EINVAL) { 378 if (tea5767_autodetection(&t->i2c) != EINVAL) {
362 t->type = TUNER_TEA5767; 379 t->type = TUNER_TEA5767;
363 t->mode_mask = T_RADIO; 380 t->mode_mask = T_RADIO;
@@ -365,10 +382,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
365 t->freq = 87.5 * 16; /* Sets freq to FM range */ 382 t->freq = 87.5 * 16; /* Sets freq to FM range */
366 default_mode_mask &= ~T_RADIO; 383 default_mode_mask &= ~T_RADIO;
367 384
368 i2c_attach_client (&t->i2c); 385 goto register_client;
369 set_type(&t->i2c,t->type, t->mode_mask);
370 return 0;
371 } 386 }
387 break;
372 } 388 }
373 } 389 }
374 390
@@ -381,6 +397,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
381 } 397 }
382 398
383 /* Should be just before return */ 399 /* Should be just before return */
400register_client:
401 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
384 i2c_attach_client (&t->i2c); 402 i2c_attach_client (&t->i2c);
385 set_type (&t->i2c,t->type, t->mode_mask); 403 set_type (&t->i2c,t->type, t->mode_mask);
386 return 0; 404 return 0;
@@ -425,23 +443,23 @@ static int tuner_detach(struct i2c_client *client)
425 443
426static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) 444static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
427{ 445{
428 if (mode == t->mode) 446 if (mode == t->mode)
429 return 0; 447 return 0;
430 448
431 t->mode = mode; 449 t->mode = mode;
432 450
433 if (check_mode(t, cmd) == EINVAL) { 451 if (check_mode(t, cmd) == EINVAL) {
434 t->mode = T_STANDBY; 452 t->mode = T_STANDBY;
435 if (t->standby) 453 if (t->standby)
436 t->standby (client); 454 t->standby (client);
437 return EINVAL; 455 return EINVAL;
438 } 456 }
439 return 0; 457 return 0;
440} 458}
441 459
442#define switch_v4l2() if (!t->using_v4l2) \ 460#define switch_v4l2() if (!t->using_v4l2) \
443 tuner_dbg("switching to v4l2\n"); \ 461 tuner_dbg("switching to v4l2\n"); \
444 t->using_v4l2 = 1; 462 t->using_v4l2 = 1;
445 463
446static inline int check_v4l2(struct tuner *t) 464static inline int check_v4l2(struct tuner *t)
447{ 465{
@@ -479,8 +497,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
479 break; 497 break;
480 } 498 }
481 case AUDC_CONFIG_PINNACLE: 499 case AUDC_CONFIG_PINNACLE:
482 if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
483 return 0;
484 switch (*iarg) { 500 switch (*iarg) {
485 case 2: 501 case 2:
486 tuner_dbg("pinnacle pal\n"); 502 tuner_dbg("pinnacle pal\n");
@@ -616,7 +632,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
616 switch_v4l2(); 632 switch_v4l2();
617 if (V4L2_TUNER_RADIO == f->type && 633 if (V4L2_TUNER_RADIO == f->type &&
618 V4L2_TUNER_RADIO != t->mode) { 634 V4L2_TUNER_RADIO != t->mode) {
619 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") 635 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
620 == EINVAL) 636 == EINVAL)
621 return 0; 637 return 0;
622 } 638 }
@@ -688,7 +704,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
688 break; 704 break;
689 } 705 }
690 default: 706 default:
691 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n", 707 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n",
692 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), 708 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
693 _IOC_NR(cmd), _IOC_SIZE(cmd)); 709 _IOC_NR(cmd), _IOC_SIZE(cmd));
694 break; 710 break;
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 8edd73abe1d8..d832205818f2 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -102,7 +102,7 @@ struct tunertype
102 */ 102 */
103static struct tunertype tuners[] = { 103static struct tunertype tuners[] = {
104 /* 0-9 */ 104 /* 0-9 */
105 { "Temic PAL (4002 FH5)", TEMIC, PAL, 105 { "Temic PAL (4002 FH5)", TEMIC, PAL,
106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, 106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, 107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
@@ -118,41 +118,41 @@ static struct tunertype tuners[] = {
118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, 118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, 119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, 120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC, 121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, 122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
123 { "Alps HSBH1", TEMIC, NTSC, 123 { "Alps HSBH1", TEMIC, NTSC,
124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
125 125
126 /* 10-19 */ 126 /* 10-19 */
127 { "Alps TSBE1", TEMIC, PAL, 127 { "Alps TSBE1", TEMIC, PAL,
128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ 129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, 130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, 132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, 134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL, 135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
137 { "Alps TSCH6", Alps, NTSC, 137 { "Alps TSCH6", Alps, NTSC,
138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, 138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, 139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, 140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
141 { "Philips NTSC_M (MK2)", Philips, NTSC, 141 { "Philips NTSC_M (MK2)", Philips, NTSC,
142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, 143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, 145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
147 147
148 /* 20-29 */ 148 /* 20-29 */
149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, 149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC, 151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, 153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, 155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, 157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
@@ -173,21 +173,21 @@ static struct tunertype tuners[] = {
173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ 173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, 174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ 175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
176 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, 176 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
177 { "MT20xx universal", Microtune, PAL|NTSC, 177 { "MT20xx universal", Microtune, PAL|NTSC,
178 /* see mt20xx.c for details */ }, 178 /* see mt20xx.c for details */ },
179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, 179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, 181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, 182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC, 183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, 185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, 186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, 187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
188 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 188 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, 189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, 190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
191 191
192 /* 40-49 */ 192 /* 40-49 */
193 { "HITACHI V7-J180AT", HITACHI, NTSC, 193 { "HITACHI V7-J180AT", HITACHI, NTSC,
@@ -196,24 +196,24 @@ static struct tunertype tuners[] = {
196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, 196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, 197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, 198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, 199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, 201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
203 { "Microtune 4049 FM5", Microtune, PAL, 203 { "Microtune 4049 FM5", Microtune, PAL,
204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, 204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, 205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, 206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, 207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
209 { "Tenna TNF 8831 BGFF)", Philips, PAL, 209 { "Tenna TNF 8831 BGFF)", Philips, PAL,
210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, 211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, 212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
213 213
214 /* 50-59 */ 214 /* 50-59 */
215 { "TCL 2002N", TCL, NTSC, 215 { "TCL 2002N", TCL, NTSC,
216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, 216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, 217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, 219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
@@ -222,8 +222,8 @@ static struct tunertype tuners[] = {
222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ 222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */
223 { "tda8290+75", Philips, PAL|NTSC, 223 { "tda8290+75", Philips, PAL|NTSC,
224 /* see tda8290.c for details */ }, 224 /* see tda8290.c for details */ },
225 { "LG PAL (TAPE series)", LGINNOTEK, PAL, 225 { "TCL 2002MB", TCL, PAL,
226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, 226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, 227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, 228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
229 { "Philips FQ1236A MK4", Philips, NTSC, 229 { "Philips FQ1236A MK4", Philips, NTSC,
@@ -233,21 +233,25 @@ static struct tunertype tuners[] = {
233 { "Ymec TVision TVF-5533MF", Philips, NTSC, 233 { "Ymec TVision TVF-5533MF", Philips, NTSC,
234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, 234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
235 235
236 /* 60-66 */ 236 /* 60-68 */
237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, 239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, 240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
241 { "Philips TEA5767HN FM Radio", Philips, RADIO, 241 { "Philips TEA5767HN FM Radio", Philips, RADIO,
242 /* see tea5767.c for details */}, 242 /* see tea5767.c for details */},
243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, 243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, 244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, 245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, 246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
247 { "Ymec TVF66T5-B/DFF", Philips, PAL, 247 { "Ymec TVF66T5-B/DFF", Philips, PAL,
248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, 248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, 249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, 250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
251 { "Philips TD1316 Hybrid Tuner", Philips, PAL,
252 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
253 { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
254 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
251}; 255};
252 256
253unsigned const int tuner_count = ARRAY_SIZE(tuners); 257unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -277,7 +281,7 @@ static int tuner_stereo(struct i2c_client *c)
277 status = tuner_getstatus (c); 281 status = tuner_getstatus (c);
278 282
279 switch (t->type) { 283 switch (t->type) {
280 case TUNER_PHILIPS_FM1216ME_MK3: 284 case TUNER_PHILIPS_FM1216ME_MK3:
281 case TUNER_PHILIPS_FM1236_MK3: 285 case TUNER_PHILIPS_FM1236_MK3:
282 case TUNER_PHILIPS_FM1256_IH3: 286 case TUNER_PHILIPS_FM1256_IH3:
283 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); 287 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
@@ -295,10 +299,10 @@ static int tuner_stereo(struct i2c_client *c)
295static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) 299static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
296{ 300{
297 struct tuner *t = i2c_get_clientdata(c); 301 struct tuner *t = i2c_get_clientdata(c);
298 u8 config; 302 u8 config, tuneraddr;
299 u16 div; 303 u16 div;
300 struct tunertype *tun; 304 struct tunertype *tun;
301 unsigned char buffer[4]; 305 unsigned char buffer[4];
302 int rc; 306 int rc;
303 307
304 tun = &tuners[t->type]; 308 tun = &tuners[t->type];
@@ -373,6 +377,31 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
373 /* Set the charge pump for fast tuning */ 377 /* Set the charge pump for fast tuning */
374 tun->config |= TUNER_CHARGE_PUMP; 378 tun->config |= TUNER_CHARGE_PUMP;
375 break; 379 break;
380
381 case TUNER_PHILIPS_TUV1236D:
382 /* 0x40 -> ATSC antenna input 1 */
383 /* 0x48 -> ATSC antenna input 2 */
384 /* 0x00 -> NTSC antenna input 1 */
385 /* 0x08 -> NTSC antenna input 2 */
386 buffer[0] = 0x14;
387 buffer[1] = 0x00;
388 buffer[2] = 0x17;
389 buffer[3] = 0x00;
390 config &= ~0x40;
391 if (t->std & V4L2_STD_ATSC) {
392 config |= 0x40;
393 buffer[1] = 0x04;
394 }
395 /* set to the correct mode (analog or digital) */
396 tuneraddr = c->addr;
397 c->addr = 0x0a;
398 if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
399 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
400 if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
401 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
402 c->addr = tuneraddr;
403 /* FIXME: input */
404 break;
376 } 405 }
377 406
378 /* 407 /*
@@ -404,7 +433,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
404 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", 433 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
405 buffer[0],buffer[1],buffer[2],buffer[3]); 434 buffer[0],buffer[1],buffer[2],buffer[3]);
406 435
407 if (4 != (rc = i2c_master_send(c,buffer,4))) 436 if (4 != (rc = i2c_master_send(c,buffer,4)))
408 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 437 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
409 438
410 if (t->type == TUNER_MICROTUNE_4042FI5) { 439 if (t->type == TUNER_MICROTUNE_4042FI5) {
@@ -443,7 +472,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
443{ 472{
444 struct tunertype *tun; 473 struct tunertype *tun;
445 struct tuner *t = i2c_get_clientdata(c); 474 struct tuner *t = i2c_get_clientdata(c);
446 unsigned char buffer[4]; 475 unsigned char buffer[4];
447 unsigned div; 476 unsigned div;
448 int rc; 477 int rc;
449 478
@@ -476,13 +505,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
476 buffer[3] = 0xa4; 505 buffer[3] = 0xa4;
477 break; 506 break;
478 } 507 }
479 buffer[0] = (div>>8) & 0x7f; 508 buffer[0] = (div>>8) & 0x7f;
480 buffer[1] = div & 0xff; 509 buffer[1] = div & 0xff;
481 510
482 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", 511 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
483 buffer[0],buffer[1],buffer[2],buffer[3]); 512 buffer[0],buffer[1],buffer[2],buffer[3]);
484 513
485 if (4 != (rc = i2c_master_send(c,buffer,4))) 514 if (4 != (rc = i2c_master_send(c,buffer,4)))
486 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 515 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
487} 516}
488 517
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 1c31ef52f863..c31bf28b73fe 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -31,7 +31,6 @@
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32 32
33#include <media/audiochip.h> 33#include <media/audiochip.h>
34#include <media/id.h>
35 34
36#include "tvaudio.h" 35#include "tvaudio.h"
37 36
@@ -458,8 +457,8 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
458#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */ 457#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
459#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */ 458#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
460 /* Bits 0 to 3 select various combinations 459 /* Bits 0 to 3 select various combinations
461 * of line in and line out, only the 460 * of line in and line out, only the
462 * interesting ones are defined */ 461 * interesting ones are defined */
463#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */ 462#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
464#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */ 463#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
465 464
@@ -1028,7 +1027,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1028#define TEA6300_TR 0x03 /* treble */ 1027#define TEA6300_TR 0x03 /* treble */
1029#define TEA6300_FA 0x04 /* fader control */ 1028#define TEA6300_FA 0x04 /* fader control */
1030#define TEA6300_S 0x05 /* switch register */ 1029#define TEA6300_S 0x05 /* switch register */
1031 /* values for those registers: */ 1030 /* values for those registers: */
1032#define TEA6300_S_SA 0x01 /* stereo A input */ 1031#define TEA6300_S_SA 0x01 /* stereo A input */
1033#define TEA6300_S_SB 0x02 /* stereo B */ 1032#define TEA6300_S_SB 0x02 /* stereo B */
1034#define TEA6300_S_SC 0x04 /* stereo C */ 1033#define TEA6300_S_SC 0x04 /* stereo C */
@@ -1042,7 +1041,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1042#define TEA6320_BA 0x05 /* bass (0-4) */ 1041#define TEA6320_BA 0x05 /* bass (0-4) */
1043#define TEA6320_TR 0x06 /* treble (0-4) */ 1042#define TEA6320_TR 0x06 /* treble (0-4) */
1044#define TEA6320_S 0x07 /* switch register */ 1043#define TEA6320_S 0x07 /* switch register */
1045 /* values for those registers: */ 1044 /* values for those registers: */
1046#define TEA6320_S_SA 0x07 /* stereo A input */ 1045#define TEA6320_S_SA 0x07 /* stereo A input */
1047#define TEA6320_S_SB 0x06 /* stereo B */ 1046#define TEA6320_S_SB 0x06 /* stereo B */
1048#define TEA6320_S_SC 0x05 /* stereo C */ 1047#define TEA6320_S_SC 0x05 /* stereo C */
@@ -1082,7 +1081,7 @@ static int tea6320_initialize(struct CHIPSTATE * chip)
1082#define TDA8425_BA 0x02 /* bass */ 1081#define TDA8425_BA 0x02 /* bass */
1083#define TDA8425_TR 0x03 /* treble */ 1082#define TDA8425_TR 0x03 /* treble */
1084#define TDA8425_S1 0x08 /* switch functions */ 1083#define TDA8425_S1 0x08 /* switch functions */
1085 /* values for those registers: */ 1084 /* values for those registers: */
1086#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */ 1085#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
1087#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */ 1086#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
1088#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */ 1087#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
@@ -1148,7 +1147,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1148 1147
1149/* bit definition of the RESET register, I2C data. */ 1148/* bit definition of the RESET register, I2C data. */
1150#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */ 1149#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
1151 /* code of remote controller */ 1150 /* code of remote controller */
1152#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */ 1151#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
1153#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */ 1152#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
1154#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */ 1153#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
@@ -1281,7 +1280,7 @@ static struct CHIPDESC chiplist[] = {
1281 .setmode = tda9840_setmode, 1280 .setmode = tda9840_setmode,
1282 .checkmode = generic_checkmode, 1281 .checkmode = generic_checkmode,
1283 1282
1284 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN 1283 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
1285 /* ,TDA9840_SW, TDA9840_MONO */} } 1284 /* ,TDA9840_SW, TDA9840_MONO */} }
1286 }, 1285 },
1287 { 1286 {
@@ -1438,7 +1437,7 @@ static struct CHIPDESC chiplist[] = {
1438 }, 1437 },
1439 { 1438 {
1440 .name = "pic16c54 (PV951)", 1439 .name = "pic16c54 (PV951)",
1441 .id = I2C_DRIVERID_PIC16C54_PV951, 1440 .id = I2C_DRIVERID_PIC16C54_PV9,
1442 .insmodopt = &pic16c54, 1441 .insmodopt = &pic16c54,
1443 .addr_lo = I2C_PIC16C54 >> 1, 1442 .addr_lo = I2C_PIC16C54 >> 1,
1444 .addr_hi = I2C_PIC16C54>> 1, 1443 .addr_hi = I2C_PIC16C54>> 1,
@@ -1467,7 +1466,7 @@ static struct CHIPDESC chiplist[] = {
1467 .setmode = ta8874z_setmode, 1466 .setmode = ta8874z_setmode,
1468 .checkmode = generic_checkmode, 1467 .checkmode = generic_checkmode,
1469 1468
1470 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, 1469 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
1471 }, 1470 },
1472 { .name = NULL } /* EOF */ 1471 { .name = NULL } /* EOF */
1473}; 1472};
@@ -1486,8 +1485,8 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1486 return -ENOMEM; 1485 return -ENOMEM;
1487 memset(chip,0,sizeof(*chip)); 1486 memset(chip,0,sizeof(*chip));
1488 memcpy(&chip->c,&client_template,sizeof(struct i2c_client)); 1487 memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
1489 chip->c.adapter = adap; 1488 chip->c.adapter = adap;
1490 chip->c.addr = addr; 1489 chip->c.addr = addr;
1491 i2c_set_clientdata(&chip->c, chip); 1490 i2c_set_clientdata(&chip->c, chip);
1492 1491
1493 /* find description for the chip */ 1492 /* find description for the chip */
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 5344d5592199..72e8741e8b59 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -6,12 +6,12 @@
6 * which are: 6 * which are:
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 * Adjustments to fit a more general model and all bugs: 12 * Adjustments to fit a more general model and all bugs:
13 13
14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com> 14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15 15
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
40 40
41#include <media/tuner.h> 41#include <media/tuner.h>
42#include <media/tveeprom.h> 42#include <media/tveeprom.h>
43#include <media/audiochip.h>
43 44
44MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); 45MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
45MODULE_AUTHOR("John Klar"); 46MODULE_AUTHOR("John Klar");
@@ -53,14 +54,14 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 54
54#define tveeprom_info(fmt, arg...) do {\ 55#define tveeprom_info(fmt, arg...) do {\
55 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 56 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
56 c->adapter->nr, c->addr , ##arg); } while (0) 57 c->adapter->nr, c->addr , ##arg); } while (0)
57#define tveeprom_warn(fmt, arg...) do {\ 58#define tveeprom_warn(fmt, arg...) do {\
58 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ 59 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
59 c->adapter->nr, c->addr , ##arg); } while (0) 60 c->adapter->nr, c->addr , ##arg); } while (0)
60#define tveeprom_dbg(fmt, arg...) do {\ 61#define tveeprom_dbg(fmt, arg...) do {\
61 if (debug) \ 62 if (debug) \
62 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 63 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
63 c->adapter->nr, c->addr , ##arg); } while (0) 64 c->adapter->nr, c->addr , ##arg); } while (0)
64 65
65 66
66/* ----------------------------------------------------------------------- */ 67/* ----------------------------------------------------------------------- */
@@ -134,8 +135,8 @@ hauppauge_tuner[] =
134 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, 135 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
135 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, 136 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
136 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, 137 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
137 { TUNER_PHILIPS_NTSC, "Philips TD1536" }, 138 { TUNER_PHILIPS_NTSC, "Philips TD1536" },
138 { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, 139 { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
139 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ 140 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
140 { TUNER_ABSENT, "Philips FI1256MP" }, 141 { TUNER_ABSENT, "Philips FI1256MP" },
141 /* 40-49 */ 142 /* 40-49 */
@@ -189,7 +190,7 @@ hauppauge_tuner[] =
189 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, 190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, 191 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
191 { TUNER_TCL_2002N, "TCL 2002N 6A"}, 192 { TUNER_TCL_2002N, "TCL 2002N 6A"},
192 { TUNER_ABSENT, "Philips FQ1236 MK3"}, 193 { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
193 { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, 194 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
194 { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, 195 { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
195 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, 196 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
@@ -200,95 +201,137 @@ hauppauge_tuner[] =
200 { TUNER_ABSENT, "Philips FQ1286A MK4"}, 201 { TUNER_ABSENT, "Philips FQ1286A MK4"},
201 { TUNER_ABSENT, "Philips FQ1216ME MK5"}, 202 { TUNER_ABSENT, "Philips FQ1216ME MK5"},
202 { TUNER_ABSENT, "Philips FQ1236 MK5"}, 203 { TUNER_ABSENT, "Philips FQ1236 MK5"},
203 { TUNER_ABSENT, "Unspecified"}, 204 { TUNER_ABSENT, "Samsung TCPG_6121P30A"},
204 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"}, 205 { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
205 { TUNER_ABSENT, "Unspecified"}, 206 { TUNER_ABSENT, "TCL 2002MI_3H"},
206 { TUNER_TCL_2002N, "TCL 2002N 5H"}, 207 { TUNER_TCL_2002N, "TCL 2002N 5H"},
207 /* 100-103 */ 208 /* 100-109 */
208 { TUNER_ABSENT, "Unspecified"}, 209 { TUNER_ABSENT, "Philips FMD1216ME"},
209 { TUNER_TEA5767, "Philips TEA5767HN FM Radio"}, 210 { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
210 { TUNER_ABSENT, "Unspecified"}, 211 { TUNER_ABSENT, "Panasonic ENV57H12D5"},
211 { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"}, 212 { TUNER_ABSENT, "TCL MFNM05-4"},
213 { TUNER_ABSENT, "TCL MNM05-4"},
214 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
215 { TUNER_ABSENT, "TCL MQNM05-4"},
216 { TUNER_ABSENT, "LG TAPC-W701D"},
217 { TUNER_ABSENT, "TCL 9886P-WM"},
218 { TUNER_ABSENT, "TCL 1676NM-WM"},
212}; 219};
213 220
214/* This list is supplied by Hauppauge. Thanks! */ 221static struct HAUPPAUGE_AUDIOIC
215static const char *audioIC[] = { 222{
216 /* 0-4 */ 223 enum audiochip id;
217 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", 224 char *name;
218 /* 5-9 */ 225}
219 "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331", 226audioIC[] =
220 /* 10-14 */ 227{
221 "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416", 228 /* 0-4 */
222 /* 15-19 */ 229 {AUDIO_CHIP_NONE, "None"},
223 "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716", 230 {AUDIO_CHIP_TEA6300, "TEA6300"},
224 /* 20-24 */ 231 {AUDIO_CHIP_TEA6300, "TEA6320"},
225 "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408", 232 {AUDIO_CHIP_TDA985X, "TDA9850"},
226 /* 25-29 */ 233 {AUDIO_CHIP_MSP34XX, "MSP3400C"},
227 "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d", 234 /* 5-9 */
228 /* 30-34 */ 235 {AUDIO_CHIP_MSP34XX, "MSP3410D"},
229 "CX880", "CX881", "CX883", "CX882", "CX25840", 236 {AUDIO_CHIP_MSP34XX, "MSP3415"},
230 /* 35-38 */ 237 {AUDIO_CHIP_MSP34XX, "MSP3430"},
231 "CX25841", "CX25842", "CX25843", "CX23418", 238 {AUDIO_CHIP_UNKNOWN, "MSP3438"},
239 {AUDIO_CHIP_UNKNOWN, "CS5331"},
240 /* 10-14 */
241 {AUDIO_CHIP_MSP34XX, "MSP3435"},
242 {AUDIO_CHIP_MSP34XX, "MSP3440"},
243 {AUDIO_CHIP_MSP34XX, "MSP3445"},
244 {AUDIO_CHIP_UNKNOWN, "MSP3411"},
245 {AUDIO_CHIP_UNKNOWN, "MSP3416"},
246 /* 15-19 */
247 {AUDIO_CHIP_MSP34XX, "MSP3425"},
248 {AUDIO_CHIP_UNKNOWN, "MSP3451"},
249 {AUDIO_CHIP_UNKNOWN, "MSP3418"},
250 {AUDIO_CHIP_UNKNOWN, "Type 0x12"},
251 {AUDIO_CHIP_UNKNOWN, "OKI7716"},
252 /* 20-24 */
253 {AUDIO_CHIP_UNKNOWN, "MSP4410"},
254 {AUDIO_CHIP_UNKNOWN, "MSP4420"},
255 {AUDIO_CHIP_UNKNOWN, "MSP4440"},
256 {AUDIO_CHIP_UNKNOWN, "MSP4450"},
257 {AUDIO_CHIP_UNKNOWN, "MSP4408"},
258 /* 25-29 */
259 {AUDIO_CHIP_UNKNOWN, "MSP4418"},
260 {AUDIO_CHIP_UNKNOWN, "MSP4428"},
261 {AUDIO_CHIP_UNKNOWN, "MSP4448"},
262 {AUDIO_CHIP_UNKNOWN, "MSP4458"},
263 {AUDIO_CHIP_UNKNOWN, "Type 0x1d"},
264 /* 30-34 */
265 {AUDIO_CHIP_INTERNAL, "CX880"},
266 {AUDIO_CHIP_INTERNAL, "CX881"},
267 {AUDIO_CHIP_INTERNAL, "CX883"},
268 {AUDIO_CHIP_INTERNAL, "CX882"},
269 {AUDIO_CHIP_INTERNAL, "CX25840"},
270 /* 35-38 */
271 {AUDIO_CHIP_INTERNAL, "CX25841"},
272 {AUDIO_CHIP_INTERNAL, "CX25842"},
273 {AUDIO_CHIP_INTERNAL, "CX25843"},
274 {AUDIO_CHIP_INTERNAL, "CX23418"},
232}; 275};
233 276
234/* This list is supplied by Hauppauge. Thanks! */ 277/* This list is supplied by Hauppauge. Thanks! */
235static const char *decoderIC[] = { 278static const char *decoderIC[] = {
236 /* 0-4 */ 279 /* 0-4 */
237 "None", "BT815", "BT817", "BT819", "BT815A", 280 "None", "BT815", "BT817", "BT819", "BT815A",
238 /* 5-9 */ 281 /* 5-9 */
239 "BT817A", "BT819A", "BT827", "BT829", "BT848", 282 "BT817A", "BT819A", "BT827", "BT829", "BT848",
240 /* 10-14 */ 283 /* 10-14 */
241 "BT848A", "BT849A", "BT829A", "BT827A", "BT878", 284 "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
242 /* 15-19 */ 285 /* 15-19 */
243 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115", 286 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
244 /* 20-24 */ 287 /* 20-24 */
245 "CX880", "CX881", "CX883", "SAA7111", "SAA7113", 288 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
246 /* 25-29 */ 289 /* 25-29 */
247 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", 290 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
248 /* 30-31 */ 291 /* 30-31 */
249 "CX25843", "CX23418", 292 "CX25843", "CX23418",
250}; 293};
251 294
252static int hasRadioTuner(int tunerType) 295static int hasRadioTuner(int tunerType)
253{ 296{
254 switch (tunerType) { 297 switch (tunerType) {
255 case 18: //PNPEnv_TUNER_FR1236_MK2: 298 case 18: //PNPEnv_TUNER_FR1236_MK2:
256 case 23: //PNPEnv_TUNER_FM1236: 299 case 23: //PNPEnv_TUNER_FM1236:
257 case 38: //PNPEnv_TUNER_FMR1236: 300 case 38: //PNPEnv_TUNER_FMR1236:
258 case 16: //PNPEnv_TUNER_FR1216_MK2: 301 case 16: //PNPEnv_TUNER_FR1216_MK2:
259 case 19: //PNPEnv_TUNER_FR1246_MK2: 302 case 19: //PNPEnv_TUNER_FR1246_MK2:
260 case 21: //PNPEnv_TUNER_FM1216: 303 case 21: //PNPEnv_TUNER_FM1216:
261 case 24: //PNPEnv_TUNER_FM1246: 304 case 24: //PNPEnv_TUNER_FM1246:
262 case 17: //PNPEnv_TUNER_FR1216MF_MK2: 305 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
263 case 22: //PNPEnv_TUNER_FM1216MF: 306 case 22: //PNPEnv_TUNER_FM1216MF:
264 case 20: //PNPEnv_TUNER_FR1256_MK2: 307 case 20: //PNPEnv_TUNER_FR1256_MK2:
265 case 25: //PNPEnv_TUNER_FM1256: 308 case 25: //PNPEnv_TUNER_FM1256:
266 case 33: //PNPEnv_TUNER_4039FR5: 309 case 33: //PNPEnv_TUNER_4039FR5:
267 case 42: //PNPEnv_TUNER_4009FR5: 310 case 42: //PNPEnv_TUNER_4009FR5:
268 case 52: //PNPEnv_TUNER_4049FM5: 311 case 52: //PNPEnv_TUNER_4049FM5:
269 case 54: //PNPEnv_TUNER_4049FM5_AltI2C: 312 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
270 case 44: //PNPEnv_TUNER_4009FN5: 313 case 44: //PNPEnv_TUNER_4009FN5:
271 case 31: //PNPEnv_TUNER_TCPB9085P: 314 case 31: //PNPEnv_TUNER_TCPB9085P:
272 case 30: //PNPEnv_TUNER_TCPN9085D: 315 case 30: //PNPEnv_TUNER_TCPN9085D:
273 case 46: //PNPEnv_TUNER_TP18NSR01F: 316 case 46: //PNPEnv_TUNER_TP18NSR01F:
274 case 47: //PNPEnv_TUNER_TP18PSB01D: 317 case 47: //PNPEnv_TUNER_TP18PSB01D:
275 case 49: //PNPEnv_TUNER_TAPC_I001D: 318 case 49: //PNPEnv_TUNER_TAPC_I001D:
276 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3: 319 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
277 case 57: //PNPEnv_TUNER_FM1216ME_MK3: 320 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
278 case 59: //PNPEnv_TUNER_FM1216MP_MK3: 321 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
279 case 58: //PNPEnv_TUNER_FM1236_MK3: 322 case 58: //PNPEnv_TUNER_FM1236_MK3:
280 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3: 323 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
281 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3: 324 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
282 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: 325 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
283 case 89: //PNPEnv_TUNER_TCL_MFPE05_2: 326 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
284 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: 327 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
285 return 1; 328 return 1;
286 } 329 }
287 return 0; 330 return 0;
288} 331}
289 332
290void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, 333void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
291 unsigned char *eeprom_data) 334 unsigned char *eeprom_data)
292{ 335{
293 /* ---------------------------------------------- 336 /* ----------------------------------------------
294 ** The hauppauge eeprom format is tagged 337 ** The hauppauge eeprom format is tagged
@@ -312,19 +355,27 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
312 ** # of inputs/outputs ??? 355 ** # of inputs/outputs ???
313 */ 356 */
314 357
315 int i, j, len, done, beenhere, tag; 358 int i, j, len, done, beenhere, tag,start;
316 359
317 int tuner1 = 0, t_format1 = 0; 360 int tuner1 = 0, t_format1 = 0, audioic=-1;
318 char *t_name1 = NULL; 361 char *t_name1 = NULL;
319 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" }; 362 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
320 363
321 int tuner2 = 0, t_format2 = 0; 364 int tuner2 = 0, t_format2 = 0;
322 char *t_name2 = NULL; 365 char *t_name2 = NULL;
323 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; 366 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
324 367
325 memset(tvee, 0, sizeof(*tvee)); 368 memset(tvee, 0, sizeof(*tvee));
326 done = len = beenhere = 0; 369 done = len = beenhere = 0;
327 for (i = 0; !done && i < 256; i += len) { 370
371 /* Hack for processing eeprom for em28xx */
372 if ((eeprom_data[0]==0x1a)&&(eeprom_data[1]==0xeb)&&
373 (eeprom_data[2]==0x67)&&(eeprom_data[3]==0x95))
374 start=0xa0;
375 else
376 start=0;
377
378 for (i = start; !done && i < 256; i += len) {
328 if (eeprom_data[i] == 0x84) { 379 if (eeprom_data[i] == 0x84) {
329 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); 380 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
330 i += 3; 381 i += 3;
@@ -338,28 +389,28 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
338 ++i; 389 ++i;
339 } else { 390 } else {
340 tveeprom_warn("Encountered bad packet header [%02x]. " 391 tveeprom_warn("Encountered bad packet header [%02x]. "
341 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); 392 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
342 return; 393 return;
343 } 394 }
344 395
345 if (debug) { 396 if (debug) {
346 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1); 397 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
347 for(j = 1; j < len; j++) { 398 for(j = 1; j < len; j++) {
348 printk(" %02x", eeprom_data[i + j]); 399 printk(" %02x", eeprom_data[i + j]);
349 } 400 }
350 printk("\n"); 401 printk("\n");
351 } 402 }
352 403
353 /* process by tag */ 404 /* process by tag */
354 tag = eeprom_data[i]; 405 tag = eeprom_data[i];
355 switch (tag) { 406 switch (tag) {
356 case 0x00: 407 case 0x00:
357 /* tag: 'Comprehensive' */ 408 /* tag: 'Comprehensive' */
358 tuner1 = eeprom_data[i+6]; 409 tuner1 = eeprom_data[i+6];
359 t_format1 = eeprom_data[i+5]; 410 t_format1 = eeprom_data[i+5];
360 tvee->has_radio = eeprom_data[i+len-1]; 411 tvee->has_radio = eeprom_data[i+len-1];
361 /* old style tag, don't know how to detect 412 /* old style tag, don't know how to detect
362 IR presence, mark as unknown. */ 413 IR presence, mark as unknown. */
363 tvee->has_ir = 2; 414 tvee->has_ir = 2;
364 tvee->model = 415 tvee->model =
365 eeprom_data[i+8] + 416 eeprom_data[i+8] +
@@ -370,7 +421,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
370 break; 421 break;
371 422
372 case 0x01: 423 case 0x01:
373 /* tag: 'SerialID' */ 424 /* tag: 'SerialID' */
374 tvee->serial_number = 425 tvee->serial_number =
375 eeprom_data[i+6] + 426 eeprom_data[i+6] +
376 (eeprom_data[i+7] << 8) + 427 (eeprom_data[i+7] << 8) +
@@ -378,17 +429,21 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
378 break; 429 break;
379 430
380 case 0x02: 431 case 0x02:
381 /* tag 'AudioInfo' 432 /* tag 'AudioInfo'
382 Note mask with 0x7F, high bit used on some older models 433 Note mask with 0x7F, high bit used on some older models
383 to indicate 4052 mux was removed in favor of using MSP 434 to indicate 4052 mux was removed in favor of using MSP
384 inputs directly. */ 435 inputs directly. */
385 tvee->audio_processor = eeprom_data[i+2] & 0x7f; 436 audioic = eeprom_data[i+2] & 0x7f;
437 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
438 tvee->audio_processor = audioIC[audioic].id;
439 else
440 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
386 break; 441 break;
387 442
388 /* case 0x03: tag 'EEInfo' */ 443 /* case 0x03: tag 'EEInfo' */
389 444
390 case 0x04: 445 case 0x04:
391 /* tag 'SerialID2' */ 446 /* tag 'SerialID2' */
392 tvee->serial_number = 447 tvee->serial_number =
393 eeprom_data[i+5] + 448 eeprom_data[i+5] +
394 (eeprom_data[i+6] << 8) + 449 (eeprom_data[i+6] << 8) +
@@ -396,15 +451,20 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
396 break; 451 break;
397 452
398 case 0x05: 453 case 0x05:
399 /* tag 'Audio2' 454 /* tag 'Audio2'
400 Note mask with 0x7F, high bit used on some older models 455 Note mask with 0x7F, high bit used on some older models
401 to indicate 4052 mux was removed in favor of using MSP 456 to indicate 4052 mux was removed in favor of using MSP
402 inputs directly. */ 457 inputs directly. */
403 tvee->audio_processor = eeprom_data[i+1] & 0x7f; 458 audioic = eeprom_data[i+1] & 0x7f;
459 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
460 tvee->audio_processor = audioIC[audioic].id;
461 else
462 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
463
404 break; 464 break;
405 465
406 case 0x06: 466 case 0x06:
407 /* tag 'ModelRev' */ 467 /* tag 'ModelRev' */
408 tvee->model = 468 tvee->model =
409 eeprom_data[i+1] + 469 eeprom_data[i+1] +
410 (eeprom_data[i+2] << 8); 470 (eeprom_data[i+2] << 8);
@@ -414,55 +474,55 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
414 break; 474 break;
415 475
416 case 0x07: 476 case 0x07:
417 /* tag 'Details': according to Hauppauge not interesting 477 /* tag 'Details': according to Hauppauge not interesting
418 on any PCI-era or later boards. */ 478 on any PCI-era or later boards. */
419 break; 479 break;
420 480
421 /* there is no tag 0x08 defined */ 481 /* there is no tag 0x08 defined */
422 482
423 case 0x09: 483 case 0x09:
424 /* tag 'Video' */ 484 /* tag 'Video' */
425 tvee->decoder_processor = eeprom_data[i + 1]; 485 tvee->decoder_processor = eeprom_data[i + 1];
426 break; 486 break;
427 487
428 case 0x0a: 488 case 0x0a:
429 /* tag 'Tuner' */ 489 /* tag 'Tuner' */
430 if (beenhere == 0) { 490 if (beenhere == 0) {
431 tuner1 = eeprom_data[i+2]; 491 tuner1 = eeprom_data[i+2];
432 t_format1 = eeprom_data[i+1]; 492 t_format1 = eeprom_data[i+1];
433 beenhere = 1; 493 beenhere = 1;
434 } else { 494 } else {
435 /* a second (radio) tuner may be present */ 495 /* a second (radio) tuner may be present */
436 tuner2 = eeprom_data[i+2]; 496 tuner2 = eeprom_data[i+2];
437 t_format2 = eeprom_data[i+1]; 497 t_format2 = eeprom_data[i+1];
438 if (t_format2 == 0) { /* not a TV tuner? */ 498 if (t_format2 == 0) { /* not a TV tuner? */
439 tvee->has_radio = 1; /* must be radio */ 499 tvee->has_radio = 1; /* must be radio */
440 } 500 }
441 } 501 }
442 break; 502 break;
443 503
444 case 0x0b: 504 case 0x0b:
445 /* tag 'Inputs': according to Hauppauge this is specific 505 /* tag 'Inputs': according to Hauppauge this is specific
446 to each driver family, so no good assumptions can be 506 to each driver family, so no good assumptions can be
447 made. */ 507 made. */
448 break; 508 break;
449 509
450 /* case 0x0c: tag 'Balun' */ 510 /* case 0x0c: tag 'Balun' */
451 /* case 0x0d: tag 'Teletext' */ 511 /* case 0x0d: tag 'Teletext' */
452 512
453 case 0x0e: 513 case 0x0e:
454 /* tag: 'Radio' */ 514 /* tag: 'Radio' */
455 tvee->has_radio = eeprom_data[i+1]; 515 tvee->has_radio = eeprom_data[i+1];
456 break; 516 break;
457 517
458 case 0x0f: 518 case 0x0f:
459 /* tag 'IRInfo' */ 519 /* tag 'IRInfo' */
460 tvee->has_ir = eeprom_data[i+1]; 520 tvee->has_ir = eeprom_data[i+1];
461 break; 521 break;
462 522
463 /* case 0x10: tag 'VBIInfo' */ 523 /* case 0x10: tag 'VBIInfo' */
464 /* case 0x11: tag 'QCInfo' */ 524 /* case 0x11: tag 'QCInfo' */
465 /* case 0x12: tag 'InfoBits' */ 525 /* case 0x12: tag 'InfoBits' */
466 526
467 default: 527 default:
468 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag); 528 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
@@ -483,11 +543,11 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
483 tvee->rev_str[4] = 0; 543 tvee->rev_str[4] = 0;
484 } 544 }
485 545
486 if (hasRadioTuner(tuner1) && !tvee->has_radio) { 546 if (hasRadioTuner(tuner1) && !tvee->has_radio) {
487 tveeprom_info("The eeprom says no radio is present, but the tuner type\n"); 547 tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
488 tveeprom_info("indicates otherwise. I will assume that radio is present.\n"); 548 tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
489 tvee->has_radio = 1; 549 tvee->has_radio = 1;
490 } 550 }
491 551
492 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { 552 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
493 tvee->tuner_type = hauppauge_tuner[tuner1].id; 553 tvee->tuner_type = hauppauge_tuner[tuner1].id;
@@ -510,45 +570,53 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
510 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; 570 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
511 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name; 571 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
512 } 572 }
513 if (t_format2 & (1 << i)) { 573 if (t_format2 & (1 << i)) {
514 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id; 574 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
515 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name; 575 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
516 } 576 }
517 } 577 }
518 578
519 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", 579 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
520 tvee->model, tvee->rev_str, tvee->serial_number); 580 tvee->model, tvee->rev_str, tvee->serial_number);
521 tveeprom_info("tuner model is %s (idx %d, type %d)\n", 581 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
522 t_name1, tuner1, tvee->tuner_type); 582 t_name1, tuner1, tvee->tuner_type);
523 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 583 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
524 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], 584 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
525 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], 585 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
526 t_format1); 586 t_format1);
527 if (tuner2) { 587 if (tuner2) {
528 tveeprom_info("second tuner model is %s (idx %d, type %d)\n", 588 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
529 t_name2, tuner2, tvee->tuner2_type); 589 t_name2, tuner2, tvee->tuner2_type);
530 } 590 }
531 if (t_format2) { 591 if (t_format2) {
532 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 592 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
533 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], 593 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
534 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], 594 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
535 t_format2); 595 t_format2);
536 } 596 }
537 tveeprom_info("audio processor is %s (idx %d)\n", 597 if (audioic<0) {
538 STRM(audioIC, tvee->audio_processor), 598 tveeprom_info("audio processor is unknown (no idx)\n");
539 tvee->audio_processor); 599 tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
540 if (tvee->decoder_processor) { 600 } else {
541 tveeprom_info("decoder processor is %s (idx %d)\n", 601 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
542 STRM(decoderIC, tvee->decoder_processor), 602 tveeprom_info("audio processor is %s (idx %d)\n",
543 tvee->decoder_processor); 603 audioIC[audioic].name,audioic);
544 } 604 else
545 if (tvee->has_ir == 2) 605 tveeprom_info("audio processor is unknown (idx %d)\n",
546 tveeprom_info("has %sradio\n", 606 audioic);
547 tvee->has_radio ? "" : "no "); 607 }
548 else 608 if (tvee->decoder_processor) {
549 tveeprom_info("has %sradio, has %sIR remote\n", 609 tveeprom_info("decoder processor is %s (idx %d)\n",
550 tvee->has_radio ? "" : "no ", 610 STRM(decoderIC, tvee->decoder_processor),
551 tvee->has_ir ? "" : "no "); 611 tvee->decoder_processor);
612 }
613 if (tvee->has_ir == 2)
614 tveeprom_info("has %sradio\n",
615 tvee->has_radio ? "" : "no ");
616 else
617 tveeprom_info("has %sradio, has %sIR remote\n",
618 tvee->has_radio ? "" : "no ",
619 tvee->has_ir ? "" : "no ");
552} 620}
553EXPORT_SYMBOL(tveeprom_hauppauge_analog); 621EXPORT_SYMBOL(tveeprom_hauppauge_analog);
554 622
@@ -569,18 +637,18 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
569 tveeprom_warn("i2c eeprom read error (err=%d)\n", err); 637 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
570 return -1; 638 return -1;
571 } 639 }
572 if (debug) { 640 if (debug) {
573 int i; 641 int i;
574 642
575 tveeprom_info("full 256-byte eeprom dump:\n"); 643 tveeprom_info("full 256-byte eeprom dump:\n");
576 for (i = 0; i < len; i++) { 644 for (i = 0; i < len; i++) {
577 if (0 == (i % 16)) 645 if (0 == (i % 16))
578 tveeprom_info("%02x:", i); 646 tveeprom_info("%02x:", i);
579 printk(" %02x", eedata[i]); 647 printk(" %02x", eedata[i]);
580 if (15 == (i % 16)) 648 if (15 == (i % 16))
581 printk("\n"); 649 printk("\n");
582 } 650 }
583 } 651 }
584 return 0; 652 return 0;
585} 653}
586EXPORT_SYMBOL(tveeprom_read); 654EXPORT_SYMBOL(tveeprom_read);
@@ -590,10 +658,6 @@ EXPORT_SYMBOL(tveeprom_read);
590/* run, just call the exported tveeprom_* directly, there is no point in */ 658/* run, just call the exported tveeprom_* directly, there is no point in */
591/* using the indirect way via i2c_driver->command() */ 659/* using the indirect way via i2c_driver->command() */
592 660
593#ifndef I2C_DRIVERID_TVEEPROM
594# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
595#endif
596
597static unsigned short normal_i2c[] = { 661static unsigned short normal_i2c[] = {
598 0xa0 >> 1, 662 0xa0 >> 1,
599 I2C_CLIENT_END, 663 I2C_CLIENT_END,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index d86e08ebddfc..8318bd1aad00 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -79,7 +79,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
79{ 79{
80 struct video_audio va; 80 struct video_audio va;
81 int left,right,ret,val = 0; 81 int left,right,ret,val = 0;
82 struct TVMIXER *mix = file->private_data; 82 struct TVMIXER *mix = file->private_data;
83 struct i2c_client *client = mix->dev; 83 struct i2c_client *client = mix->dev;
84 void __user *argp = (void __user *)arg; 84 void __user *argp = (void __user *)arg;
85 int __user *p = argp; 85 int __user *p = argp;
@@ -87,25 +87,25 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
87 if (NULL == client) 87 if (NULL == client)
88 return -ENODEV; 88 return -ENODEV;
89 89
90 if (cmd == SOUND_MIXER_INFO) { 90 if (cmd == SOUND_MIXER_INFO) {
91 mixer_info info; 91 mixer_info info;
92 strlcpy(info.id, "tv card", sizeof(info.id)); 92 strlcpy(info.id, "tv card", sizeof(info.id));
93 strlcpy(info.name, client->name, sizeof(info.name)); 93 strlcpy(info.name, client->name, sizeof(info.name));
94 info.modify_counter = 42 /* FIXME */; 94 info.modify_counter = 42 /* FIXME */;
95 if (copy_to_user(argp, &info, sizeof(info))) 95 if (copy_to_user(argp, &info, sizeof(info)))
96 return -EFAULT; 96 return -EFAULT;
97 return 0; 97 return 0;
98 } 98 }
99 if (cmd == SOUND_OLD_MIXER_INFO) { 99 if (cmd == SOUND_OLD_MIXER_INFO) {
100 _old_mixer_info info; 100 _old_mixer_info info;
101 strlcpy(info.id, "tv card", sizeof(info.id)); 101 strlcpy(info.id, "tv card", sizeof(info.id));
102 strlcpy(info.name, client->name, sizeof(info.name)); 102 strlcpy(info.name, client->name, sizeof(info.name));
103 if (copy_to_user(argp, &info, sizeof(info))) 103 if (copy_to_user(argp, &info, sizeof(info)))
104 return -EFAULT; 104 return -EFAULT;
105 return 0; 105 return 0;
106 } 106 }
107 if (cmd == OSS_GETVERSION) 107 if (cmd == OSS_GETVERSION)
108 return put_user(SOUND_VERSION, p); 108 return put_user(SOUND_VERSION, p);
109 109
110 if (_SIOC_DIR(cmd) & _SIOC_WRITE) 110 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
111 if (get_user(val, p)) 111 if (get_user(val, p))
@@ -181,8 +181,8 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
181 181
182static int tvmixer_open(struct inode *inode, struct file *file) 182static int tvmixer_open(struct inode *inode, struct file *file)
183{ 183{
184 int i, minor = iminor(inode); 184 int i, minor = iminor(inode);
185 struct TVMIXER *mix = NULL; 185 struct TVMIXER *mix = NULL;
186 struct i2c_client *client = NULL; 186 struct i2c_client *client = NULL;
187 187
188 for (i = 0; i < DEV_MAX; i++) { 188 for (i = 0; i < DEV_MAX; i++) {
@@ -204,7 +204,7 @@ static int tvmixer_open(struct inode *inode, struct file *file)
204#endif 204#endif
205 if (client->adapter->owner) 205 if (client->adapter->owner)
206 try_module_get(client->adapter->owner); 206 try_module_get(client->adapter->owner);
207 return 0; 207 return 0;
208} 208}
209 209
210static int tvmixer_release(struct inode *inode, struct file *file) 210static int tvmixer_release(struct inode *inode, struct file *file)
@@ -231,15 +231,15 @@ static struct i2c_driver driver = {
231 .owner = THIS_MODULE, 231 .owner = THIS_MODULE,
232#endif 232#endif
233 .name = "tv card mixer driver", 233 .name = "tv card mixer driver",
234 .id = I2C_DRIVERID_TVMIXER, 234 .id = I2C_DRIVERID_TVMIXER,
235#ifdef I2C_DF_DUMMY 235#ifdef I2C_DF_DUMMY
236 .flags = I2C_DF_DUMMY, 236 .flags = I2C_DF_DUMMY,
237#else 237#else
238 .flags = I2C_DF_NOTIFY, 238 .flags = I2C_DF_NOTIFY,
239 .detach_adapter = tvmixer_adapters, 239 .detach_adapter = tvmixer_adapters,
240#endif 240#endif
241 .attach_adapter = tvmixer_adapters, 241 .attach_adapter = tvmixer_adapters,
242 .detach_client = tvmixer_clients, 242 .detach_client = tvmixer_clients,
243}; 243};
244 244
245static struct file_operations tvmixer_fops = { 245static struct file_operations tvmixer_fops = {
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
new file mode 100644
index 000000000000..81e6d4494e7d
--- /dev/null
+++ b/drivers/media/video/tvp5150.c
@@ -0,0 +1,829 @@
1/*
2 * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver
3 *
4 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
5 * This code is placed under the terms of the GNU General Public License
6 */
7
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <linux/delay.h>
11#include <linux/video_decoder.h>
12
13#include "tvp5150_reg.h"
14
15MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */
16MODULE_AUTHOR("Mauro Carvalho Chehab");
17MODULE_LICENSE("GPL");
18
19static unsigned short normal_i2c[] = {
20 0xb8 >> 1,
21 0xba >> 1,
22 I2C_CLIENT_END
23};
24
25I2C_CLIENT_INSMOD;
26
27static int debug = 0;
28module_param(debug, int, 0);
29MODULE_PARM_DESC(debug, "Debug level (0-1)");
30
31#define dprintk(num, format, args...) \
32 do { \
33 if (debug >= num) \
34 printk(format , ##args); \
35 } while (0)
36
37/* supported controls */
38static struct v4l2_queryctrl tvp5150_qctrl[] = {
39 {
40 .id = V4L2_CID_BRIGHTNESS,
41 .type = V4L2_CTRL_TYPE_INTEGER,
42 .name = "Brightness",
43 .minimum = 0,
44 .maximum = 255,
45 .step = 1,
46 .default_value = 0,
47 .flags = 0,
48 }, {
49 .id = V4L2_CID_CONTRAST,
50 .type = V4L2_CTRL_TYPE_INTEGER,
51 .name = "Contrast",
52 .minimum = 0,
53 .maximum = 255,
54 .step = 0x1,
55 .default_value = 0x10,
56 .flags = 0,
57 }, {
58 .id = V4L2_CID_SATURATION,
59 .type = V4L2_CTRL_TYPE_INTEGER,
60 .name = "Saturation",
61 .minimum = 0,
62 .maximum = 255,
63 .step = 0x1,
64 .default_value = 0x10,
65 .flags = 0,
66 }, {
67 .id = V4L2_CID_HUE,
68 .type = V4L2_CTRL_TYPE_INTEGER,
69 .name = "Hue",
70 .minimum = -128,
71 .maximum = 127,
72 .step = 0x1,
73 .default_value = 0x10,
74 .flags = 0,
75 }
76};
77
78struct tvp5150 {
79 struct i2c_client *client;
80
81 int norm;
82 int input;
83 int enable;
84 int bright;
85 int contrast;
86 int hue;
87 int sat;
88};
89
90static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
91{
92 unsigned char buffer[1];
93 int rc;
94
95 buffer[0] = addr;
96 if (1 != (rc = i2c_master_send(c, buffer, 1)))
97 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
98
99 msleep(10);
100
101 if (1 != (rc = i2c_master_recv(c, buffer, 1)))
102 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
103
104 return (buffer[0]);
105}
106
107static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
108 unsigned char value)
109{
110 unsigned char buffer[2];
111 int rc;
112/* struct tvp5150 *core = i2c_get_clientdata(c); */
113
114 buffer[0] = addr;
115 buffer[1] = value;
116 dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
117 if (2 != (rc = i2c_master_send(c, buffer, 2)))
118 dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
119}
120
121static void dump_reg(struct i2c_client *c)
122{
123 printk("tvp5150: Video input source selection #1 = 0x%02x\n",
124 tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1));
125 printk("tvp5150: Analog channel controls = 0x%02x\n",
126 tvp5150_read(c, TVP5150_ANAL_CHL_CTL));
127 printk("tvp5150: Operation mode controls = 0x%02x\n",
128 tvp5150_read(c, TVP5150_OP_MODE_CTL));
129 printk("tvp5150: Miscellaneous controls = 0x%02x\n",
130 tvp5150_read(c, TVP5150_MISC_CTL));
131 printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n",
132 tvp5150_read(c, TVP5150_AUTOSW_MSK));
133 printk("tvp5150: Color killer threshold control = 0x%02x\n",
134 tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL));
135 printk("tvp5150: Luminance processing control #1 = 0x%02x\n",
136 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1));
137 printk("tvp5150: Luminance processing control #2 = 0x%02x\n",
138 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2));
139 printk("tvp5150: Brightness control = 0x%02x\n",
140 tvp5150_read(c, TVP5150_BRIGHT_CTL));
141 printk("tvp5150: Color saturation control = 0x%02x\n",
142 tvp5150_read(c, TVP5150_SATURATION_CTL));
143 printk("tvp5150: Hue control = 0x%02x\n",
144 tvp5150_read(c, TVP5150_HUE_CTL));
145 printk("tvp5150: Contrast control = 0x%02x\n",
146 tvp5150_read(c, TVP5150_CONTRAST_CTL));
147 printk("tvp5150: Outputs and data rates select = 0x%02x\n",
148 tvp5150_read(c, TVP5150_DATA_RATE_SEL));
149 printk("tvp5150: Luminance processing control #3 = 0x%02x\n",
150 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3));
151 printk("tvp5150: Configuration shared pins = 0x%02x\n",
152 tvp5150_read(c, TVP5150_CONF_SHARED_PIN));
153 printk("tvp5150: Active video cropping start MSB = 0x%02x\n",
154 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB));
155 printk("tvp5150: Active video cropping start LSB = 0x%02x\n",
156 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB));
157 printk("tvp5150: Active video cropping stop MSB = 0x%02x\n",
158 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB));
159 printk("tvp5150: Active video cropping stop LSB = 0x%02x\n",
160 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB));
161 printk("tvp5150: Genlock/RTC = 0x%02x\n",
162 tvp5150_read(c, TVP5150_GENLOCK));
163 printk("tvp5150: Horizontal sync start = 0x%02x\n",
164 tvp5150_read(c, TVP5150_HORIZ_SYNC_START));
165 printk("tvp5150: Vertical blanking start = 0x%02x\n",
166 tvp5150_read(c, TVP5150_VERT_BLANKING_START));
167 printk("tvp5150: Vertical blanking stop = 0x%02x\n",
168 tvp5150_read(c, TVP5150_VERT_BLANKING_STOP));
169 printk("tvp5150: Chrominance processing control #1 = 0x%02x\n",
170 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1));
171 printk("tvp5150: Chrominance processing control #2 = 0x%02x\n",
172 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2));
173 printk("tvp5150: Interrupt reset register B = 0x%02x\n",
174 tvp5150_read(c, TVP5150_INT_RESET_REG_B));
175 printk("tvp5150: Interrupt enable register B = 0x%02x\n",
176 tvp5150_read(c, TVP5150_INT_ENABLE_REG_B));
177 printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
178 tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B));
179 printk("tvp5150: Video standard = 0x%02x\n",
180 tvp5150_read(c, TVP5150_VIDEO_STD));
181 printk("tvp5150: Cb gain factor = 0x%02x\n",
182 tvp5150_read(c, TVP5150_CB_GAIN_FACT));
183 printk("tvp5150: Cr gain factor = 0x%02x\n",
184 tvp5150_read(c, TVP5150_CR_GAIN_FACTOR));
185 printk("tvp5150: Macrovision on counter = 0x%02x\n",
186 tvp5150_read(c, TVP5150_MACROVISION_ON_CTR));
187 printk("tvp5150: Macrovision off counter = 0x%02x\n",
188 tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR));
189 printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n",
190 tvp5150_read(c, TVP5150_REV_SELECT));
191 printk("tvp5150: MSB of device ID = 0x%02x\n",
192 tvp5150_read(c, TVP5150_MSB_DEV_ID));
193 printk("tvp5150: LSB of device ID = 0x%02x\n",
194 tvp5150_read(c, TVP5150_LSB_DEV_ID));
195 printk("tvp5150: ROM major version = 0x%02x\n",
196 tvp5150_read(c, TVP5150_ROM_MAJOR_VER));
197 printk("tvp5150: ROM minor version = 0x%02x\n",
198 tvp5150_read(c, TVP5150_ROM_MINOR_VER));
199 printk("tvp5150: Vertical line count MSB = 0x%02x\n",
200 tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB));
201 printk("tvp5150: Vertical line count LSB = 0x%02x\n",
202 tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB));
203 printk("tvp5150: Interrupt status register B = 0x%02x\n",
204 tvp5150_read(c, TVP5150_INT_STATUS_REG_B));
205 printk("tvp5150: Interrupt active register B = 0x%02x\n",
206 tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B));
207 printk("tvp5150: Status register #1 = 0x%02x\n",
208 tvp5150_read(c, TVP5150_STATUS_REG_1));
209 printk("tvp5150: Status register #2 = 0x%02x\n",
210 tvp5150_read(c, TVP5150_STATUS_REG_2));
211 printk("tvp5150: Status register #3 = 0x%02x\n",
212 tvp5150_read(c, TVP5150_STATUS_REG_3));
213 printk("tvp5150: Status register #4 = 0x%02x\n",
214 tvp5150_read(c, TVP5150_STATUS_REG_4));
215 printk("tvp5150: Status register #5 = 0x%02x\n",
216 tvp5150_read(c, TVP5150_STATUS_REG_5));
217 printk("tvp5150: Closed caption data registers = 0x%02x\n",
218 tvp5150_read(c, TVP5150_CC_DATA_REG1));
219 printk("tvp5150: Closed caption data registers = 0x%02x\n",
220 tvp5150_read(c, TVP5150_CC_DATA_REG2));
221 printk("tvp5150: Closed caption data registers = 0x%02x\n",
222 tvp5150_read(c, TVP5150_CC_DATA_REG3));
223 printk("tvp5150: Closed caption data registers = 0x%02x\n",
224 tvp5150_read(c, TVP5150_CC_DATA_REG4));
225 printk("tvp5150: WSS data registers = 0x%02x\n",
226 tvp5150_read(c, TVP5150_WSS_DATA_REG1));
227 printk("tvp5150: WSS data registers = 0x%02x\n",
228 tvp5150_read(c, TVP5150_WSS_DATA_REG2));
229 printk("tvp5150: WSS data registers = 0x%02x\n",
230 tvp5150_read(c, TVP5150_WSS_DATA_REG3));
231 printk("tvp5150: WSS data registers = 0x%02x\n",
232 tvp5150_read(c, TVP5150_WSS_DATA_REG4));
233 printk("tvp5150: WSS data registers = 0x%02x\n",
234 tvp5150_read(c, TVP5150_WSS_DATA_REG5));
235 printk("tvp5150: WSS data registers = 0x%02x\n",
236 tvp5150_read(c, TVP5150_WSS_DATA_REG6));
237 printk("tvp5150: VPS data registers = 0x%02x\n",
238 tvp5150_read(c, TVP5150_VPS_DATA_REG1));
239 printk("tvp5150: VPS data registers = 0x%02x\n",
240 tvp5150_read(c, TVP5150_VPS_DATA_REG2));
241 printk("tvp5150: VPS data registers = 0x%02x\n",
242 tvp5150_read(c, TVP5150_VPS_DATA_REG3));
243 printk("tvp5150: VPS data registers = 0x%02x\n",
244 tvp5150_read(c, TVP5150_VPS_DATA_REG4));
245 printk("tvp5150: VPS data registers = 0x%02x\n",
246 tvp5150_read(c, TVP5150_VPS_DATA_REG5));
247 printk("tvp5150: VPS data registers = 0x%02x\n",
248 tvp5150_read(c, TVP5150_VPS_DATA_REG6));
249 printk("tvp5150: VPS data registers = 0x%02x\n",
250 tvp5150_read(c, TVP5150_VPS_DATA_REG7));
251 printk("tvp5150: VPS data registers = 0x%02x\n",
252 tvp5150_read(c, TVP5150_VPS_DATA_REG8));
253 printk("tvp5150: VPS data registers = 0x%02x\n",
254 tvp5150_read(c, TVP5150_VPS_DATA_REG9));
255 printk("tvp5150: VPS data registers = 0x%02x\n",
256 tvp5150_read(c, TVP5150_VPS_DATA_REG10));
257 printk("tvp5150: VPS data registers = 0x%02x\n",
258 tvp5150_read(c, TVP5150_VPS_DATA_REG11));
259 printk("tvp5150: VPS data registers = 0x%02x\n",
260 tvp5150_read(c, TVP5150_VPS_DATA_REG12));
261 printk("tvp5150: VPS data registers = 0x%02x\n",
262 tvp5150_read(c, TVP5150_VPS_DATA_REG13));
263 printk("tvp5150: VITC data registers = 0x%02x\n",
264 tvp5150_read(c, TVP5150_VITC_DATA_REG1));
265 printk("tvp5150: VITC data registers = 0x%02x\n",
266 tvp5150_read(c, TVP5150_VITC_DATA_REG2));
267 printk("tvp5150: VITC data registers = 0x%02x\n",
268 tvp5150_read(c, TVP5150_VITC_DATA_REG3));
269 printk("tvp5150: VITC data registers = 0x%02x\n",
270 tvp5150_read(c, TVP5150_VITC_DATA_REG4));
271 printk("tvp5150: VITC data registers = 0x%02x\n",
272 tvp5150_read(c, TVP5150_VITC_DATA_REG5));
273 printk("tvp5150: VITC data registers = 0x%02x\n",
274 tvp5150_read(c, TVP5150_VITC_DATA_REG6));
275 printk("tvp5150: VITC data registers = 0x%02x\n",
276 tvp5150_read(c, TVP5150_VITC_DATA_REG7));
277 printk("tvp5150: VITC data registers = 0x%02x\n",
278 tvp5150_read(c, TVP5150_VITC_DATA_REG8));
279 printk("tvp5150: VITC data registers = 0x%02x\n",
280 tvp5150_read(c, TVP5150_VITC_DATA_REG9));
281 printk("tvp5150: VBI FIFO read data = 0x%02x\n",
282 tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA));
283 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
284 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1));
285 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
286 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2));
287 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
288 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3));
289 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
290 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4));
291 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
292 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5));
293 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
294 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1));
295 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
296 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2));
297 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
298 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3));
299 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
300 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4));
301 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
302 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5));
303 printk("tvp5150: Teletext filter enable = 0x%02x\n",
304 tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA));
305 printk("tvp5150: Interrupt status register A = 0x%02x\n",
306 tvp5150_read(c, TVP5150_INT_STATUS_REG_A));
307 printk("tvp5150: Interrupt enable register A = 0x%02x\n",
308 tvp5150_read(c, TVP5150_INT_ENABLE_REG_A));
309 printk("tvp5150: Interrupt configuration = 0x%02x\n",
310 tvp5150_read(c, TVP5150_INT_CONF));
311 printk("tvp5150: VDP configuration RAM data = 0x%02x\n",
312 tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA));
313 printk("tvp5150: Configuration RAM address low byte = 0x%02x\n",
314 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW));
315 printk("tvp5150: Configuration RAM address high byte = 0x%02x\n",
316 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH));
317 printk("tvp5150: VDP status register = 0x%02x\n",
318 tvp5150_read(c, TVP5150_VDP_STATUS_REG));
319 printk("tvp5150: FIFO word count = 0x%02x\n",
320 tvp5150_read(c, TVP5150_FIFO_WORD_COUNT));
321 printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
322 tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD));
323 printk("tvp5150: FIFO reset = 0x%02x\n",
324 tvp5150_read(c, TVP5150_FIFO_RESET));
325 printk("tvp5150: Line number interrupt = 0x%02x\n",
326 tvp5150_read(c, TVP5150_LINE_NUMBER_INT));
327 printk("tvp5150: Pixel alignment register low byte = 0x%02x\n",
328 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW));
329 printk("tvp5150: Pixel alignment register high byte = 0x%02x\n",
330 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH));
331 printk("tvp5150: FIFO output control = 0x%02x\n",
332 tvp5150_read(c, TVP5150_FIFO_OUT_CTRL));
333 printk("tvp5150: Full field enable 1 = 0x%02x\n",
334 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1));
335 printk("tvp5150: Full field enable 2 = 0x%02x\n",
336 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2));
337 printk("tvp5150: Line mode registers = 0x%02x\n",
338 tvp5150_read(c, TVP5150_LINE_MODE_REG_1));
339 printk("tvp5150: Line mode registers = 0x%02x\n",
340 tvp5150_read(c, TVP5150_LINE_MODE_REG_2));
341 printk("tvp5150: Line mode registers = 0x%02x\n",
342 tvp5150_read(c, TVP5150_LINE_MODE_REG_3));
343 printk("tvp5150: Line mode registers = 0x%02x\n",
344 tvp5150_read(c, TVP5150_LINE_MODE_REG_4));
345 printk("tvp5150: Line mode registers = 0x%02x\n",
346 tvp5150_read(c, TVP5150_LINE_MODE_REG_5));
347 printk("tvp5150: Line mode registers = 0x%02x\n",
348 tvp5150_read(c, TVP5150_LINE_MODE_REG_6));
349 printk("tvp5150: Line mode registers = 0x%02x\n",
350 tvp5150_read(c, TVP5150_LINE_MODE_REG_7));
351 printk("tvp5150: Line mode registers = 0x%02x\n",
352 tvp5150_read(c, TVP5150_LINE_MODE_REG_8));
353 printk("tvp5150: Line mode registers = 0x%02x\n",
354 tvp5150_read(c, TVP5150_LINE_MODE_REG_9));
355 printk("tvp5150: Line mode registers = 0x%02x\n",
356 tvp5150_read(c, TVP5150_LINE_MODE_REG_10));
357 printk("tvp5150: Line mode registers = 0x%02x\n",
358 tvp5150_read(c, TVP5150_LINE_MODE_REG_11));
359 printk("tvp5150: Line mode registers = 0x%02x\n",
360 tvp5150_read(c, TVP5150_LINE_MODE_REG_12));
361 printk("tvp5150: Line mode registers = 0x%02x\n",
362 tvp5150_read(c, TVP5150_LINE_MODE_REG_13));
363 printk("tvp5150: Line mode registers = 0x%02x\n",
364 tvp5150_read(c, TVP5150_LINE_MODE_REG_14));
365 printk("tvp5150: Line mode registers = 0x%02x\n",
366 tvp5150_read(c, TVP5150_LINE_MODE_REG_15));
367 printk("tvp5150: Line mode registers = 0x%02x\n",
368 tvp5150_read(c, TVP5150_LINE_MODE_REG_16));
369 printk("tvp5150: Line mode registers = 0x%02x\n",
370 tvp5150_read(c, TVP5150_LINE_MODE_REG_17));
371 printk("tvp5150: Line mode registers = 0x%02x\n",
372 tvp5150_read(c, TVP5150_LINE_MODE_REG_18));
373 printk("tvp5150: Line mode registers = 0x%02x\n",
374 tvp5150_read(c, TVP5150_LINE_MODE_REG_19));
375 printk("tvp5150: Line mode registers = 0x%02x\n",
376 tvp5150_read(c, TVP5150_LINE_MODE_REG_20));
377 printk("tvp5150: Line mode registers = 0x%02x\n",
378 tvp5150_read(c, TVP5150_LINE_MODE_REG_21));
379 printk("tvp5150: Line mode registers = 0x%02x\n",
380 tvp5150_read(c, TVP5150_LINE_MODE_REG_22));
381 printk("tvp5150: Line mode registers = 0x%02x\n",
382 tvp5150_read(c, TVP5150_LINE_MODE_REG_23));
383 printk("tvp5150: Line mode registers = 0x%02x\n",
384 tvp5150_read(c, TVP5150_LINE_MODE_REG_24));
385 printk("tvp5150: Line mode registers = 0x%02x\n",
386 tvp5150_read(c, TVP5150_LINE_MODE_REG_25));
387 printk("tvp5150: Line mode registers = 0x%02x\n",
388 tvp5150_read(c, TVP5150_LINE_MODE_REG_27));
389 printk("tvp5150: Line mode registers = 0x%02x\n",
390 tvp5150_read(c, TVP5150_LINE_MODE_REG_28));
391 printk("tvp5150: Line mode registers = 0x%02x\n",
392 tvp5150_read(c, TVP5150_LINE_MODE_REG_29));
393 printk("tvp5150: Line mode registers = 0x%02x\n",
394 tvp5150_read(c, TVP5150_LINE_MODE_REG_30));
395 printk("tvp5150: Line mode registers = 0x%02x\n",
396 tvp5150_read(c, TVP5150_LINE_MODE_REG_31));
397 printk("tvp5150: Line mode registers = 0x%02x\n",
398 tvp5150_read(c, TVP5150_LINE_MODE_REG_32));
399 printk("tvp5150: Line mode registers = 0x%02x\n",
400 tvp5150_read(c, TVP5150_LINE_MODE_REG_33));
401 printk("tvp5150: Line mode registers = 0x%02x\n",
402 tvp5150_read(c, TVP5150_LINE_MODE_REG_34));
403 printk("tvp5150: Line mode registers = 0x%02x\n",
404 tvp5150_read(c, TVP5150_LINE_MODE_REG_35));
405 printk("tvp5150: Line mode registers = 0x%02x\n",
406 tvp5150_read(c, TVP5150_LINE_MODE_REG_36));
407 printk("tvp5150: Line mode registers = 0x%02x\n",
408 tvp5150_read(c, TVP5150_LINE_MODE_REG_37));
409 printk("tvp5150: Line mode registers = 0x%02x\n",
410 tvp5150_read(c, TVP5150_LINE_MODE_REG_38));
411 printk("tvp5150: Line mode registers = 0x%02x\n",
412 tvp5150_read(c, TVP5150_LINE_MODE_REG_39));
413 printk("tvp5150: Line mode registers = 0x%02x\n",
414 tvp5150_read(c, TVP5150_LINE_MODE_REG_40));
415 printk("tvp5150: Line mode registers = 0x%02x\n",
416 tvp5150_read(c, TVP5150_LINE_MODE_REG_41));
417 printk("tvp5150: Line mode registers = 0x%02x\n",
418 tvp5150_read(c, TVP5150_LINE_MODE_REG_42));
419 printk("tvp5150: Line mode registers = 0x%02x\n",
420 tvp5150_read(c, TVP5150_LINE_MODE_REG_43));
421 printk("tvp5150: Line mode registers = 0x%02x\n",
422 tvp5150_read(c, TVP5150_LINE_MODE_REG_44));
423 printk("tvp5150: Full field mode register = 0x%02x\n",
424 tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG));
425}
426
427/****************************************************************************
428 Basic functions
429 ****************************************************************************/
430enum tvp5150_input {
431 TVP5150_ANALOG_CH0 = 0,
432 TVP5150_SVIDEO = 1,
433 TVP5150_ANALOG_CH1 = 2,
434 TVP5150_BLACK_SCREEN = 8
435};
436
437static inline void tvp5150_selmux(struct i2c_client *c,
438 enum tvp5150_input input)
439{
440 struct tvp5150 *decoder = i2c_get_clientdata(c);
441
442 if (!decoder->enable)
443 input |= TVP5150_BLACK_SCREEN;
444
445 tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
446};
447
448static inline void tvp5150_reset(struct i2c_client *c)
449{
450 struct tvp5150 *decoder = i2c_get_clientdata(c);
451
452 tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2);
453
454 /* Automatic offset and AGC enabled */
455 tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15);
456
457 /* Normal Operation */
458// tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00);
459
460 /* Activate YCrCb output 0x9 or 0xd ? */
461 tvp5150_write(c, TVP5150_MISC_CTL, 0x6f);
462
463 /* Activates video std autodetection for all standards */
464 tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0);
465
466 /* Default format: 0x47, 4:2:2: 0x40 */
467 tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47);
468
469 tvp5150_selmux(c, decoder->input);
470
471 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c);
472 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54);
473
474 tvp5150_write(c, 0x27, 0x20); /* ?????????? */
475
476 tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */
477
478 tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
479 tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
480 tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
481 tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
482};
483
484static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
485{
486/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
487
488 switch (ctrl->id) {
489 case V4L2_CID_BRIGHTNESS:
490 ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL);
491 return 0;
492 case V4L2_CID_CONTRAST:
493 ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL);
494 return 0;
495 case V4L2_CID_SATURATION:
496 ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL);
497 return 0;
498 case V4L2_CID_HUE:
499 ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL);
500 return 0;
501 default:
502 return -EINVAL;
503 }
504}
505
506static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
507{
508/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
509
510 switch (ctrl->id) {
511 case V4L2_CID_BRIGHTNESS:
512 tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value);
513 return 0;
514 case V4L2_CID_CONTRAST:
515 tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value);
516 return 0;
517 case V4L2_CID_SATURATION:
518 tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value);
519 return 0;
520 case V4L2_CID_HUE:
521 tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
522 return 0;
523 default:
524 return -EINVAL;
525 }
526}
527
528/****************************************************************************
529 I2C Command
530 ****************************************************************************/
531static int tvp5150_command(struct i2c_client *client,
532 unsigned int cmd, void *arg)
533{
534 struct tvp5150 *decoder = i2c_get_clientdata(client);
535
536 switch (cmd) {
537
538 case 0:
539 case DECODER_INIT:
540 tvp5150_reset(client);
541 break;
542
543 case DECODER_DUMP:
544 dump_reg(client);
545 break;
546
547 case DECODER_GET_CAPABILITIES:
548 {
549 struct video_decoder_capability *cap = arg;
550
551 cap->flags = VIDEO_DECODER_PAL |
552 VIDEO_DECODER_NTSC |
553 VIDEO_DECODER_SECAM |
554 VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
555 cap->inputs = 3;
556 cap->outputs = 1;
557 break;
558 }
559 case DECODER_GET_STATUS:
560 {
561 break;
562 }
563
564 case DECODER_SET_GPIO:
565 break;
566
567 case DECODER_SET_VBI_BYPASS:
568 break;
569
570 case DECODER_SET_NORM:
571 {
572 int *iarg = arg;
573
574 switch (*iarg) {
575
576 case VIDEO_MODE_NTSC:
577 break;
578
579 case VIDEO_MODE_PAL:
580 break;
581
582 case VIDEO_MODE_SECAM:
583 break;
584
585 case VIDEO_MODE_AUTO:
586 break;
587
588 default:
589 return -EINVAL;
590
591 }
592 decoder->norm = *iarg;
593 break;
594 }
595 case DECODER_SET_INPUT:
596 {
597 int *iarg = arg;
598 if (*iarg < 0 || *iarg > 3) {
599 return -EINVAL;
600 }
601
602 decoder->input = *iarg;
603 tvp5150_selmux(client, decoder->input);
604
605 break;
606 }
607 case DECODER_SET_OUTPUT:
608 {
609 int *iarg = arg;
610
611 /* not much choice of outputs */
612 if (*iarg != 0) {
613 return -EINVAL;
614 }
615 break;
616 }
617 case DECODER_ENABLE_OUTPUT:
618 {
619 int *iarg = arg;
620
621 decoder->enable = (*iarg != 0);
622
623 tvp5150_selmux(client, decoder->input);
624
625 break;
626 }
627 case VIDIOC_QUERYCTRL:
628 {
629 struct v4l2_queryctrl *qc = arg;
630 u8 i, n;
631
632 dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL");
633
634 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
635 for (i = 0; i < n; i++)
636 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
637 memcpy(qc, &(tvp5150_qctrl[i]),
638 sizeof(*qc));
639 return 0;
640 }
641
642 return -EINVAL;
643 }
644 case VIDIOC_G_CTRL:
645 {
646 struct v4l2_control *ctrl = arg;
647 dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL");
648
649 return tvp5150_get_ctrl(client, ctrl);
650 }
651 case VIDIOC_S_CTRL_OLD: /* ??? */
652 case VIDIOC_S_CTRL:
653 {
654 struct v4l2_control *ctrl = arg;
655 u8 i, n;
656 dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
657 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
658 for (i = 0; i < n; i++)
659 if (ctrl->id == tvp5150_qctrl[i].id) {
660 if (ctrl->value <
661 tvp5150_qctrl[i].minimum
662 || ctrl->value >
663 tvp5150_qctrl[i].maximum)
664 return -ERANGE;
665 dprintk(1,
666 KERN_DEBUG
667 "VIDIOC_S_CTRL: id=%d, value=%d",
668 ctrl->id, ctrl->value);
669 return tvp5150_set_ctrl(client, ctrl);
670 }
671 return -EINVAL;
672 }
673
674 case DECODER_SET_PICTURE:
675 {
676 struct video_picture *pic = arg;
677 if (decoder->bright != pic->brightness) {
678 /* We want 0 to 255 we get 0-65535 */
679 decoder->bright = pic->brightness;
680 tvp5150_write(client, TVP5150_BRIGHT_CTL,
681 decoder->bright >> 8);
682 }
683 if (decoder->contrast != pic->contrast) {
684 /* We want 0 to 255 we get 0-65535 */
685 decoder->contrast = pic->contrast;
686 tvp5150_write(client, TVP5150_CONTRAST_CTL,
687 decoder->contrast >> 8);
688 }
689 if (decoder->sat != pic->colour) {
690 /* We want 0 to 255 we get 0-65535 */
691 decoder->sat = pic->colour;
692 tvp5150_write(client, TVP5150_SATURATION_CTL,
693 decoder->contrast >> 8);
694 }
695 if (decoder->hue != pic->hue) {
696 /* We want -128 to 127 we get 0-65535 */
697 decoder->hue = pic->hue;
698 tvp5150_write(client, TVP5150_HUE_CTL,
699 (decoder->hue - 32768) >> 8);
700 }
701 break;
702 }
703 default:
704 return -EINVAL;
705 }
706
707 return 0;
708}
709
710/****************************************************************************
711 I2C Client & Driver
712 ****************************************************************************/
713static struct i2c_driver driver;
714
715static struct i2c_client client_template = {
716 .name = "(unset)",
717 .flags = I2C_CLIENT_ALLOW_USE,
718 .driver = &driver,
719};
720
721static int tvp5150_detect_client(struct i2c_adapter *adapter,
722 int address, int kind)
723{
724 struct i2c_client *client;
725 struct tvp5150 *core;
726 int rv;
727
728 dprintk(1,
729 KERN_INFO
730 "tvp5150.c: detecting tvp5150 client on address 0x%x\n",
731 address << 1);
732
733 client_template.adapter = adapter;
734 client_template.addr = address;
735
736 /* Check if the adapter supports the needed features */
737 if (!i2c_check_functionality
738 (adapter,
739 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
740 return 0;
741
742 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
743 if (client == 0)
744 return -ENOMEM;
745 memcpy(client, &client_template, sizeof(struct i2c_client));
746
747 core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL);
748 if (core == 0) {
749 kfree(client);
750 return -ENOMEM;
751 }
752 memset(core, 0, sizeof(struct tvp5150));
753 i2c_set_clientdata(client, core);
754
755 rv = i2c_attach_client(client);
756
757 core->norm = VIDEO_MODE_AUTO;
758 core->input = 2;
759 core->enable = 1;
760 core->bright = 32768;
761 core->contrast = 32768;
762 core->hue = 32768;
763 core->sat = 32768;
764
765 if (rv) {
766 kfree(client);
767 kfree(core);
768 return rv;
769 }
770
771 if (debug > 1)
772 dump_reg(client);
773
774 return 0;
775}
776
777static int tvp5150_attach_adapter(struct i2c_adapter *adapter)
778{
779 dprintk(1,
780 KERN_INFO
781 "tvp5150.c: starting probe for adapter %s (0x%x)\n",
782 adapter->name, adapter->id);
783 return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
784}
785
786static int tvp5150_detach_client(struct i2c_client *client)
787{
788 struct tvp5150 *decoder = i2c_get_clientdata(client);
789 int err;
790
791 err = i2c_detach_client(client);
792 if (err) {
793 return err;
794 }
795
796 kfree(decoder);
797 kfree(client);
798
799 return 0;
800}
801
802/* ----------------------------------------------------------------------- */
803
804static struct i2c_driver driver = {
805 .owner = THIS_MODULE,
806 .name = "tvp5150",
807
808 /* FIXME */
809 .id = I2C_DRIVERID_SAA7110,
810 .flags = I2C_DF_NOTIFY,
811
812 .attach_adapter = tvp5150_attach_adapter,
813 .detach_client = tvp5150_detach_client,
814
815 .command = tvp5150_command,
816};
817
818static int __init tvp5150_init(void)
819{
820 return i2c_add_driver(&driver);
821}
822
823static void __exit tvp5150_exit(void)
824{
825 i2c_del_driver(&driver);
826}
827
828module_init(tvp5150_init);
829module_exit(tvp5150_exit);
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h
new file mode 100644
index 000000000000..cd45c1ded786
--- /dev/null
+++ b/drivers/media/video/tvp5150_reg.h
@@ -0,0 +1,173 @@
1#define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */
2#define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */
3#define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */
4#define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */
5#define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */
6
7/* Reserved 05h */
8
9#define TVP5150_COLOR_KIL_THSH_CTL 0x06 /* Color killer threshold control */
10#define TVP5150_LUMA_PROC_CTL_1 0x07 /* Luminance processing control #1 */
11#define TVP5150_LUMA_PROC_CTL_2 0x08 /* Luminance processing control #2 */
12#define TVP5150_BRIGHT_CTL 0x09 /* Brightness control */
13#define TVP5150_SATURATION_CTL 0x0a /* Color saturation control */
14#define TVP5150_HUE_CTL 0x0b /* Hue control */
15#define TVP5150_CONTRAST_CTL 0x0c /* Contrast control */
16#define TVP5150_DATA_RATE_SEL 0x0d /* Outputs and data rates select */
17#define TVP5150_LUMA_PROC_CTL_3 0x0e /* Luminance processing control #3 */
18#define TVP5150_CONF_SHARED_PIN 0x0f /* Configuration shared pins */
19
20/* Reserved 10h */
21
22#define TVP5150_ACT_VD_CROP_ST_MSB 0x11 /* Active video cropping start MSB */
23#define TVP5150_ACT_VD_CROP_ST_LSB 0x12 /* Active video cropping start LSB */
24#define TVP5150_ACT_VD_CROP_STP_MSB 0x13 /* Active video cropping stop MSB */
25#define TVP5150_ACT_VD_CROP_STP_LSB 0x14 /* Active video cropping stop LSB */
26#define TVP5150_GENLOCK 0x15 /* Genlock/RTC */
27#define TVP5150_HORIZ_SYNC_START 0x16 /* Horizontal sync start */
28
29/* Reserved 17h */
30
31#define TVP5150_VERT_BLANKING_START 0x18 /* Vertical blanking start */
32#define TVP5150_VERT_BLANKING_STOP 0x19 /* Vertical blanking stop */
33#define TVP5150_CHROMA_PROC_CTL_1 0x1a /* Chrominance processing control #1 */
34#define TVP5150_CHROMA_PROC_CTL_2 0x1b /* Chrominance processing control #2 */
35#define TVP5150_INT_RESET_REG_B 0x1c /* Interrupt reset register B */
36#define TVP5150_INT_ENABLE_REG_B 0x1d /* Interrupt enable register B */
37#define TVP5150_INTT_CONFIG_REG_B 0x1e /* Interrupt configuration register B */
38
39/* Reserved 1Fh-27h */
40
41#define TVP5150_VIDEO_STD 0x28 /* Video standard */
42
43/* Reserved 29h-2bh */
44
45#define TVP5150_CB_GAIN_FACT 0x2c /* Cb gain factor */
46#define TVP5150_CR_GAIN_FACTOR 0x2d /* Cr gain factor */
47#define TVP5150_MACROVISION_ON_CTR 0x2e /* Macrovision on counter */
48#define TVP5150_MACROVISION_OFF_CTR 0x2f /* Macrovision off counter */
49#define TVP5150_REV_SELECT 0x30 /* revision select (TVP5150AM1 only) */
50
51/* Reserved 31h-7Fh */
52
53#define TVP5150_MSB_DEV_ID 0x80 /* MSB of device ID */
54#define TVP5150_LSB_DEV_ID 0x81 /* LSB of device ID */
55#define TVP5150_ROM_MAJOR_VER 0x82 /* ROM major version */
56#define TVP5150_ROM_MINOR_VER 0x83 /* ROM minor version */
57#define TVP5150_VERT_LN_COUNT_MSB 0x84 /* Vertical line count MSB */
58#define TVP5150_VERT_LN_COUNT_LSB 0x85 /* Vertical line count LSB */
59#define TVP5150_INT_STATUS_REG_B 0x86 /* Interrupt status register B */
60#define TVP5150_INT_ACTIVE_REG_B 0x87 /* Interrupt active register B */
61#define TVP5150_STATUS_REG_1 0x88 /* Status register #1 */
62#define TVP5150_STATUS_REG_2 0x89 /* Status register #2 */
63#define TVP5150_STATUS_REG_3 0x8a /* Status register #3 */
64#define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */
65#define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */
66/* Reserved 8Dh-8Fh */
67#define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */
68#define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */
69#define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */
70#define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */
71#define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */
72#define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */
73#define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */
74#define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */
75#define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */
76#define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */
77#define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */
78#define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */
79#define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */
80#define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */
81#define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */
82#define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */
83#define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */
84#define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */
85#define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */
86#define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */
87#define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */
88#define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */
89#define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */
90#define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */
91#define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */
92#define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */
93#define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */
94#define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */
95#define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */
96#define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */
97#define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */
98#define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */
99#define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */
100#define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */
101#define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */
102#define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */
103#define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */
104#define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */
105#define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */
106#define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */
107#define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */
108#define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */
109#define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */
110#define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */
111/* Reserved BCh-BFh */
112#define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */
113#define TVP5150_INT_ENABLE_REG_A 0xc1 /* Interrupt enable register A */
114#define TVP5150_INT_CONF 0xc2 /* Interrupt configuration */
115#define TVP5150_VDP_CONF_RAM_DATA 0xc3 /* VDP configuration RAM data */
116#define TVP5150_CONF_RAM_ADDR_LOW 0xc4 /* Configuration RAM address low byte */
117#define TVP5150_CONF_RAM_ADDR_HIGH 0xc5 /* Configuration RAM address high byte */
118#define TVP5150_VDP_STATUS_REG 0xc6 /* VDP status register */
119#define TVP5150_FIFO_WORD_COUNT 0xc7 /* FIFO word count */
120#define TVP5150_FIFO_INT_THRESHOLD 0xc8 /* FIFO interrupt threshold */
121#define TVP5150_FIFO_RESET 0xc9 /* FIFO reset */
122#define TVP5150_LINE_NUMBER_INT 0xca /* Line number interrupt */
123#define TVP5150_PIX_ALIGN_REG_LOW 0xcb /* Pixel alignment register low byte */
124#define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */
125#define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */
126/* Reserved CEh */
127#define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */
128#define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */
129#define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */
130#define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */
131#define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */
132#define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */
133#define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */
134#define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */
135#define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */
136#define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */
137#define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */
138#define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */
139#define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */
140#define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */
141#define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */
142#define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */
143#define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */
144#define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */
145#define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */
146#define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */
147#define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */
148#define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */
149#define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */
150#define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */
151#define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */
152#define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */
153#define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */
154#define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */
155#define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */
156#define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */
157#define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */
158#define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */
159#define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */
160#define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */
161#define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */
162#define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */
163#define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */
164#define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */
165#define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */
166#define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */
167#define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */
168#define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */
169#define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */
170#define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */
171#define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */
172#define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */
173/* Reserved FDh-FFh */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index d679ca23ded7..4134549d11a8 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -708,7 +708,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
708 } 708 }
709 case VIDIOCGFREQ: /* get frequency */ 709 case VIDIOCGFREQ: /* get frequency */
710 { 710 {
711 int *freq = arg; 711 unsigned long *freq = arg;
712 712
713 freq2.tuner = 0; 713 freq2.tuner = 0;
714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -720,7 +720,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
720 } 720 }
721 case VIDIOCSFREQ: /* set frequency */ 721 case VIDIOCSFREQ: /* set frequency */
722 { 722 {
723 int *freq = arg; 723 unsigned long *freq = arg;
724 724
725 freq2.tuner = 0; 725 freq2.tuner = 0;
726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -960,7 +960,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
960 fmt->start[1] = fmt2->fmt.vbi.start[1]; 960 fmt->start[1] = fmt2->fmt.vbi.start[1];
961 fmt->count[1] = fmt2->fmt.vbi.count[1]; 961 fmt->count[1] = fmt2->fmt.vbi.count[1];
962 fmt->flags = fmt2->fmt.vbi.flags & 0x03; 962 fmt->flags = fmt2->fmt.vbi.flags & 0x03;
963 break; 963 break;
964 } 964 }
965 case VIDIOCSVBIFMT: 965 case VIDIOCSVBIFMT:
966 { 966 {
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index 574b8e36f3c6..acfd3a103f35 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -147,7 +147,7 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
147 data,size,dma->nr_pages); 147 data,size,dma->nr_pages);
148 148
149 down_read(&current->mm->mmap_sem); 149 down_read(&current->mm->mmap_sem);
150 err = get_user_pages(current,current->mm, 150 err = get_user_pages(current,current->mm,
151 data & PAGE_MASK, dma->nr_pages, 151 data & PAGE_MASK, dma->nr_pages,
152 rw == READ, 1, /* force */ 152 rw == READ, 1, /* force */
153 dma->pages, NULL); 153 dma->pages, NULL);
@@ -750,9 +750,9 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
750{ 750{
751 enum v4l2_field field; 751 enum v4l2_field field;
752 unsigned long flags; 752 unsigned long flags;
753 int retval; 753 int retval;
754 754
755 /* setup stuff */ 755 /* setup stuff */
756 retval = -ENOMEM; 756 retval = -ENOMEM;
757 q->read_buf = videobuf_alloc(q->msize); 757 q->read_buf = videobuf_alloc(q->msize);
758 if (NULL == q->read_buf) 758 if (NULL == q->read_buf)
@@ -760,18 +760,18 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
760 760
761 q->read_buf->memory = V4L2_MEMORY_USERPTR; 761 q->read_buf->memory = V4L2_MEMORY_USERPTR;
762 q->read_buf->baddr = (unsigned long)data; 762 q->read_buf->baddr = (unsigned long)data;
763 q->read_buf->bsize = count; 763 q->read_buf->bsize = count;
764 field = videobuf_next_field(q); 764 field = videobuf_next_field(q);
765 retval = q->ops->buf_prepare(q,q->read_buf,field); 765 retval = q->ops->buf_prepare(q,q->read_buf,field);
766 if (0 != retval) 766 if (0 != retval)
767 goto done; 767 goto done;
768 768
769 /* start capture & wait */ 769 /* start capture & wait */
770 spin_lock_irqsave(q->irqlock,flags); 770 spin_lock_irqsave(q->irqlock,flags);
771 q->ops->buf_queue(q,q->read_buf); 771 q->ops->buf_queue(q,q->read_buf);
772 spin_unlock_irqrestore(q->irqlock,flags); 772 spin_unlock_irqrestore(q->irqlock,flags);
773 retval = videobuf_waiton(q->read_buf,0,0); 773 retval = videobuf_waiton(q->read_buf,0,0);
774 if (0 == retval) { 774 if (0 == retval) {
775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
776 if (STATE_ERROR == q->read_buf->state) 776 if (STATE_ERROR == q->read_buf->state)
777 retval = -EIO; 777 retval = -EIO;
@@ -828,7 +828,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
828 } 828 }
829 829
830 /* wait until capture is done */ 830 /* wait until capture is done */
831 retval = videobuf_waiton(q->read_buf, nonblocking, 1); 831 retval = videobuf_waiton(q->read_buf, nonblocking, 1);
832 if (0 != retval) 832 if (0 != retval)
833 goto done; 833 goto done;
834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
@@ -1096,7 +1096,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
1096 1096
1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n", 1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
1098 vaddr,vma->vm_start,vma->vm_end); 1098 vaddr,vma->vm_start,vma->vm_end);
1099 if (vaddr > vma->vm_end) 1099 if (vaddr > vma->vm_end)
1100 return NOPAGE_SIGBUS; 1100 return NOPAGE_SIGBUS;
1101 page = alloc_page(GFP_USER); 1101 page = alloc_page(GFP_USER);
1102 if (!page) 1102 if (!page)
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
new file mode 100644
index 000000000000..22f286222004
--- /dev/null
+++ b/drivers/media/video/wm8775.c
@@ -0,0 +1,254 @@
1/*
2 * wm8775 - driver version 0.0.1
3 *
4 * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
5 *
6 * Based on saa7115 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24#include <linux/module.h>
25#include <linux/types.h>
26#include <linux/ioctl.h>
27#include <asm/uaccess.h>
28#include <linux/i2c.h>
29#include <linux/i2c-id.h>
30#include <linux/videodev.h>
31#include <media/audiochip.h>
32
33MODULE_DESCRIPTION("wm8775 driver");
34MODULE_AUTHOR("Ulf Eklund");
35MODULE_LICENSE("GPL");
36
37#define wm8775_err(fmt, arg...) do { \
38 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
39 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
40#define wm8775_info(fmt, arg...) do { \
41 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
42 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
43
44
45static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
46
47
48I2C_CLIENT_INSMOD;
49
50/* ----------------------------------------------------------------------- */
51
52enum {
53 R7 = 7, R11 = 11,
54 R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 = 23,
55 TOT_REGS
56};
57
58struct wm8775_state {
59 u8 input; /* Last selected input (0-0xf) */
60 u8 muted;
61};
62
63static int wm8775_write(struct i2c_client *client, int reg, u16 val)
64{
65 int i;
66
67 if (reg < 0 || reg >= TOT_REGS) {
68 wm8775_err("Invalid register R%d\n", reg);
69 return -1;
70 }
71
72 for (i = 0; i < 3; i++) {
73 if (i2c_smbus_write_byte_data(client, (reg << 1) |
74 (val >> 8), val & 0xff) == 0) {
75 return 0;
76 }
77 }
78 wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg);
79 return -1;
80}
81
82static int wm8775_command(struct i2c_client *client, unsigned int cmd,
83 void *arg)
84{
85 struct wm8775_state *state = i2c_get_clientdata(client);
86 int *input = arg;
87
88 switch (cmd) {
89 case AUDC_SET_INPUT:
90 wm8775_write(client, R21, 0x0c0);
91 wm8775_write(client, R14, 0x1d4);
92 wm8775_write(client, R15, 0x1d4);
93
94 if (*input == AUDIO_RADIO) {
95 wm8775_write(client, R21, 0x108);
96 state->input = 8;
97 state->muted = 0;
98 break;
99 }
100 if (*input == AUDIO_MUTE) {
101 state->muted = 1;
102 break;
103 }
104 if (*input == AUDIO_UNMUTE) {
105 wm8775_write(client, R21, 0x100 + state->input);
106 state->muted = 0;
107 break;
108 }
109 /* All other inputs... */
110 wm8775_write(client, R21, 0x102);
111 state->input = 2;
112 state->muted = 0;
113 break;
114
115 case VIDIOC_LOG_STATUS:
116 wm8775_info("Input: %s%s\n",
117 state->input == 8 ? "radio" : "default",
118 state->muted ? " (muted)" : "");
119 break;
120
121 case VIDIOC_S_FREQUENCY:
122 /* If I remove this, then it can happen that I have no
123 sound the first time I tune from static to a valid channel.
124 It's difficult to reproduce and is almost certainly related
125 to the zero cross detect circuit. */
126 wm8775_write(client, R21, 0x0c0);
127 wm8775_write(client, R14, 0x1d4);
128 wm8775_write(client, R15, 0x1d4);
129 wm8775_write(client, R21, 0x100 + state->input);
130 break;
131
132 default:
133 return -EINVAL;
134 }
135 return 0;
136}
137
138/* ----------------------------------------------------------------------- */
139
140/* i2c implementation */
141
142/*
143 * Generic i2c probe
144 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
145 */
146
147static struct i2c_driver i2c_driver;
148
149static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind)
150{
151 struct i2c_client *client;
152 struct wm8775_state *state;
153
154 /* Check if the adapter supports the needed features */
155 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
156 return 0;
157
158 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
159 if (client == 0)
160 return -ENOMEM;
161
162 memset(client, 0, sizeof(struct i2c_client));
163 client->addr = address;
164 client->adapter = adapter;
165 client->driver = &i2c_driver;
166 client->flags = I2C_CLIENT_ALLOW_USE;
167 snprintf(client->name, sizeof(client->name) - 1, "wm8775");
168
169 wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
170
171 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
172 if (state == NULL) {
173 kfree(client);
174 return -ENOMEM;
175 }
176 state->input = 2;
177 state->muted = 0;
178 i2c_set_clientdata(client, state);
179
180 /* initialize wm8775 */
181 wm8775_write(client, R23, 0x000); /* RESET */
182 wm8775_write(client, R7, 0x000); /* Disable zero cross detect timeout */
183 wm8775_write(client, R11, 0x021); /* Left justified, 24-bit mode */
184 wm8775_write(client, R12, 0x102); /* Master mode, clock ratio 256fs */
185 wm8775_write(client, R13, 0x000); /* Powered up */
186 wm8775_write(client, R14, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
187 wm8775_write(client, R15, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
188 wm8775_write(client, R16, 0x1bf); /* ALC Stereo, ALC target level -1dB FS */
189 /* max gain +8dB */
190 wm8775_write(client, R17, 0x185); /* Enable gain control, use zero cross */
191 /* detection, ALC hold time 42.6 ms */
192 wm8775_write(client, R18, 0x0a2); /* ALC gain ramp up delay 34 s, */
193 /* ALC gain ramp down delay 33 ms */
194 wm8775_write(client, R19, 0x005); /* Enable noise gate, threshold -72dBfs */
195 wm8775_write(client, R20, 0x07a); /* Transient window 4ms, lower PGA gain */
196 /* limit -1dB */
197 wm8775_write(client, R21, 0x102); /* LRBOTH = 1, use input 2. */
198 i2c_attach_client(client);
199
200 return 0;
201}
202
203static int wm8775_probe(struct i2c_adapter *adapter)
204{
205#ifdef I2C_CLASS_TV_ANALOG
206 if (adapter->class & I2C_CLASS_TV_ANALOG)
207#else
208 if (adapter->id == I2C_HW_B_BT848)
209#endif
210 return i2c_probe(adapter, &addr_data, wm8775_attach);
211 return 0;
212}
213
214static int wm8775_detach(struct i2c_client *client)
215{
216 int err;
217
218 err = i2c_detach_client(client);
219 if (err) {
220 return err;
221 }
222 kfree(client);
223
224 return 0;
225}
226
227/* ----------------------------------------------------------------------- */
228
229/* i2c implementation */
230static struct i2c_driver i2c_driver = {
231 .name = "wm8775",
232
233 .id = I2C_DRIVERID_WM8775,
234 .flags = I2C_DF_NOTIFY,
235
236 .attach_adapter = wm8775_probe,
237 .detach_client = wm8775_detach,
238 .command = wm8775_command,
239 .owner = THIS_MODULE,
240};
241
242
243static int __init wm8775_init_module(void)
244{
245 return i2c_add_driver(&i2c_driver);
246}
247
248static void __exit wm8775_cleanup_module(void)
249{
250 i2c_del_driver(&i2c_driver);
251}
252
253module_init(wm8775_init_module);
254module_exit(wm8775_cleanup_module);
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
index d4740a89cea1..4ed898585c70 100644
--- a/drivers/media/video/zr36016.c
+++ b/drivers/media/video/zr36016.c
@@ -26,7 +26,6 @@
26 26
27#define ZR016_VERSION "v0.7" 27#define ZR016_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
index 13b1e7b6fd6e..0144576a6123 100644
--- a/drivers/media/video/zr36050.c
+++ b/drivers/media/video/zr36050.c
@@ -26,7 +26,6 @@
26 26
27#define ZR050_VERSION "v0.7.1" 27#define ZR050_VERSION "v0.7.1"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
index b50dc403e6db..129744a07abd 100644
--- a/drivers/media/video/zr36060.c
+++ b/drivers/media/video/zr36060.c
@@ -26,7 +26,6 @@
26 26
27#define ZR060_VERSION "v0.7" 27#define ZR060_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 790a2932ded9..74022316fc63 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -47,7 +47,6 @@
47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 48
49#include <linux/config.h> 49#include <linux/config.h>
50#include <linux/version.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
@@ -92,9 +91,9 @@ static int mfcounter = 0;
92 * Public data... 91 * Public data...
93 */ 92 */
94int mpt_lan_index = -1; 93int mpt_lan_index = -1;
95int mpt_stm_index = -1; 94static int mpt_stm_index = -1;
96 95
97struct proc_dir_entry *mpt_proc_root_dir; 96static struct proc_dir_entry *mpt_proc_root_dir;
98 97
99#define WHOINIT_UNKNOWN 0xAA 98#define WHOINIT_UNKNOWN 0xAA
100 99
@@ -6272,7 +6271,6 @@ EXPORT_SYMBOL(mpt_resume);
6272EXPORT_SYMBOL(mpt_suspend); 6271EXPORT_SYMBOL(mpt_suspend);
6273#endif 6272#endif
6274EXPORT_SYMBOL(ioc_list); 6273EXPORT_SYMBOL(ioc_list);
6275EXPORT_SYMBOL(mpt_proc_root_dir);
6276EXPORT_SYMBOL(mpt_register); 6274EXPORT_SYMBOL(mpt_register);
6277EXPORT_SYMBOL(mpt_deregister); 6275EXPORT_SYMBOL(mpt_deregister);
6278EXPORT_SYMBOL(mpt_event_register); 6276EXPORT_SYMBOL(mpt_event_register);
@@ -6290,7 +6288,6 @@ EXPORT_SYMBOL(mpt_verify_adapter);
6290EXPORT_SYMBOL(mpt_GetIocState); 6288EXPORT_SYMBOL(mpt_GetIocState);
6291EXPORT_SYMBOL(mpt_print_ioc_summary); 6289EXPORT_SYMBOL(mpt_print_ioc_summary);
6292EXPORT_SYMBOL(mpt_lan_index); 6290EXPORT_SYMBOL(mpt_lan_index);
6293EXPORT_SYMBOL(mpt_stm_index);
6294EXPORT_SYMBOL(mpt_HardResetHandler); 6291EXPORT_SYMBOL(mpt_HardResetHandler);
6295EXPORT_SYMBOL(mpt_config); 6292EXPORT_SYMBOL(mpt_config);
6296EXPORT_SYMBOL(mpt_toolbox); 6293EXPORT_SYMBOL(mpt_toolbox);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index e7efeb7740b9..8ad277a9afa1 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -49,7 +49,6 @@
49#define MPTBASE_H_INCLUDED 49#define MPTBASE_H_INCLUDED
50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include <linux/version.h>
53#include <linux/config.h> 52#include <linux/config.h>
54#include <linux/kernel.h> 53#include <linux/kernel.h>
55#include <linux/pci.h> 54#include <linux/pci.h>
@@ -1007,10 +1006,8 @@ extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1007 * Public data decl's... 1006 * Public data decl's...
1008 */ 1007 */
1009extern struct list_head ioc_list; 1008extern struct list_head ioc_list;
1010extern struct proc_dir_entry *mpt_proc_root_dir;
1011 1009
1012extern int mpt_lan_index; /* needed by mptlan.c */ 1010extern int mpt_lan_index; /* needed by mptlan.c */
1013extern int mpt_stm_index; /* needed by mptstm.c */
1014 1011
1015/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1012/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1016#endif /* } __KERNEL__ */ 1013#endif /* } __KERNEL__ */
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index cb2d59d5f5af..602138f8544d 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -45,7 +45,6 @@
45*/ 45*/
46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 47
48#include <linux/version.h>
49#include <linux/kernel.h> 48#include <linux/kernel.h>
50#include <linux/module.h> 49#include <linux/module.h>
51#include <linux/errno.h> 50#include <linux/errno.h>
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index 28754a9cb803..518996e03481 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -49,7 +49,6 @@
49#define MPTCTL_H_INCLUDED 49#define MPTCTL_H_INCLUDED
50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include "linux/version.h"
53 52
54 53
55/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 54/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 750e343eb981..3726ecba5707 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -66,7 +66,6 @@
66#include <linux/slab.h> 66#include <linux/slab.h>
67#include <linux/miscdevice.h> 67#include <linux/miscdevice.h>
68#include <linux/spinlock.h> 68#include <linux/spinlock.h>
69#include <linux/version.h>
70#include <linux/workqueue.h> 69#include <linux/workqueue.h>
71#include <linux/delay.h> 70#include <linux/delay.h>
72// #include <linux/trdevice.h> 71// #include <linux/trdevice.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 226a7cd4ee3d..11a801be71c8 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/spinlock.h> 19#include <linux/spinlock.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index 21da8a6ff8a1..ea9d5f233c83 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index ecce4ffd3e23..d7e20a34f88d 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -31,7 +31,6 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/config.h> 32#include <linux/config.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/version.h>
35#include <linux/interrupt.h> 34#include <linux/interrupt.h>
36#include <linux/device.h> 35#include <linux/device.h>
37#include <linux/input.h> 36#include <linux/input.h>
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index ea23a31fac90..c7eb7c269081 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -42,7 +42,7 @@
42#include "wbsd.h" 42#include "wbsd.h"
43 43
44#define DRIVER_NAME "wbsd" 44#define DRIVER_NAME "wbsd"
45#define DRIVER_VERSION "1.4" 45#define DRIVER_VERSION "1.5"
46 46
47#ifdef CONFIG_MMC_DEBUG 47#ifdef CONFIG_MMC_DEBUG
48#define DBG(x...) \ 48#define DBG(x...) \
@@ -2040,7 +2040,7 @@ static struct platform_device *wbsd_device;
2040 2040
2041static struct platform_driver wbsd_driver = { 2041static struct platform_driver wbsd_driver = {
2042 .probe = wbsd_probe, 2042 .probe = wbsd_probe,
2043 .remove = wbsd_remove, 2043 .remove = __devexit_p(wbsd_remove),
2044 2044
2045 .suspend = wbsd_suspend, 2045 .suspend = wbsd_suspend,
2046 .resume = wbsd_resume, 2046 .resume = wbsd_resume,
@@ -2055,7 +2055,7 @@ static struct pnp_driver wbsd_pnp_driver = {
2055 .name = DRIVER_NAME, 2055 .name = DRIVER_NAME,
2056 .id_table = pnp_dev_table, 2056 .id_table = pnp_dev_table,
2057 .probe = wbsd_pnp_probe, 2057 .probe = wbsd_pnp_probe,
2058 .remove = wbsd_pnp_remove, 2058 .remove = __devexit_p(wbsd_pnp_remove),
2059}; 2059};
2060 2060
2061#endif /* CONFIG_PNP */ 2061#endif /* CONFIG_PNP */
@@ -2128,6 +2128,7 @@ module_param(irq, uint, 0444);
2128module_param(dma, int, 0444); 2128module_param(dma, int, 0444);
2129 2129
2130MODULE_LICENSE("GPL"); 2130MODULE_LICENSE("GPL");
2131MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
2131MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver"); 2132MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
2132MODULE_VERSION(DRIVER_VERSION); 2133MODULE_VERSION(DRIVER_VERSION);
2133 2134
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index c4a19d2dc67f..0807c1c91e55 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -20,7 +20,6 @@
20 * - Plugged memory leak in cfi_staa_writev(). 20 * - Plugged memory leak in cfi_staa_writev().
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/types.h> 24#include <linux/types.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index de48b35f5609..666cce1bf60c 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -82,7 +82,6 @@
82 * * Comb the init routine. It's still a bit cludgy on a few things. 82 * * Comb the init routine. It's still a bit cludgy on a few things.
83 */ 83 */
84 84
85#include <linux/version.h>
86#include <linux/config.h> 85#include <linux/config.h>
87#include <linux/kernel.h> 86#include <linux/kernel.h>
88#include <linux/module.h> 87#include <linux/module.h>
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index c0daf58357ca..60a6e51d662f 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm44x.h> 25#include <asm/ibm44x.h>
27#include <platforms/4xx/ebony.h> 26#include <platforms/4xx/ebony.h>
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index 6e559bc14636..c223514ca2eb 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -19,7 +19,6 @@
19#include <linux/mtd/map.h> 19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/version.h>
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/ibm44x.h> 23#include <asm/ibm44x.h>
25#include <platforms/4xx/ocotea.h> 24#include <platforms/4xx/ocotea.h>
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index 5c17bca3a37e..f46bec66150f 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm4xx.h> 25#include <asm/ibm4xx.h>
27#include <platforms/4xx/walnut.h> 26#include <platforms/4xx/walnut.h>
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 3cafcdf28aed..9c5945d6df88 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -17,6 +17,7 @@
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h> 18#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
20#include <linux/version.h>
20#include <asm/io.h> 21#include <asm/io.h>
21 22
22/* fixme: this is ugly */ 23/* fixme: this is ugly */
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 056dfc17a075..a3c7fea404d0 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -27,7 +27,6 @@
27 * 10-06-2002 TG 128K card support added 27 * 10-06-2002 TG 128K card support added
28 */ 28 */
29 29
30#include <linux/version.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/module.h> 32#include <linux/module.h>
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index cc38fa0d45c6..f67d5d6eb9a6 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -12,6 +12,8 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/sched.h>
16#include <linux/jiffies.h>
15#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
16#include <linux/mtd/onenand.h> 18#include <linux/mtd/onenand.h>
17#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index 041ee59ea77d..0ab8d29caeea 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -18,6 +18,7 @@
18#include <linux/mtd/blktrans.h> 18#include <linux/mtd/blktrans.h>
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/jiffies.h>
21 22
22#include <asm/types.h> 23#include <asm/types.h>
23 24
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 24f1691b84f9..5c69d57f8548 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@ config NET_SB1250_MAC
447 447
448config SGI_IOC3_ETH 448config SGI_IOC3_ETH
449 bool "SGI IOC3 Ethernet" 449 bool "SGI IOC3 Ethernet"
450 depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN 450 depends on NET_ETHERNET && PCI && SGI_IP27
451 select CRC32 451 select CRC32
452 select MII 452 select MII
453 help 453 help
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 0ee3e27969c6..c53848f787eb 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -18,7 +18,6 @@
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/version.h>
22#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
23 22
24#include <asm/uaccess.h> 23#include <asm/uaccess.h>
@@ -29,8 +28,8 @@
29 28
30#define DRV_MODULE_NAME "b44" 29#define DRV_MODULE_NAME "b44"
31#define PFX DRV_MODULE_NAME ": " 30#define PFX DRV_MODULE_NAME ": "
32#define DRV_MODULE_VERSION "0.95" 31#define DRV_MODULE_VERSION "0.96"
33#define DRV_MODULE_RELDATE "Aug 3, 2004" 32#define DRV_MODULE_RELDATE "Nov 8, 2005"
34 33
35#define B44_DEF_MSG_ENABLE \ 34#define B44_DEF_MSG_ENABLE \
36 (NETIF_MSG_DRV | \ 35 (NETIF_MSG_DRV | \
@@ -102,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
102static void b44_halt(struct b44 *); 101static void b44_halt(struct b44 *);
103static void b44_init_rings(struct b44 *); 102static void b44_init_rings(struct b44 *);
104static void b44_init_hw(struct b44 *); 103static void b44_init_hw(struct b44 *);
105static int b44_poll(struct net_device *dev, int *budget);
106#ifdef CONFIG_NET_POLL_CONTROLLER
107static void b44_poll_controller(struct net_device *dev);
108#endif
109 104
110static int dma_desc_align_mask; 105static int dma_desc_align_mask;
111static int dma_desc_sync_size; 106static int dma_desc_sync_size;
112 107
108static const char b44_gstrings[][ETH_GSTRING_LEN] = {
109#define _B44(x...) # x,
110B44_STAT_REG_DECLARE
111#undef _B44
112};
113
113static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, 114static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
114 dma_addr_t dma_base, 115 dma_addr_t dma_base,
115 unsigned long offset, 116 unsigned long offset,
@@ -502,7 +503,10 @@ static void b44_stats_update(struct b44 *bp)
502 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { 503 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
503 *val++ += br32(bp, reg); 504 *val++ += br32(bp, reg);
504 } 505 }
505 val = &bp->hw_stats.rx_good_octets; 506
507 /* Pad */
508 reg += 8*4UL;
509
506 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { 510 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
507 *val++ += br32(bp, reg); 511 *val++ += br32(bp, reg);
508 } 512 }
@@ -653,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
653 657
654 /* Hardware bug work-around, the chip is unable to do PCI DMA 658 /* Hardware bug work-around, the chip is unable to do PCI DMA
655 to/from anything above 1GB :-( */ 659 to/from anything above 1GB :-( */
656 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 660 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
657 /* Sigh... */ 661 /* Sigh... */
658 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 662 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
659 dev_kfree_skb_any(skb); 663 dev_kfree_skb_any(skb);
@@ -663,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
663 mapping = pci_map_single(bp->pdev, skb->data, 667 mapping = pci_map_single(bp->pdev, skb->data,
664 RX_PKT_BUF_SZ, 668 RX_PKT_BUF_SZ,
665 PCI_DMA_FROMDEVICE); 669 PCI_DMA_FROMDEVICE);
666 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 670 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
667 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 671 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
668 dev_kfree_skb_any(skb); 672 dev_kfree_skb_any(skb);
669 return -ENOMEM; 673 return -ENOMEM;
@@ -890,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
890{ 894{
891 struct net_device *dev = dev_id; 895 struct net_device *dev = dev_id;
892 struct b44 *bp = netdev_priv(dev); 896 struct b44 *bp = netdev_priv(dev);
893 unsigned long flags;
894 u32 istat, imask; 897 u32 istat, imask;
895 int handled = 0; 898 int handled = 0;
896 899
897 spin_lock_irqsave(&bp->lock, flags); 900 spin_lock(&bp->lock);
898 901
899 istat = br32(bp, B44_ISTAT); 902 istat = br32(bp, B44_ISTAT);
900 imask = br32(bp, B44_IMASK); 903 imask = br32(bp, B44_IMASK);
@@ -905,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
905 istat &= imask; 908 istat &= imask;
906 if (istat) { 909 if (istat) {
907 handled = 1; 910 handled = 1;
911
912 if (unlikely(!netif_running(dev))) {
913 printk(KERN_INFO "%s: late interrupt.\n", dev->name);
914 goto irq_ack;
915 }
916
908 if (netif_rx_schedule_prep(dev)) { 917 if (netif_rx_schedule_prep(dev)) {
909 /* NOTE: These writes are posted by the readback of 918 /* NOTE: These writes are posted by the readback of
910 * the ISTAT register below. 919 * the ISTAT register below.
@@ -917,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
917 dev->name); 926 dev->name);
918 } 927 }
919 928
929irq_ack:
920 bw32(bp, B44_ISTAT, istat); 930 bw32(bp, B44_ISTAT, istat);
921 br32(bp, B44_ISTAT); 931 br32(bp, B44_ISTAT);
922 } 932 }
923 spin_unlock_irqrestore(&bp->lock, flags); 933 spin_unlock(&bp->lock);
924 return IRQ_RETVAL(handled); 934 return IRQ_RETVAL(handled);
925} 935}
926 936
@@ -948,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
948{ 958{
949 struct b44 *bp = netdev_priv(dev); 959 struct b44 *bp = netdev_priv(dev);
950 struct sk_buff *bounce_skb; 960 struct sk_buff *bounce_skb;
961 int rc = NETDEV_TX_OK;
951 dma_addr_t mapping; 962 dma_addr_t mapping;
952 u32 len, entry, ctrl; 963 u32 len, entry, ctrl;
953 964
@@ -957,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
957 /* This is a hard error, log it. */ 968 /* This is a hard error, log it. */
958 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { 969 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
959 netif_stop_queue(dev); 970 netif_stop_queue(dev);
960 spin_unlock_irq(&bp->lock);
961 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", 971 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
962 dev->name); 972 dev->name);
963 return 1; 973 goto err_out;
964 } 974 }
965 975
966 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); 976 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
967 if(mapping+len > B44_DMA_MASK) { 977 if (mapping + len > B44_DMA_MASK) {
968 /* Chip can't handle DMA to/from >1GB, use bounce buffer */ 978 /* Chip can't handle DMA to/from >1GB, use bounce buffer */
969 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); 979 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
970 980
971 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, 981 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
972 GFP_ATOMIC|GFP_DMA); 982 GFP_ATOMIC|GFP_DMA);
973 if (!bounce_skb) 983 if (!bounce_skb)
974 return NETDEV_TX_BUSY; 984 goto err_out;
975 985
976 mapping = pci_map_single(bp->pdev, bounce_skb->data, 986 mapping = pci_map_single(bp->pdev, bounce_skb->data,
977 len, PCI_DMA_TODEVICE); 987 len, PCI_DMA_TODEVICE);
978 if(mapping+len > B44_DMA_MASK) { 988 if (mapping + len > B44_DMA_MASK) {
979 pci_unmap_single(bp->pdev, mapping, 989 pci_unmap_single(bp->pdev, mapping,
980 len, PCI_DMA_TODEVICE); 990 len, PCI_DMA_TODEVICE);
981 dev_kfree_skb_any(bounce_skb); 991 dev_kfree_skb_any(bounce_skb);
982 return NETDEV_TX_BUSY; 992 goto err_out;
983 } 993 }
984 994
985 memcpy(skb_put(bounce_skb, len), skb->data, skb->len); 995 memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
@@ -1019,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
1019 if (TX_BUFFS_AVAIL(bp) < 1) 1029 if (TX_BUFFS_AVAIL(bp) < 1)
1020 netif_stop_queue(dev); 1030 netif_stop_queue(dev);
1021 1031
1032 dev->trans_start = jiffies;
1033
1034out_unlock:
1022 spin_unlock_irq(&bp->lock); 1035 spin_unlock_irq(&bp->lock);
1023 1036
1024 dev->trans_start = jiffies; 1037 return rc;
1025 1038
1026 return 0; 1039err_out:
1040 rc = NETDEV_TX_BUSY;
1041 goto out_unlock;
1027} 1042}
1028 1043
1029static int b44_change_mtu(struct net_device *dev, int new_mtu) 1044static int b44_change_mtu(struct net_device *dev, int new_mtu)
@@ -1097,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp)
1097 * 1112 *
1098 * The chip has been shut down and the driver detached from 1113 * The chip has been shut down and the driver detached from
1099 * the networking, so no interrupts or new tx packets will 1114 * the networking, so no interrupts or new tx packets will
1100 * end up in the driver. bp->lock is not held and we are not 1115 * end up in the driver.
1101 * in an interrupt context and thus may sleep.
1102 */ 1116 */
1103static void b44_init_rings(struct b44 *bp) 1117static void b44_init_rings(struct b44 *bp)
1104{ 1118{
@@ -1170,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp)
1170 int size; 1184 int size;
1171 1185
1172 size = B44_RX_RING_SIZE * sizeof(struct ring_info); 1186 size = B44_RX_RING_SIZE * sizeof(struct ring_info);
1173 bp->rx_buffers = kmalloc(size, GFP_KERNEL); 1187 bp->rx_buffers = kzalloc(size, GFP_KERNEL);
1174 if (!bp->rx_buffers) 1188 if (!bp->rx_buffers)
1175 goto out_err; 1189 goto out_err;
1176 memset(bp->rx_buffers, 0, size);
1177 1190
1178 size = B44_TX_RING_SIZE * sizeof(struct ring_info); 1191 size = B44_TX_RING_SIZE * sizeof(struct ring_info);
1179 bp->tx_buffers = kmalloc(size, GFP_KERNEL); 1192 bp->tx_buffers = kzalloc(size, GFP_KERNEL);
1180 if (!bp->tx_buffers) 1193 if (!bp->tx_buffers)
1181 goto out_err; 1194 goto out_err;
1182 memset(bp->tx_buffers, 0, size);
1183 1195
1184 size = DMA_TABLE_BYTES; 1196 size = DMA_TABLE_BYTES;
1185 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); 1197 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
@@ -1190,10 +1202,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1190 struct dma_desc *rx_ring; 1202 struct dma_desc *rx_ring;
1191 dma_addr_t rx_ring_dma; 1203 dma_addr_t rx_ring_dma;
1192 1204
1193 if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1205 rx_ring = kzalloc(size, GFP_KERNEL);
1206 if (!rx_ring)
1194 goto out_err; 1207 goto out_err;
1195 1208
1196 memset(rx_ring, 0, size);
1197 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, 1209 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
1198 DMA_TABLE_BYTES, 1210 DMA_TABLE_BYTES,
1199 DMA_BIDIRECTIONAL); 1211 DMA_BIDIRECTIONAL);
@@ -1216,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1216 struct dma_desc *tx_ring; 1228 struct dma_desc *tx_ring;
1217 dma_addr_t tx_ring_dma; 1229 dma_addr_t tx_ring_dma;
1218 1230
1219 if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1231 tx_ring = kzalloc(size, GFP_KERNEL);
1232 if (!tx_ring)
1220 goto out_err; 1233 goto out_err;
1221 1234
1222 memset(tx_ring, 0, size);
1223 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, 1235 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
1224 DMA_TABLE_BYTES, 1236 DMA_TABLE_BYTES,
1225 DMA_TO_DEVICE); 1237 DMA_TO_DEVICE);
@@ -1382,22 +1394,21 @@ static int b44_open(struct net_device *dev)
1382 1394
1383 err = b44_alloc_consistent(bp); 1395 err = b44_alloc_consistent(bp);
1384 if (err) 1396 if (err)
1385 return err; 1397 goto out;
1386
1387 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1388 if (err)
1389 goto err_out_free;
1390
1391 spin_lock_irq(&bp->lock);
1392 1398
1393 b44_init_rings(bp); 1399 b44_init_rings(bp);
1394 b44_init_hw(bp); 1400 b44_init_hw(bp);
1395 bp->flags |= B44_FLAG_INIT_COMPLETE;
1396 1401
1397 netif_carrier_off(dev); 1402 netif_carrier_off(dev);
1398 b44_check_phy(bp); 1403 b44_check_phy(bp);
1399 1404
1400 spin_unlock_irq(&bp->lock); 1405 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1406 if (unlikely(err < 0)) {
1407 b44_chip_reset(bp);
1408 b44_free_rings(bp);
1409 b44_free_consistent(bp);
1410 goto out;
1411 }
1401 1412
1402 init_timer(&bp->timer); 1413 init_timer(&bp->timer);
1403 bp->timer.expires = jiffies + HZ; 1414 bp->timer.expires = jiffies + HZ;
@@ -1406,11 +1417,7 @@ static int b44_open(struct net_device *dev)
1406 add_timer(&bp->timer); 1417 add_timer(&bp->timer);
1407 1418
1408 b44_enable_ints(bp); 1419 b44_enable_ints(bp);
1409 1420out:
1410 return 0;
1411
1412err_out_free:
1413 b44_free_consistent(bp);
1414 return err; 1421 return err;
1415} 1422}
1416 1423
@@ -1445,6 +1452,8 @@ static int b44_close(struct net_device *dev)
1445 1452
1446 netif_stop_queue(dev); 1453 netif_stop_queue(dev);
1447 1454
1455 netif_poll_disable(dev);
1456
1448 del_timer_sync(&bp->timer); 1457 del_timer_sync(&bp->timer);
1449 1458
1450 spin_lock_irq(&bp->lock); 1459 spin_lock_irq(&bp->lock);
@@ -1454,13 +1463,14 @@ static int b44_close(struct net_device *dev)
1454#endif 1463#endif
1455 b44_halt(bp); 1464 b44_halt(bp);
1456 b44_free_rings(bp); 1465 b44_free_rings(bp);
1457 bp->flags &= ~B44_FLAG_INIT_COMPLETE;
1458 netif_carrier_off(bp->dev); 1466 netif_carrier_off(bp->dev);
1459 1467
1460 spin_unlock_irq(&bp->lock); 1468 spin_unlock_irq(&bp->lock);
1461 1469
1462 free_irq(dev->irq, dev); 1470 free_irq(dev->irq, dev);
1463 1471
1472 netif_poll_enable(dev);
1473
1464 b44_free_consistent(bp); 1474 b44_free_consistent(bp);
1465 1475
1466 return 0; 1476 return 0;
@@ -1525,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev)
1525{ 1535{
1526 struct b44 *bp = netdev_priv(dev); 1536 struct b44 *bp = netdev_priv(dev);
1527 u32 val; 1537 u32 val;
1528 int i=0;
1529 unsigned char zero[6] = {0,0,0,0,0,0};
1530 1538
1531 val = br32(bp, B44_RXCONFIG); 1539 val = br32(bp, B44_RXCONFIG);
1532 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); 1540 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
@@ -1534,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev)
1534 val |= RXCONFIG_PROMISC; 1542 val |= RXCONFIG_PROMISC;
1535 bw32(bp, B44_RXCONFIG, val); 1543 bw32(bp, B44_RXCONFIG, val);
1536 } else { 1544 } else {
1545 unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
1546 int i = 0;
1547
1537 __b44_set_mac_addr(bp); 1548 __b44_set_mac_addr(bp);
1538 1549
1539 if (dev->flags & IFF_ALLMULTI) 1550 if (dev->flags & IFF_ALLMULTI)
1540 val |= RXCONFIG_ALLMULTI; 1551 val |= RXCONFIG_ALLMULTI;
1541 else 1552 else
1542 i=__b44_load_mcast(bp, dev); 1553 i = __b44_load_mcast(bp, dev);
1543 1554
1544 for(;i<64;i++) { 1555 for (; i < 64; i++) {
1545 __b44_cam_write(bp, zero, i); 1556 __b44_cam_write(bp, zero, i);
1546 } 1557 }
1547 bw32(bp, B44_RXCONFIG, val); 1558 bw32(bp, B44_RXCONFIG, val);
@@ -1605,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1605{ 1616{
1606 struct b44 *bp = netdev_priv(dev); 1617 struct b44 *bp = netdev_priv(dev);
1607 1618
1608 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1619 if (!netif_running(dev))
1609 return -EAGAIN; 1620 return -EAGAIN;
1610 cmd->supported = (SUPPORTED_Autoneg); 1621 cmd->supported = (SUPPORTED_Autoneg);
1611 cmd->supported |= (SUPPORTED_100baseT_Half | 1622 cmd->supported |= (SUPPORTED_100baseT_Half |
@@ -1643,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1643{ 1654{
1644 struct b44 *bp = netdev_priv(dev); 1655 struct b44 *bp = netdev_priv(dev);
1645 1656
1646 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1657 if (!netif_running(dev))
1647 return -EAGAIN; 1658 return -EAGAIN;
1648 1659
1649 /* We do not support gigabit. */ 1660 /* We do not support gigabit. */
@@ -1773,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev,
1773 return 0; 1784 return 0;
1774} 1785}
1775 1786
1787static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1788{
1789 switch(stringset) {
1790 case ETH_SS_STATS:
1791 memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
1792 break;
1793 }
1794}
1795
1796static int b44_get_stats_count(struct net_device *dev)
1797{
1798 return ARRAY_SIZE(b44_gstrings);
1799}
1800
1801static void b44_get_ethtool_stats(struct net_device *dev,
1802 struct ethtool_stats *stats, u64 *data)
1803{
1804 struct b44 *bp = netdev_priv(dev);
1805 u32 *val = &bp->hw_stats.tx_good_octets;
1806 u32 i;
1807
1808 spin_lock_irq(&bp->lock);
1809
1810 b44_stats_update(bp);
1811
1812 for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
1813 *data++ = *val++;
1814
1815 spin_unlock_irq(&bp->lock);
1816}
1817
1776static struct ethtool_ops b44_ethtool_ops = { 1818static struct ethtool_ops b44_ethtool_ops = {
1777 .get_drvinfo = b44_get_drvinfo, 1819 .get_drvinfo = b44_get_drvinfo,
1778 .get_settings = b44_get_settings, 1820 .get_settings = b44_get_settings,
@@ -1785,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = {
1785 .set_pauseparam = b44_set_pauseparam, 1827 .set_pauseparam = b44_set_pauseparam,
1786 .get_msglevel = b44_get_msglevel, 1828 .get_msglevel = b44_get_msglevel,
1787 .set_msglevel = b44_set_msglevel, 1829 .set_msglevel = b44_set_msglevel,
1830 .get_strings = b44_get_strings,
1831 .get_stats_count = b44_get_stats_count,
1832 .get_ethtool_stats = b44_get_ethtool_stats,
1788 .get_perm_addr = ethtool_op_get_perm_addr, 1833 .get_perm_addr = ethtool_op_get_perm_addr,
1789}; 1834};
1790 1835
@@ -1893,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1893 1938
1894 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); 1939 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
1895 if (err) { 1940 if (err) {
1896 printk(KERN_ERR PFX "No usable DMA configuration, " 1941 printk(KERN_ERR PFX "No usable DMA configuration, "
1897 "aborting.\n"); 1942 "aborting.\n");
1898 goto err_out_free_res; 1943 goto err_out_free_res;
1899 } 1944 }
1900 1945
1901 b44reg_base = pci_resource_start(pdev, 0); 1946 b44reg_base = pci_resource_start(pdev, 0);
@@ -1917,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1917 bp = netdev_priv(dev); 1962 bp = netdev_priv(dev);
1918 bp->pdev = pdev; 1963 bp->pdev = pdev;
1919 bp->dev = dev; 1964 bp->dev = dev;
1920 if (b44_debug >= 0) 1965
1921 bp->msg_enable = (1 << b44_debug) - 1; 1966 bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
1922 else
1923 bp->msg_enable = B44_DEF_MSG_ENABLE;
1924 1967
1925 spin_lock_init(&bp->lock); 1968 spin_lock_init(&bp->lock);
1926 1969
@@ -2010,17 +2053,14 @@ err_out_disable_pdev:
2010static void __devexit b44_remove_one(struct pci_dev *pdev) 2053static void __devexit b44_remove_one(struct pci_dev *pdev)
2011{ 2054{
2012 struct net_device *dev = pci_get_drvdata(pdev); 2055 struct net_device *dev = pci_get_drvdata(pdev);
2056 struct b44 *bp = netdev_priv(dev);
2013 2057
2014 if (dev) { 2058 unregister_netdev(dev);
2015 struct b44 *bp = netdev_priv(dev); 2059 iounmap(bp->regs);
2016 2060 free_netdev(dev);
2017 unregister_netdev(dev); 2061 pci_release_regions(pdev);
2018 iounmap(bp->regs); 2062 pci_disable_device(pdev);
2019 free_netdev(dev); 2063 pci_set_drvdata(pdev, NULL);
2020 pci_release_regions(pdev);
2021 pci_disable_device(pdev);
2022 pci_set_drvdata(pdev, NULL);
2023 }
2024} 2064}
2025 2065
2026static int b44_suspend(struct pci_dev *pdev, pm_message_t state) 2066static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 593cb0ad4100..b178662978f3 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -346,29 +346,63 @@ struct ring_info {
346 346
347#define B44_MCAST_TABLE_SIZE 32 347#define B44_MCAST_TABLE_SIZE 32
348 348
349#define B44_STAT_REG_DECLARE \
350 _B44(tx_good_octets) \
351 _B44(tx_good_pkts) \
352 _B44(tx_octets) \
353 _B44(tx_pkts) \
354 _B44(tx_broadcast_pkts) \
355 _B44(tx_multicast_pkts) \
356 _B44(tx_len_64) \
357 _B44(tx_len_65_to_127) \
358 _B44(tx_len_128_to_255) \
359 _B44(tx_len_256_to_511) \
360 _B44(tx_len_512_to_1023) \
361 _B44(tx_len_1024_to_max) \
362 _B44(tx_jabber_pkts) \
363 _B44(tx_oversize_pkts) \
364 _B44(tx_fragment_pkts) \
365 _B44(tx_underruns) \
366 _B44(tx_total_cols) \
367 _B44(tx_single_cols) \
368 _B44(tx_multiple_cols) \
369 _B44(tx_excessive_cols) \
370 _B44(tx_late_cols) \
371 _B44(tx_defered) \
372 _B44(tx_carrier_lost) \
373 _B44(tx_pause_pkts) \
374 _B44(rx_good_octets) \
375 _B44(rx_good_pkts) \
376 _B44(rx_octets) \
377 _B44(rx_pkts) \
378 _B44(rx_broadcast_pkts) \
379 _B44(rx_multicast_pkts) \
380 _B44(rx_len_64) \
381 _B44(rx_len_65_to_127) \
382 _B44(rx_len_128_to_255) \
383 _B44(rx_len_256_to_511) \
384 _B44(rx_len_512_to_1023) \
385 _B44(rx_len_1024_to_max) \
386 _B44(rx_jabber_pkts) \
387 _B44(rx_oversize_pkts) \
388 _B44(rx_fragment_pkts) \
389 _B44(rx_missed_pkts) \
390 _B44(rx_crc_align_errs) \
391 _B44(rx_undersize) \
392 _B44(rx_crc_errs) \
393 _B44(rx_align_errs) \
394 _B44(rx_symbol_errs) \
395 _B44(rx_pause_pkts) \
396 _B44(rx_nonpause_pkts)
397
349/* SW copy of device statistics, kept up to date by periodic timer 398/* SW copy of device statistics, kept up to date by periodic timer
350 * which probes HW values. Must have same relative layout as HW 399 * which probes HW values. Check b44_stats_update if you mess with
351 * register above, because b44_stats_update depends upon this. 400 * the layout
352 */ 401 */
353struct b44_hw_stats { 402struct b44_hw_stats {
354 u32 tx_good_octets, tx_good_pkts, tx_octets; 403#define _B44(x) u32 x;
355 u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; 404B44_STAT_REG_DECLARE
356 u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255; 405#undef _B44
357 u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
358 u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
359 u32 tx_underruns, tx_total_cols, tx_single_cols;
360 u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
361 u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
362 u32 __pad1[8];
363
364 u32 rx_good_octets, rx_good_pkts, rx_octets;
365 u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
366 u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
367 u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
368 u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
369 u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
370 u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
371 u32 rx_pause_pkts, rx_nonpause_pkts;
372}; 406};
373 407
374struct b44 { 408struct b44 {
@@ -386,7 +420,6 @@ struct b44 {
386 420
387 u32 dma_offset; 421 u32 dma_offset;
388 u32 flags; 422 u32 flags;
389#define B44_FLAG_INIT_COMPLETE 0x00000001
390#define B44_FLAG_BUGGY_TXPTR 0x00000002 423#define B44_FLAG_BUGGY_TXPTR 0x00000002
391#define B44_FLAG_REORDER_BUG 0x00000004 424#define B44_FLAG_REORDER_BUG 0x00000004
392#define B44_FLAG_PAUSE_AUTO 0x00008000 425#define B44_FLAG_PAUSE_AUTO 0x00008000
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 8f464271664d..49fa1e4413fa 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -2707,7 +2707,7 @@ bnx2_init_nvram(struct bnx2 *bp)
2707 2707
2708 if (j == entry_count) { 2708 if (j == entry_count) {
2709 bp->flash_info = NULL; 2709 bp->flash_info = NULL;
2710 printk(KERN_ALERT "Unknown flash/EEPROM type.\n"); 2710 printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
2711 rc = -ENODEV; 2711 rc = -ENODEV;
2712 } 2712 }
2713 2713
@@ -3903,6 +3903,8 @@ bnx2_test_loopback(struct bnx2 *bp)
3903 3903
3904 pkt_size = 1514; 3904 pkt_size = 1514;
3905 skb = dev_alloc_skb(pkt_size); 3905 skb = dev_alloc_skb(pkt_size);
3906 if (!skb)
3907 return -ENOMEM;
3906 packet = skb_put(skb, pkt_size); 3908 packet = skb_put(skb, pkt_size);
3907 memcpy(packet, bp->mac_addr, 6); 3909 memcpy(packet, bp->mac_addr, 6);
3908 memset(packet + 6, 0x0, 8); 3910 memset(packet + 6, 0x0, 8);
@@ -4798,11 +4800,7 @@ bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
4798 struct bnx2 *bp = dev->priv; 4800 struct bnx2 *bp = dev->priv;
4799 int rc; 4801 int rc;
4800 4802
4801 if (eeprom->offset > bp->flash_info->total_size) 4803 /* parameters already validated in ethtool_get_eeprom */
4802 return -EINVAL;
4803
4804 if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
4805 eeprom->len = bp->flash_info->total_size - eeprom->offset;
4806 4804
4807 rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); 4805 rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
4808 4806
@@ -4816,11 +4814,7 @@ bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
4816 struct bnx2 *bp = dev->priv; 4814 struct bnx2 *bp = dev->priv;
4817 int rc; 4815 int rc;
4818 4816
4819 if (eeprom->offset > bp->flash_info->total_size) 4817 /* parameters already validated in ethtool_set_eeprom */
4820 return -EINVAL;
4821
4822 if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
4823 eeprom->len = bp->flash_info->total_size - eeprom->offset;
4824 4818
4825 rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); 4819 rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
4826 4820
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8032126fd589..94cec3cf2a13 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) 1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
1605 1605
1606/* 1606/*
1607 * Compute the features available to the bonding device by 1607 * Compute the common dev->feature set available to all slaves. Some
1608 * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. 1608 * feature bits are managed elsewhere, so preserve feature bits set on
1609 * Call this after attaching or detaching a slave to update the 1609 * master device that are not part of the examined set.
1610 * bond's features.
1611 */ 1610 */
1612static int bond_compute_features(struct bonding *bond) 1611static int bond_compute_features(struct bonding *bond)
1613{ 1612{
1614 int i; 1613 unsigned long features = BOND_INTERSECT_FEATURES;
1615 struct slave *slave; 1614 struct slave *slave;
1616 struct net_device *bond_dev = bond->dev; 1615 struct net_device *bond_dev = bond->dev;
1617 int features = bond->bond_features; 1616 int i;
1618 1617
1619 bond_for_each_slave(bond, slave, i) { 1618 bond_for_each_slave(bond, slave, i)
1620 struct net_device * slave_dev = slave->dev; 1619 features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
1621 if (i == 0) {
1622 features |= BOND_INTERSECT_FEATURES;
1623 }
1624 features &=
1625 ~(~slave_dev->features & BOND_INTERSECT_FEATURES);
1626 }
1627 1620
1628 /* turn off NETIF_F_SG if we need a csum and h/w can't do it */
1629 if ((features & NETIF_F_SG) && 1621 if ((features & NETIF_F_SG) &&
1630 !(features & (NETIF_F_IP_CSUM | 1622 !(features & (NETIF_F_IP_CSUM |
1631 NETIF_F_NO_CSUM | 1623 NETIF_F_NO_CSUM |
1632 NETIF_F_HW_CSUM))) { 1624 NETIF_F_HW_CSUM)))
1633 features &= ~NETIF_F_SG; 1625 features &= ~NETIF_F_SG;
1634 }
1635 1626
1627 features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
1636 bond_dev->features = features; 1628 bond_dev->features = features;
1637 1629
1638 return 0; 1630 return 0;
@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
4561 NETIF_F_HW_VLAN_RX | 4553 NETIF_F_HW_VLAN_RX |
4562 NETIF_F_HW_VLAN_FILTER); 4554 NETIF_F_HW_VLAN_FILTER);
4563 4555
4564 bond->bond_features = bond_dev->features;
4565
4566#ifdef CONFIG_PROC_FS 4556#ifdef CONFIG_PROC_FS
4567 bond_create_proc_entry(bond); 4557 bond_create_proc_entry(bond);
4568#endif 4558#endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index bbf9da8af624..1433e91db0f7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -40,8 +40,8 @@
40#include "bond_3ad.h" 40#include "bond_3ad.h"
41#include "bond_alb.h" 41#include "bond_alb.h"
42 42
43#define DRV_VERSION "2.6.4" 43#define DRV_VERSION "2.6.5"
44#define DRV_RELDATE "September 26, 2005" 44#define DRV_RELDATE "November 4, 2005"
45#define DRV_NAME "bonding" 45#define DRV_NAME "bonding"
46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
47 47
@@ -211,9 +211,6 @@ struct bonding {
211 struct bond_params params; 211 struct bond_params params;
212 struct list_head vlan_list; 212 struct list_head vlan_list;
213 struct vlan_group *vlgrp; 213 struct vlan_group *vlgrp;
214 /* the features the bonding device supports, independently
215 * of any slaves */
216 int bond_features;
217}; 214};
218 215
219/** 216/**
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 50f43dbf31ae..1f7ca453bb4a 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -67,7 +67,6 @@
67 */ 67 */
68 68
69#include <linux/config.h> 69#include <linux/config.h>
70#include <linux/version.h>
71 70
72#include <linux/module.h> 71#include <linux/module.h>
73#include <linux/kernel.h> 72#include <linux/kernel.h>
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index b68b9cad76e9..64105e4eaf31 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
409static void e100_rx(struct net_device *dev); 409static void e100_rx(struct net_device *dev);
410static int e100_close(struct net_device *dev); 410static int e100_close(struct net_device *dev);
411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
412static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
413static int e100_set_config(struct net_device* dev, struct ifmap* map); 412static int e100_set_config(struct net_device* dev, struct ifmap* map);
414static void e100_tx_timeout(struct net_device *dev); 413static void e100_tx_timeout(struct net_device *dev);
415static struct net_device_stats *e100_get_stats(struct net_device *dev); 414static struct net_device_stats *e100_get_stats(struct net_device *dev);
@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net);
436static void e100_clear_network_leds(unsigned long dummy); 435static void e100_clear_network_leds(unsigned long dummy);
437static void e100_set_network_leds(int active); 436static void e100_set_network_leds(int active);
438 437
438static struct ethtool_ops e100_ethtool_ops;
439
439static void broadcom_check_speed(struct net_device* dev); 440static void broadcom_check_speed(struct net_device* dev);
440static void broadcom_check_duplex(struct net_device* dev); 441static void broadcom_check_duplex(struct net_device* dev);
441static void tdk_check_speed(struct net_device* dev); 442static void tdk_check_speed(struct net_device* dev);
@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
495 dev->get_stats = e100_get_stats; 496 dev->get_stats = e100_get_stats;
496 dev->set_multicast_list = set_multicast_list; 497 dev->set_multicast_list = set_multicast_list;
497 dev->set_mac_address = e100_set_mac_address; 498 dev->set_mac_address = e100_set_mac_address;
499 dev->ethtool_ops = &e100_ethtool_ops;
498 dev->do_ioctl = e100_ioctl; 500 dev->do_ioctl = e100_ioctl;
499 dev->set_config = e100_set_config; 501 dev->set_config = e100_set_config;
500 dev->tx_timeout = e100_tx_timeout; 502 dev->tx_timeout = e100_tx_timeout;
@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1448 1450
1449 spin_lock(&np->lock); /* Preempt protection */ 1451 spin_lock(&np->lock); /* Preempt protection */
1450 switch (cmd) { 1452 switch (cmd) {
1451 case SIOCETHTOOL:
1452 return e100_ethtool_ioctl(dev,ifr);
1453 case SIOCGMIIPHY: /* Get PHY address */ 1453 case SIOCGMIIPHY: /* Get PHY address */
1454 data->phy_id = mdio_phy_addr; 1454 data->phy_id = mdio_phy_addr;
1455 break; 1455 break;
@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1486 return 0; 1486 return 0;
1487} 1487}
1488 1488
1489static int 1489static int e100_set_settings(struct net_device *dev,
1490e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) 1490 struct ethtool_cmd *ecmd)
1491{ 1491{
1492 struct ethtool_cmd ecmd; 1492 ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1493
1494 if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
1495 return -EFAULT;
1496
1497 switch (ecmd.cmd) {
1498 case ETHTOOL_GSET:
1499 {
1500 memset((void *) &ecmd, 0, sizeof (ecmd));
1501 ecmd.supported =
1502 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1503 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | 1493 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
1504 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; 1494 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
1505 ecmd.port = PORT_TP; 1495 ecmd->port = PORT_TP;
1506 ecmd.transceiver = XCVR_EXTERNAL; 1496 ecmd->transceiver = XCVR_EXTERNAL;
1507 ecmd.phy_address = mdio_phy_addr; 1497 ecmd->phy_address = mdio_phy_addr;
1508 ecmd.speed = current_speed; 1498 ecmd->speed = current_speed;
1509 ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 1499 ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1510 ecmd.advertising = ADVERTISED_TP; 1500 ecmd->advertising = ADVERTISED_TP;
1511 if (current_duplex == autoneg && current_speed_selection == 0) 1501
1512 ecmd.advertising |= ADVERTISED_Autoneg; 1502 if (current_duplex == autoneg && current_speed_selection == 0)
1513 else { 1503 ecmd->advertising |= ADVERTISED_Autoneg;
1514 ecmd.advertising |= 1504 else {
1515 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | 1505 ecmd->advertising |=
1516 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; 1506 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
1517 if (current_speed_selection == 10) 1507 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
1518 ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); 1508 if (current_speed_selection == 10)
1519 else if (current_speed_selection == 100) 1509 ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
1520 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); 1510 ADVERTISED_100baseT_Full);
1521 if (current_duplex == half) 1511 else if (current_speed_selection == 100)
1522 ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); 1512 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1523 else if (current_duplex == full) 1513 ADVERTISED_10baseT_Full);
1524 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); 1514 if (current_duplex == half)
1525 } 1515 ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
1526 ecmd.autoneg = AUTONEG_ENABLE; 1516 ADVERTISED_100baseT_Full);
1527 if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) 1517 else if (current_duplex == full)
1528 return -EFAULT; 1518 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1529 } 1519 ADVERTISED_100baseT_Half);
1530 break; 1520 }
1531 case ETHTOOL_SSET: 1521
1532 { 1522 ecmd->autoneg = AUTONEG_ENABLE;
1533 if (!capable(CAP_NET_ADMIN)) { 1523 return 0;
1534 return -EPERM; 1524}
1535 } 1525
1536 if (ecmd.autoneg == AUTONEG_ENABLE) { 1526static int e100_set_settings(struct net_device *dev,
1537 e100_set_duplex(dev, autoneg); 1527 struct ethtool_cmd *ecmd)
1538 e100_set_speed(dev, 0); 1528{
1539 } else { 1529 if (ecmd->autoneg == AUTONEG_ENABLE) {
1540 e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); 1530 e100_set_duplex(dev, autoneg);
1541 e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100); 1531 e100_set_speed(dev, 0);
1542 } 1532 } else {
1543 } 1533 e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
1544 break; 1534 e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
1545 case ETHTOOL_GDRVINFO:
1546 {
1547 struct ethtool_drvinfo info;
1548 memset((void *) &info, 0, sizeof (info));
1549 strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
1550 strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
1551 strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
1552 strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
1553 info.regdump_len = 0;
1554 info.eedump_len = 0;
1555 info.testinfo_len = 0;
1556 if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
1557 return -EFAULT;
1558 }
1559 break;
1560 case ETHTOOL_NWAY_RST:
1561 if (current_duplex == autoneg && current_speed_selection == 0)
1562 e100_negotiate(dev);
1563 break;
1564 default:
1565 return -EOPNOTSUPP;
1566 break;
1567 } 1535 }
1536
1537 return 0;
1538}
1539
1540static void e100_get_drvinfo(struct net_device *dev,
1541 struct ethtool_drvinfo *info)
1542{
1543 strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
1544 strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
1545 strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
1546 strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
1547}
1548
1549static int e100_nway_reset(struct net_device *dev)
1550{
1551 if (current_duplex == autoneg && current_speed_selection == 0)
1552 e100_negotiate(dev);
1568 return 0; 1553 return 0;
1569} 1554}
1570 1555
1556static struct ethtool_ops e100_ethtool_ops = {
1557 .get_settings = e100_get_settings,
1558 .set_settings = e100_set_settings,
1559 .get_drvinfo = e100_get_drvinfo,
1560 .nway_reset = e100_nway_reset,
1561 .get_link = ethtool_op_get_link,
1562};
1563
1571static int 1564static int
1572e100_set_config(struct net_device *dev, struct ifmap *map) 1565e100_set_config(struct net_device *dev, struct ifmap *map)
1573{ 1566{
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 7809838e6c4c..2a290cc397ad 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-
1549static int __init dgrs_init_module (void) 1549static int __init dgrs_init_module (void)
1550{ 1550{
1551 int i; 1551 int i;
1552 int eisacount = 0, pcicount = 0; 1552 int cardcount = 0;
1553 1553
1554 /* 1554 /*
1555 * Command line variable overrides 1555 * Command line variable overrides
@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void)
1591 * Find and configure all the cards 1591 * Find and configure all the cards
1592 */ 1592 */
1593#ifdef CONFIG_EISA 1593#ifdef CONFIG_EISA
1594 eisacount = eisa_driver_register(&dgrs_eisa_driver); 1594 cardcount = eisa_driver_register(&dgrs_eisa_driver);
1595 if (eisacount < 0) 1595 if (cardcount < 0)
1596 return eisacount; 1596 return cardcount;
1597#endif
1598#ifdef CONFIG_PCI
1599 pcicount = pci_register_driver(&dgrs_pci_driver);
1600 if (pcicount)
1601 return pcicount;
1602#endif 1597#endif
1598 cardcount = pci_register_driver(&dgrs_pci_driver);
1599 if (cardcount)
1600 return cardcount;
1603 return 0; 1601 return 0;
1604} 1602}
1605 1603
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 25227222e086..24996da4c1c4 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -60,7 +60,6 @@
60#include <linux/etherdevice.h> 60#include <linux/etherdevice.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/skbuff.h> 62#include <linux/skbuff.h>
63#include <linux/version.h>
64#include <linux/spinlock.h> 63#include <linux/spinlock.h>
65#include <linux/crc32.h> 64#include <linux/crc32.h>
66#include <linux/mii.h> 65#include <linux/mii.h>
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index eb169a8e8773..7a6aeae2c9fa 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
1478 1478
1479 if(pci_dma_mapping_error(rx->dma_addr)) { 1479 if(pci_dma_mapping_error(rx->dma_addr)) {
1480 dev_kfree_skb_any(rx->skb); 1480 dev_kfree_skb_any(rx->skb);
1481 rx->skb = 0; 1481 rx->skb = NULL;
1482 rx->dma_addr = 0; 1482 rx->dma_addr = 0;
1483 return -ENOMEM; 1483 return -ENOMEM;
1484 } 1484 }
@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
1764 if((err = e100_hw_init(nic))) 1764 if((err = e100_hw_init(nic)))
1765 goto err_clean_cbs; 1765 goto err_clean_cbs;
1766 e100_set_multicast_list(nic->netdev); 1766 e100_set_multicast_list(nic->netdev);
1767 e100_start_receiver(nic, 0); 1767 e100_start_receiver(nic, NULL);
1768 mod_timer(&nic->watchdog, jiffies); 1768 mod_timer(&nic->watchdog, jiffies);
1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, 1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
1770 nic->netdev->name, nic->netdev))) 1770 nic->netdev->name, nic->netdev)))
@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
1845 BMCR_LOOPBACK); 1845 BMCR_LOOPBACK);
1846 1846
1847 e100_start_receiver(nic, 0); 1847 e100_start_receiver(nic, NULL);
1848 1848
1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) { 1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
1850 err = -ENOMEM; 1850 err = -ENOMEM;
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 9342d5bc7bb4..f5d49a110654 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -37,6 +37,7 @@
37#include <linux/ethtool.h> 37#include <linux/ethtool.h>
38#include <linux/bitops.h> 38#include <linux/bitops.h>
39#include <linux/fs.h> 39#include <linux/fs.h>
40#include <linux/platform_device.h>
40 41
41#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 1105543b9d88..e7ec96c964a9 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -4,7 +4,6 @@
4#include <linux/mii.h> 4#include <linux/mii.h>
5#include <linux/netdevice.h> 5#include <linux/netdevice.h>
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/version.h>
8#include <linux/list.h> 7#include <linux/list.h>
9 8
10#include <linux/fs_enet_pd.h> 9#include <linux/fs_enet_pd.h>
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index a940b96433c7..e67b1d06611c 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -34,6 +34,7 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/immap_cpm2.h> 39#include <asm/immap_cpm2.h>
39#include <asm/mpc8260.h> 40#include <asm/mpc8260.h>
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 5ef4e845a387..2e8f44469699 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -34,6 +34,7 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/irq.h> 39#include <asm/irq.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index d8c6e9cadcf5..a3897fda71fa 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -34,6 +34,7 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/irq.h> 39#include <asm/irq.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index e8dab3983619..e3a329539f1c 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -90,7 +90,6 @@
90#include <asm/irq.h> 90#include <asm/irq.h>
91#include <asm/uaccess.h> 91#include <asm/uaccess.h>
92#include <linux/module.h> 92#include <linux/module.h>
93#include <linux/version.h>
94#include <linux/dma-mapping.h> 93#include <linux/dma-mapping.h>
95#include <linux/crc32.h> 94#include <linux/crc32.h>
96#include <linux/mii.h> 95#include <linux/mii.h>
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index c77ca6c0d04a..220084e53341 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -43,7 +43,6 @@
43#include <asm/irq.h> 43#include <asm/irq.h>
44#include <asm/uaccess.h> 44#include <asm/uaccess.h>
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/version.h>
47#include <linux/crc32.h> 46#include <linux/crc32.h>
48#include <linux/workqueue.h> 47#include <linux/workqueue.h>
49#include <linux/ethtool.h> 48#include <linux/ethtool.h>
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 68e3578e7613..5a2d810ce575 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -34,7 +34,6 @@
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/uaccess.h> 35#include <asm/uaccess.h>
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/version.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
39#include <asm/types.h> 38#include <asm/types.h>
40#include <asm/uaccess.h> 39#include <asm/uaccess.h>
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 5a74d3d3dbe1..7263395d78bb 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -32,7 +32,6 @@
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/version.h>
36#include <linux/platform_device.h> 35#include <linux/platform_device.h>
37#include <asm/ocp.h> 36#include <asm/ocp.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index b71fab6e34f4..e92c17f6931c 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -96,7 +96,6 @@
96 96
97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */ 97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */
98 98
99#include <linux/version.h>
100#include <linux/module.h> 99#include <linux/module.h>
101#include <linux/kernel.h> 100#include <linux/kernel.h>
102#include <linux/string.h> 101#include <linux/string.h>
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 94239f67f3a3..be191d80ef9c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -35,7 +35,6 @@
35 35
36#include <linux/config.h> 36#include <linux/config.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/version.h>
39#include <linux/types.h> 38#include <linux/types.h>
40#include <linux/errno.h> 39#include <linux/errno.h>
41#include <linux/ioport.h> 40#include <linux/ioport.h>
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index d86d8f055a6c..77eadf84cb2c 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -58,7 +58,6 @@
58 58
59#include <linux/config.h> 59#include <linux/config.h>
60#include <linux/module.h> 60#include <linux/module.h>
61#include <linux/version.h>
62#include <linux/types.h> 61#include <linux/types.h>
63#include <linux/errno.h> 62#include <linux/errno.h>
64#include <linux/ioport.h> 63#include <linux/ioport.h>
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index ce5761816a64..d8c99f038fa0 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -15,7 +15,6 @@
15 * and fixed access to Sonic Sys card which masquerades as a Farallon 15 * and fixed access to Sonic Sys card which masquerades as a Farallon
16 * by rayk@knightsmanor.org */ 16 * by rayk@knightsmanor.org */
17 17
18#include <linux/version.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/types.h> 20#include <linux/types.h>
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index bcfda5192da0..f769f9b626ea 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -1,7 +1,6 @@
1#ifndef __MV643XX_ETH_H__ 1#ifndef __MV643XX_ETH_H__
2#define __MV643XX_ETH_H__ 2#define __MV643XX_ETH_H__
3 3
4#include <linux/version.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index a3c3fc9c0d8a..f857ae94d261 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -110,7 +110,6 @@
110#include <linux/init.h> 110#include <linux/init.h>
111#include <linux/ip.h> /* for iph */ 111#include <linux/ip.h> /* for iph */
112#include <linux/in.h> /* for IPPROTO_... */ 112#include <linux/in.h> /* for IPPROTO_... */
113#include <linux/eeprom.h>
114#include <linux/compiler.h> 113#include <linux/compiler.h>
115#include <linux/prefetch.h> 114#include <linux/prefetch.h>
116#include <linux/ethtool.h> 115#include <linux/ethtool.h>
@@ -445,7 +444,6 @@ struct ns83820 {
445 444
446 u32 MEAR_cache; 445 u32 MEAR_cache;
447 u32 IMR_cache; 446 u32 IMR_cache;
448 struct eeprom ee;
449 447
450 unsigned linkstate; 448 unsigned linkstate;
451 449
@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
1558 unsigned i; 1556 unsigned i;
1559 for (i=0; i<3; i++) { 1557 for (i=0; i<3; i++) {
1560 u32 data; 1558 u32 data;
1561#if 0 /* I've left this in as an example of how to use eeprom.h */ 1559
1562 data = eeprom_readw(&dev->ee, 0xa + 2 - i);
1563#else
1564 /* Read from the perfect match memory: this is loaded by 1560 /* Read from the perfect match memory: this is loaded by
1565 * the chip from the EEPROM via the EELOAD self test. 1561 * the chip from the EEPROM via the EELOAD self test.
1566 */ 1562 */
1567 writel(i*2, dev->base + RFCR); 1563 writel(i*2, dev->base + RFCR);
1568 data = readl(dev->base + RFDR); 1564 data = readl(dev->base + RFDR);
1569#endif 1565
1570 *mac++ = data; 1566 *mac++ = data;
1571 *mac++ = data >> 8; 1567 *mac++ = data >> 8;
1572 } 1568 }
@@ -1851,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1851 spin_lock_init(&dev->misc_lock); 1847 spin_lock_init(&dev->misc_lock);
1852 dev->pci_dev = pci_dev; 1848 dev->pci_dev = pci_dev;
1853 1849
1854 dev->ee.cache = &dev->MEAR_cache;
1855 dev->ee.lock = &dev->misc_lock;
1856 SET_MODULE_OWNER(ndev); 1850 SET_MODULE_OWNER(ndev);
1857 SET_NETDEV_DEV(ndev, &pci_dev->dev); 1851 SET_NETDEV_DEV(ndev, &pci_dev->dev);
1858 1852
@@ -1887,9 +1881,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1887 1881
1888 dev->IMR_cache = 0; 1882 dev->IMR_cache = 0;
1889 1883
1890 setup_ee_mem_bitbanger(&dev->ee, dev->base + MEAR, 3, 2, 1, 0,
1891 0);
1892
1893 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ, 1884 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
1894 DRV_NAME, ndev); 1885 DRV_NAME, ndev);
1895 if (err) { 1886 if (err) {
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 0745dd9d01f3..e57df8dfe6b4 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -55,7 +55,6 @@
55#include <linux/timex.h> 55#include <linux/timex.h>
56#include <linux/sched.h> 56#include <linux/sched.h>
57#include <linux/ethtool.h> 57#include <linux/ethtool.h>
58#include <linux/version.h>
59#include <linux/workqueue.h> 58#include <linux/workqueue.h>
60#include <linux/if_vlan.h> 59#include <linux/if_vlan.h>
61 60
@@ -1532,7 +1531,7 @@ static int init_nic(struct s2io_nic *nic)
1532#define LINK_UP_DOWN_INTERRUPT 1 1531#define LINK_UP_DOWN_INTERRUPT 1
1533#define MAC_RMAC_ERR_TIMER 2 1532#define MAC_RMAC_ERR_TIMER 2
1534 1533
1535int s2io_link_fault_indication(nic_t *nic) 1534static int s2io_link_fault_indication(nic_t *nic)
1536{ 1535{
1537 if (nic->intr_type != INTA) 1536 if (nic->intr_type != INTA)
1538 return MAC_RMAC_ERR_TIMER; 1537 return MAC_RMAC_ERR_TIMER;
@@ -1864,7 +1863,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
1864 * 1863 *
1865 */ 1864 */
1866 1865
1867void fix_mac_address(nic_t * sp) 1866static void fix_mac_address(nic_t * sp)
1868{ 1867{
1869 XENA_dev_config_t __iomem *bar0 = sp->bar0; 1868 XENA_dev_config_t __iomem *bar0 = sp->bar0;
1870 u64 val64; 1869 u64 val64;
@@ -2160,7 +2159,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
2160 * SUCCESS on success or an appropriate -ve value on failure. 2159 * SUCCESS on success or an appropriate -ve value on failure.
2161 */ 2160 */
2162 2161
2163int fill_rx_buffers(struct s2io_nic *nic, int ring_no) 2162static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
2164{ 2163{
2165 struct net_device *dev = nic->dev; 2164 struct net_device *dev = nic->dev;
2166 struct sk_buff *skb; 2165 struct sk_buff *skb;
@@ -2831,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
2831 * SUCCESS on success and FAILURE on failure. 2830 * SUCCESS on success and FAILURE on failure.
2832 */ 2831 */
2833 2832
2834int wait_for_cmd_complete(nic_t * sp) 2833static int wait_for_cmd_complete(nic_t * sp)
2835{ 2834{
2836 XENA_dev_config_t __iomem *bar0 = sp->bar0; 2835 XENA_dev_config_t __iomem *bar0 = sp->bar0;
2837 int ret = FAILURE, cnt = 0; 2836 int ret = FAILURE, cnt = 0;
@@ -3077,7 +3076,7 @@ int s2io_set_swapper(nic_t * sp)
3077 return SUCCESS; 3076 return SUCCESS;
3078} 3077}
3079 3078
3080int wait_for_msix_trans(nic_t *nic, int i) 3079static int wait_for_msix_trans(nic_t *nic, int i)
3081{ 3080{
3082 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3081 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3083 u64 val64; 3082 u64 val64;
@@ -3116,7 +3115,7 @@ void restore_xmsi_data(nic_t *nic)
3116 } 3115 }
3117} 3116}
3118 3117
3119void store_xmsi_data(nic_t *nic) 3118static void store_xmsi_data(nic_t *nic)
3120{ 3119{
3121 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3120 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3122 u64 val64, addr, data; 3121 u64 val64, addr, data;
@@ -3288,7 +3287,7 @@ int s2io_enable_msi_x(nic_t *nic)
3288 * file on failure. 3287 * file on failure.
3289 */ 3288 */
3290 3289
3291int s2io_open(struct net_device *dev) 3290static int s2io_open(struct net_device *dev)
3292{ 3291{
3293 nic_t *sp = dev->priv; 3292 nic_t *sp = dev->priv;
3294 int err = 0; 3293 int err = 0;
@@ -3418,7 +3417,7 @@ hw_init_failed:
3418 * file on failure. 3417 * file on failure.
3419 */ 3418 */
3420 3419
3421int s2io_close(struct net_device *dev) 3420static int s2io_close(struct net_device *dev)
3422{ 3421{
3423 nic_t *sp = dev->priv; 3422 nic_t *sp = dev->priv;
3424 int i; 3423 int i;
@@ -3467,7 +3466,7 @@ int s2io_close(struct net_device *dev)
3467 * 0 on success & 1 on failure. 3466 * 0 on success & 1 on failure.
3468 */ 3467 */
3469 3468
3470int s2io_xmit(struct sk_buff *skb, struct net_device *dev) 3469static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
3471{ 3470{
3472 nic_t *sp = dev->priv; 3471 nic_t *sp = dev->priv;
3473 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; 3472 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -3913,7 +3912,7 @@ static void s2io_updt_stats(nic_t *sp)
3913 * pointer to the updated net_device_stats structure. 3912 * pointer to the updated net_device_stats structure.
3914 */ 3913 */
3915 3914
3916struct net_device_stats *s2io_get_stats(struct net_device *dev) 3915static struct net_device_stats *s2io_get_stats(struct net_device *dev)
3917{ 3916{
3918 nic_t *sp = dev->priv; 3917 nic_t *sp = dev->priv;
3919 mac_info_t *mac_control; 3918 mac_info_t *mac_control;
@@ -5106,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
5106 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; 5105 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
5107} 5106}
5108 5107
5109int s2io_ethtool_get_regs_len(struct net_device *dev) 5108static int s2io_ethtool_get_regs_len(struct net_device *dev)
5110{ 5109{
5111 return (XENA_REG_SPACE); 5110 return (XENA_REG_SPACE);
5112} 5111}
5113 5112
5114 5113
5115u32 s2io_ethtool_get_rx_csum(struct net_device * dev) 5114static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
5116{ 5115{
5117 nic_t *sp = dev->priv; 5116 nic_t *sp = dev->priv;
5118 5117
5119 return (sp->rx_csum); 5118 return (sp->rx_csum);
5120} 5119}
5121int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) 5120
5121static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5122{ 5122{
5123 nic_t *sp = dev->priv; 5123 nic_t *sp = dev->priv;
5124 5124
@@ -5129,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5129 5129
5130 return 0; 5130 return 0;
5131} 5131}
5132int s2io_get_eeprom_len(struct net_device *dev) 5132
5133static int s2io_get_eeprom_len(struct net_device *dev)
5133{ 5134{
5134 return (XENA_EEPROM_SPACE); 5135 return (XENA_EEPROM_SPACE);
5135} 5136}
5136 5137
5137int s2io_ethtool_self_test_count(struct net_device *dev) 5138static int s2io_ethtool_self_test_count(struct net_device *dev)
5138{ 5139{
5139 return (S2IO_TEST_LEN); 5140 return (S2IO_TEST_LEN);
5140} 5141}
5141void s2io_ethtool_get_strings(struct net_device *dev, 5142
5142 u32 stringset, u8 * data) 5143static void s2io_ethtool_get_strings(struct net_device *dev,
5144 u32 stringset, u8 * data)
5143{ 5145{
5144 switch (stringset) { 5146 switch (stringset) {
5145 case ETH_SS_TEST: 5147 case ETH_SS_TEST:
@@ -5155,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
5155 return (S2IO_STAT_LEN); 5157 return (S2IO_STAT_LEN);
5156} 5158}
5157 5159
5158int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) 5160static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
5159{ 5161{
5160 if (data) 5162 if (data)
5161 dev->features |= NETIF_F_IP_CSUM; 5163 dev->features |= NETIF_F_IP_CSUM;
@@ -5208,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
5208 * function always return EOPNOTSUPPORTED 5210 * function always return EOPNOTSUPPORTED
5209 */ 5211 */
5210 5212
5211int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 5213static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5212{ 5214{
5213 return -EOPNOTSUPP; 5215 return -EOPNOTSUPP;
5214} 5216}
@@ -5224,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5224 * file on failure. 5226 * file on failure.
5225 */ 5227 */
5226 5228
5227int s2io_change_mtu(struct net_device *dev, int new_mtu) 5229static int s2io_change_mtu(struct net_device *dev, int new_mtu)
5228{ 5230{
5229 nic_t *sp = dev->priv; 5231 nic_t *sp = dev->priv;
5230 5232
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
index 308440bd0e12..91b8d4f45904 100644
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ b/drivers/net/sk98lin/h/skdrv1st.h
@@ -39,9 +39,6 @@
39#ifndef __INC_SKDRV1ST_H 39#ifndef __INC_SKDRV1ST_H
40#define __INC_SKDRV1ST_H 40#define __INC_SKDRV1ST_H
41 41
42/* Check kernel version */
43#include <linux/version.h>
44
45typedef struct s_AC SK_AC; 42typedef struct s_AC SK_AC;
46 43
47/* Set card versions */ 44/* Set card versions */
diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
index 4c56b8d8221b..e5d6d95960c7 100644
--- a/drivers/net/sk_mca.c
+++ b/drivers/net/sk_mca.c
@@ -93,7 +93,6 @@ History:
93#include <linux/mca-legacy.h> 93#include <linux/mca-legacy.h>
94#include <linux/init.h> 94#include <linux/init.h>
95#include <linux/module.h> 95#include <linux/module.h>
96#include <linux/version.h>
97#include <linux/netdevice.h> 96#include <linux/netdevice.h>
98#include <linux/etherdevice.h> 97#include <linux/etherdevice.h>
99#include <linux/skbuff.h> 98#include <linux/skbuff.h>
diff --git a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h
index 7e7c99582746..d6fa1823dfa6 100644
--- a/drivers/net/sk_mca.h
+++ b/drivers/net/sk_mca.h
@@ -1,5 +1,3 @@
1#include <linux/version.h>
2
3#ifndef _SK_MCA_INCLUDE_ 1#ifndef _SK_MCA_INCLUDE_
4#define _SK_MCA_INCLUDE_ 2#define _SK_MCA_INCLUDE_
5 3
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 572f121b1f4e..596c93b12daa 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -37,12 +37,13 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/crc32.h> 38#include <linux/crc32.h>
39#include <linux/dma-mapping.h> 39#include <linux/dma-mapping.h>
40#include <linux/mii.h>
40#include <asm/irq.h> 41#include <asm/irq.h>
41 42
42#include "skge.h" 43#include "skge.h"
43 44
44#define DRV_NAME "skge" 45#define DRV_NAME "skge"
45#define DRV_VERSION "1.1" 46#define DRV_VERSION "1.2"
46#define PFX DRV_NAME " " 47#define PFX DRV_NAME " "
47 48
48#define DEFAULT_TX_RING_SIZE 128 49#define DEFAULT_TX_RING_SIZE 128
@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
88static int skge_up(struct net_device *dev); 89static int skge_up(struct net_device *dev);
89static int skge_down(struct net_device *dev); 90static int skge_down(struct net_device *dev);
90static void skge_tx_clean(struct skge_port *skge); 91static void skge_tx_clean(struct skge_port *skge);
91static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 92static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
92static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 93static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
93static void genesis_get_stats(struct skge_port *skge, u64 *data); 94static void genesis_get_stats(struct skge_port *skge, u64 *data);
94static void yukon_get_stats(struct skge_port *skge, u64 *data); 95static void yukon_get_stats(struct skge_port *skge, u64 *data);
95static void yukon_init(struct skge_hw *hw, int port); 96static void yukon_init(struct skge_hw *hw, int port);
@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
129 regs->len - B3_RI_WTO_R1); 130 regs->len - B3_RI_WTO_R1);
130} 131}
131 132
132/* Wake on Lan only supported on Yukon chps with rev 1 or above */ 133/* Wake on Lan only supported on Yukon chips with rev 1 or above */
133static int wol_supported(const struct skge_hw *hw) 134static int wol_supported(const struct skge_hw *hw)
134{ 135{
135 return !((hw->chip_id == CHIP_ID_GENESIS || 136 return !((hw->chip_id == CHIP_ID_GENESIS ||
@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
169 return 0; 170 return 0;
170} 171}
171 172
172/* Determine supported/adverised modes based on hardware. 173/* Determine supported/advertised modes based on hardware.
173 * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx 174 * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
174 */ 175 */
175static u32 skge_supported_modes(const struct skge_hw *hw) 176static u32 skge_supported_modes(const struct skge_hw *hw)
176{ 177{
@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
531 return 78215; /* or: 78.125 MHz */ 532 return 78215; /* or: 78.125 MHz */
532} 533}
533 534
534/* Chip hz to microseconds */ 535/* Chip HZ to microseconds */
535static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks) 536static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
536{ 537{
537 return (ticks * 1000) / hwkhz(hw); 538 return (ticks * 1000) / hwkhz(hw);
538} 539}
539 540
540/* Microseconds to chip hz */ 541/* Microseconds to chip HZ */
541static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec) 542static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
542{ 543{
543 return hwkhz(hw) * usec / 1000; 544 return hwkhz(hw) * usec / 1000;
@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_port *skge)
883 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); 884 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
884} 885}
885 886
886static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) 887static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
887{ 888{
888 int i; 889 int i;
889 u16 v;
890 890
891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); 891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
892 v = xm_read16(hw, port, XM_PHY_DATA); 892 xm_read16(hw, port, XM_PHY_DATA);
893 893
894 /* Need to wait for external PHY */ 894 /* Need to wait for external PHY */
895 for (i = 0; i < PHY_RETRIES; i++) { 895 for (i = 0; i < PHY_RETRIES; i++) {
896 udelay(1); 896 udelay(1);
897 if (xm_read16(hw, port, XM_MMU_CMD) 897 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
898 & XM_MMU_PHY_RDY)
899 goto ready; 898 goto ready;
900 } 899 }
901 900
902 printk(KERN_WARNING PFX "%s: phy read timed out\n", 901 return -ETIMEDOUT;
903 hw->dev[port]->name);
904 return 0;
905 ready: 902 ready:
906 v = xm_read16(hw, port, XM_PHY_DATA); 903 *val = xm_read16(hw, port, XM_PHY_DATA);
907 904
905 return 0;
906}
907
908static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
909{
910 u16 v = 0;
911 if (__xm_phy_read(hw, port, reg, &v))
912 printk(KERN_WARNING PFX "%s: phy read timed out\n",
913 hw->dev[port]->name);
908 return v; 914 return v;
909} 915}
910 916
911static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) 917static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
912{ 918{
913 int i; 919 int i;
914 920
@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
918 goto ready; 924 goto ready;
919 udelay(1); 925 udelay(1);
920 } 926 }
921 printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", 927 return -EIO;
922 hw->dev[port]->name);
923
924 928
925 ready: 929 ready:
926 xm_write16(hw, port, XM_PHY_DATA, val); 930 xm_write16(hw, port, XM_PHY_DATA, val);
927 for (i = 0; i < PHY_RETRIES; i++) { 931 return 0;
928 udelay(1);
929 if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
930 return;
931 }
932 printk(KERN_WARNING PFX "%s: phy write timed out\n",
933 hw->dev[port]->name);
934} 932}
935 933
936static void genesis_init(struct skge_hw *hw) 934static void genesis_init(struct skge_hw *hw)
@@ -1165,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1165 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); 1163 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
1166 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); 1164 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
1167 1165
1168 /* Use link status change interrrupt */ 1166 /* Use link status change interrupt */
1169 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1167 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1170 1168
1171 bcom_check_link(hw, port); 1169 bcom_check_link(hw, port);
@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1205 skge_write32(hw, B2_GP_IO, r); 1203 skge_write32(hw, B2_GP_IO, r);
1206 skge_read32(hw, B2_GP_IO); 1204 skge_read32(hw, B2_GP_IO);
1207 1205
1208 /* Enable GMII interfac */ 1206 /* Enable GMII interface */
1209 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); 1207 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1210 1208
1211 bcom_phy_init(skge, jumbo); 1209 bcom_phy_init(skge, jumbo);
@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1256 * that jumbo frames larger than 8192 bytes will be 1254 * that jumbo frames larger than 8192 bytes will be
1257 * truncated. Disabling all bad frame filtering causes 1255 * truncated. Disabling all bad frame filtering causes
1258 * the RX FIFO to operate in streaming mode, in which 1256 * the RX FIFO to operate in streaming mode, in which
1259 * case the XMAC will start transfering frames out of the 1257 * case the XMAC will start transferring frames out of the
1260 * RX FIFO as soon as the FIFO threshold is reached. 1258 * RX FIFO as soon as the FIFO threshold is reached.
1261 */ 1259 */
1262 xm_write32(hw, port, XM_MODE, XM_DEF_MODE); 1260 xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge)
1323 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); 1321 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
1324 1322
1325 /* 1323 /*
1326 * If the transfer stucks at the MAC the STOP command will not 1324 * If the transfer sticks at the MAC the STOP command will not
1327 * terminate if we don't flush the XMAC's transmit FIFO ! 1325 * terminate if we don't flush the XMAC's transmit FIFO !
1328 */ 1326 */
1329 xm_write32(hw, port, XM_MODE, 1327 xm_write32(hw, port, XM_MODE,
@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port)
1400 } 1398 }
1401} 1399}
1402 1400
1403static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1404{
1405 int i;
1406
1407 gma_write16(hw, port, GM_SMI_DATA, val);
1408 gma_write16(hw, port, GM_SMI_CTRL,
1409 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1410 for (i = 0; i < PHY_RETRIES; i++) {
1411 udelay(1);
1412
1413 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1414 break;
1415 }
1416}
1417
1418static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1419{
1420 int i;
1421
1422 gma_write16(hw, port, GM_SMI_CTRL,
1423 GM_SMI_CT_PHY_AD(hw->phy_addr)
1424 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1425
1426 for (i = 0; i < PHY_RETRIES; i++) {
1427 udelay(1);
1428 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1429 goto ready;
1430 }
1431
1432 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1433 hw->dev[port]->name);
1434 return 0;
1435 ready:
1436 return gma_read16(hw, port, GM_SMI_DATA);
1437}
1438
1439static void genesis_link_up(struct skge_port *skge) 1401static void genesis_link_up(struct skge_port *skge)
1440{ 1402{
1441 struct skge_hw *hw = skge->hw; 1403 struct skge_hw *hw = skge->hw;
@@ -1549,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge)
1549 1511
1550} 1512}
1551 1513
1552/* Marvell Phy Initailization */ 1514static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1515{
1516 int i;
1517
1518 gma_write16(hw, port, GM_SMI_DATA, val);
1519 gma_write16(hw, port, GM_SMI_CTRL,
1520 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1521 for (i = 0; i < PHY_RETRIES; i++) {
1522 udelay(1);
1523
1524 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1525 return 0;
1526 }
1527
1528 printk(KERN_WARNING PFX "%s: phy write timeout\n",
1529 hw->dev[port]->name);
1530 return -EIO;
1531}
1532
1533static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
1534{
1535 int i;
1536
1537 gma_write16(hw, port, GM_SMI_CTRL,
1538 GM_SMI_CT_PHY_AD(hw->phy_addr)
1539 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1540
1541 for (i = 0; i < PHY_RETRIES; i++) {
1542 udelay(1);
1543 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1544 goto ready;
1545 }
1546
1547 return -ETIMEDOUT;
1548 ready:
1549 *val = gma_read16(hw, port, GM_SMI_DATA);
1550 return 0;
1551}
1552
1553static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1554{
1555 u16 v = 0;
1556 if (__gm_phy_read(hw, port, reg, &v))
1557 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1558 hw->dev[port]->name);
1559 return v;
1560}
1561
1562/* Marvell Phy Initialization */
1553static void yukon_init(struct skge_hw *hw, int port) 1563static void yukon_init(struct skge_hw *hw, int port)
1554{ 1564{
1555 struct skge_port *skge = netdev_priv(hw->dev[port]); 1565 struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1794,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
1794 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); 1804 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
1795} 1805}
1796 1806
1807/* Go into power down mode */
1808static void yukon_suspend(struct skge_hw *hw, int port)
1809{
1810 u16 ctrl;
1811
1812 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
1813 ctrl |= PHY_M_PC_POL_R_DIS;
1814 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
1815
1816 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1817 ctrl |= PHY_CT_RESET;
1818 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1819
1820 /* switch IEEE compatible power down mode on */
1821 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1822 ctrl |= PHY_CT_PDOWN;
1823 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1824}
1825
1797static void yukon_stop(struct skge_port *skge) 1826static void yukon_stop(struct skge_port *skge)
1798{ 1827{
1799 struct skge_hw *hw = skge->hw; 1828 struct skge_hw *hw = skge->hw;
@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge)
1807 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); 1836 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
1808 gma_read16(hw, port, GM_GP_CTRL); 1837 gma_read16(hw, port, GM_GP_CTRL);
1809 1838
1810 if (hw->chip_id == CHIP_ID_YUKON_LITE && 1839 yukon_suspend(hw, port);
1811 hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
1812 u32 io = skge_read32(hw, B2_GP_IO);
1813
1814 io |= GP_DIR_9 | GP_IO_9;
1815 skge_write32(hw, B2_GP_IO, io);
1816 skge_read32(hw, B2_GP_IO);
1817 }
1818 1840
1819 /* set GPHY Control reset */ 1841 /* set GPHY Control reset */
1820 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); 1842 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge)
1997 /* XXX restart autonegotiation? */ 2019 /* XXX restart autonegotiation? */
1998} 2020}
1999 2021
2022/* Basic MII support */
2023static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2024{
2025 struct mii_ioctl_data *data = if_mii(ifr);
2026 struct skge_port *skge = netdev_priv(dev);
2027 struct skge_hw *hw = skge->hw;
2028 int err = -EOPNOTSUPP;
2029
2030 if (!netif_running(dev))
2031 return -ENODEV; /* Phy still in reset */
2032
2033 switch(cmd) {
2034 case SIOCGMIIPHY:
2035 data->phy_id = hw->phy_addr;
2036
2037 /* fallthru */
2038 case SIOCGMIIREG: {
2039 u16 val = 0;
2040 spin_lock_bh(&hw->phy_lock);
2041 if (hw->chip_id == CHIP_ID_GENESIS)
2042 err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2043 else
2044 err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2045 spin_unlock_bh(&hw->phy_lock);
2046 data->val_out = val;
2047 break;
2048 }
2049
2050 case SIOCSMIIREG:
2051 if (!capable(CAP_NET_ADMIN))
2052 return -EPERM;
2053
2054 spin_lock_bh(&hw->phy_lock);
2055 if (hw->chip_id == CHIP_ID_GENESIS)
2056 err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2057 data->val_in);
2058 else
2059 err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2060 data->val_in);
2061 spin_unlock_bh(&hw->phy_lock);
2062 break;
2063 }
2064 return err;
2065}
2066
2000static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) 2067static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
2001{ 2068{
2002 u32 end; 2069 u32 end;
@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev)
2089 hw->intr_mask |= portirqmask[port]; 2156 hw->intr_mask |= portirqmask[port];
2090 skge_write32(hw, B0_IMSK, hw->intr_mask); 2157 skge_write32(hw, B0_IMSK, hw->intr_mask);
2091 2158
2092 /* Initialze MAC */ 2159 /* Initialize MAC */
2093 spin_lock_bh(&hw->phy_lock); 2160 spin_lock_bh(&hw->phy_lock);
2094 if (hw->chip_id == CHIP_ID_GENESIS) 2161 if (hw->chip_id == CHIP_ID_GENESIS)
2095 genesis_mac_init(hw, port); 2162 genesis_mac_init(hw, port);
@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev)
2409 reg = gma_read16(hw, port, GM_RX_CTRL); 2476 reg = gma_read16(hw, port, GM_RX_CTRL);
2410 reg |= GM_RXCR_UCF_ENA; 2477 reg |= GM_RXCR_UCF_ENA;
2411 2478
2412 if (dev->flags & IFF_PROMISC) /* promiscious */ 2479 if (dev->flags & IFF_PROMISC) /* promiscuous */
2413 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); 2480 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
2414 else if (dev->flags & IFF_ALLMULTI) /* all multicast */ 2481 else if (dev->flags & IFF_ALLMULTI) /* all multicast */
2415 memset(filter, 0xff, sizeof(filter)); 2482 memset(filter, 0xff, sizeof(filter));
@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget)
2560 unsigned int to_do = min(dev->quota, *budget); 2627 unsigned int to_do = min(dev->quota, *budget);
2561 unsigned int work_done = 0; 2628 unsigned int work_done = 0;
2562 2629
2563 for (e = ring->to_clean; work_done < to_do; e = e->next) { 2630 for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
2564 struct skge_rx_desc *rd = e->desc; 2631 struct skge_rx_desc *rd = e->desc;
2565 struct sk_buff *skb; 2632 struct sk_buff *skb;
2566 u32 control; 2633 u32 control;
@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget)
2593 if (work_done >= to_do) 2660 if (work_done >= to_do)
2594 return 1; /* not done */ 2661 return 1; /* not done */
2595 2662
2596 local_irq_disable(); 2663 netif_rx_complete(dev);
2597 __netif_rx_complete(dev);
2598 hw->intr_mask |= portirqmask[skge->port]; 2664 hw->intr_mask |= portirqmask[skge->port];
2599 skge_write32(hw, B0_IMSK, hw->intr_mask); 2665 skge_write32(hw, B0_IMSK, hw->intr_mask);
2600 local_irq_enable(); 2666 skge_read32(hw, B0_IMSK);
2667
2601 return 0; 2668 return 0;
2602} 2669}
2603 2670
@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev)
2609 struct skge_element *e; 2676 struct skge_element *e;
2610 2677
2611 spin_lock(&skge->tx_lock); 2678 spin_lock(&skge->tx_lock);
2612 for (e = ring->to_clean; e != ring->to_use; e = e->next) { 2679 for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
2613 struct skge_tx_desc *td = e->desc; 2680 struct skge_tx_desc *td = e->desc;
2614 u32 control; 2681 u32 control;
2615 2682
@@ -2732,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw)
2732} 2799}
2733 2800
2734/* 2801/*
2735 * Interrrupt from PHY are handled in tasklet (soft irq) 2802 * Interrupt from PHY are handled in tasklet (soft irq)
2736 * because accessing phy registers requires spin wait which might 2803 * because accessing phy registers requires spin wait which might
2737 * cause excess interrupt latency. 2804 * cause excess interrupt latency.
2738 */ 2805 */
@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data)
2762 local_irq_enable(); 2829 local_irq_enable();
2763} 2830}
2764 2831
2832static inline void skge_wakeup(struct net_device *dev)
2833{
2834 struct skge_port *skge = netdev_priv(dev);
2835
2836 prefetch(skge->rx_ring.to_clean);
2837 netif_rx_schedule(dev);
2838}
2839
2765static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) 2840static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2766{ 2841{
2767 struct skge_hw *hw = dev_id; 2842 struct skge_hw *hw = dev_id;
@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2773 status &= hw->intr_mask; 2848 status &= hw->intr_mask;
2774 if (status & IS_R1_F) { 2849 if (status & IS_R1_F) {
2775 hw->intr_mask &= ~IS_R1_F; 2850 hw->intr_mask &= ~IS_R1_F;
2776 netif_rx_schedule(hw->dev[0]); 2851 skge_wakeup(hw->dev[0]);
2777 } 2852 }
2778 2853
2779 if (status & IS_R2_F) { 2854 if (status & IS_R2_F) {
2780 hw->intr_mask &= ~IS_R2_F; 2855 hw->intr_mask &= ~IS_R2_F;
2781 netif_rx_schedule(hw->dev[1]); 2856 skge_wakeup(hw->dev[1]);
2782 } 2857 }
2783 2858
2784 if (status & IS_XA1_F) 2859 if (status & IS_XA1_F)
@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw)
2893 */ 2968 */
2894static int skge_reset(struct skge_hw *hw) 2969static int skge_reset(struct skge_hw *hw)
2895{ 2970{
2971 u32 reg;
2896 u16 ctst; 2972 u16 ctst;
2897 u8 t8, mac_cfg, pmd_type, phy_type; 2973 u8 t8, mac_cfg, pmd_type, phy_type;
2898 int i; 2974 int i;
@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw)
2971 /* switch power to VCC (WA for VAUX problem) */ 3047 /* switch power to VCC (WA for VAUX problem) */
2972 skge_write8(hw, B0_POWER_CTRL, 3048 skge_write8(hw, B0_POWER_CTRL,
2973 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); 3049 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
3050
2974 /* avoid boards with stuck Hardware error bits */ 3051 /* avoid boards with stuck Hardware error bits */
2975 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && 3052 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
2976 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { 3053 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw)
2978 hw->intr_mask &= ~IS_HW_ERR; 3055 hw->intr_mask &= ~IS_HW_ERR;
2979 } 3056 }
2980 3057
3058 /* Clear PHY COMA */
3059 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
3060 pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
3061 reg &= ~PCI_PHY_COMA;
3062 pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
3063 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
3064
3065
2981 for (i = 0; i < hw->ports; i++) { 3066 for (i = 0; i < hw->ports; i++) {
2982 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); 3067 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
2983 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); 3068 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
@@ -3048,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
3048 SET_NETDEV_DEV(dev, &hw->pdev->dev); 3133 SET_NETDEV_DEV(dev, &hw->pdev->dev);
3049 dev->open = skge_up; 3134 dev->open = skge_up;
3050 dev->stop = skge_down; 3135 dev->stop = skge_down;
3136 dev->do_ioctl = skge_ioctl;
3051 dev->hard_start_xmit = skge_xmit_frame; 3137 dev->hard_start_xmit = skge_xmit_frame;
3052 dev->get_stats = skge_get_stats; 3138 dev->get_stats = skge_get_stats;
3053 if (hw->chip_id == CHIP_ID_GENESIS) 3139 if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3147 } 3233 }
3148 3234
3149#ifdef __BIG_ENDIAN 3235#ifdef __BIG_ENDIAN
3150 /* byte swap decriptors in hardware */ 3236 /* byte swap descriptors in hardware */
3151 { 3237 {
3152 u32 reg; 3238 u32 reg;
3153 3239
@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3158#endif 3244#endif
3159 3245
3160 err = -ENOMEM; 3246 err = -ENOMEM;
3161 hw = kmalloc(sizeof(*hw), GFP_KERNEL); 3247 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
3162 if (!hw) { 3248 if (!hw) {
3163 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", 3249 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
3164 pci_name(pdev)); 3250 pci_name(pdev));
3165 goto err_out_free_regions; 3251 goto err_out_free_regions;
3166 } 3252 }
3167 3253
3168 memset(hw, 0, sizeof(*hw));
3169 hw->pdev = pdev; 3254 hw->pdev = pdev;
3170 spin_lock_init(&hw->phy_lock); 3255 spin_lock_init(&hw->phy_lock);
3171 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); 3256 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3188 if (err) 3273 if (err)
3189 goto err_out_free_irq; 3274 goto err_out_free_irq;
3190 3275
3191 printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", 3276 printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
3192 pci_resource_start(pdev, 0), pdev->irq, 3277 pci_resource_start(pdev, 0), pdev->irq,
3193 skge_board_name(hw), hw->chip_rev); 3278 skge_board_name(hw), hw->chip_rev);
3194 3279
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 72c175b87a5a..ee123c15f545 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -6,6 +6,8 @@
6 6
7/* PCI config registers */ 7/* PCI config registers */
8#define PCI_DEV_REG1 0x40 8#define PCI_DEV_REG1 0x40
9#define PCI_PHY_COMA 0x8000000
10#define PCI_VIO 0x2000000
9#define PCI_DEV_REG2 0x44 11#define PCI_DEV_REG2 0x44
10#define PCI_REV_DESC 0x4 12#define PCI_REV_DESC 0x4
11 13
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c796f41b4a52..0d765f1733b5 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -2290,7 +2290,6 @@ spider_net_remove(struct pci_dev *pdev)
2290} 2290}
2291 2291
2292static struct pci_driver spider_net_driver = { 2292static struct pci_driver spider_net_driver = {
2293 .owner = THIS_MODULE,
2294 .name = spider_net_driver_name, 2293 .name = spider_net_driver_name,
2295 .id_table = spider_net_pci_tbl, 2294 .id_table = spider_net_pci_tbl,
2296 .probe = spider_net_probe, 2295 .probe = spider_net_probe,
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 38b2b0a3ce96..d167deda9a53 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -147,7 +147,6 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when
147#define DRV_RELDATE "October 3, 2005" 147#define DRV_RELDATE "October 3, 2005"
148 148
149#include <linux/config.h> 149#include <linux/config.h>
150#include <linux/version.h>
151#include <linux/module.h> 150#include <linux/module.h>
152#include <linux/kernel.h> 151#include <linux/kernel.h>
153#include <linux/pci.h> 152#include <linux/pci.h>
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index a368d08e7d19..82c6b757d306 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -61,7 +61,6 @@
61#include <linux/timer.h> 61#include <linux/timer.h>
62#include <linux/slab.h> 62#include <linux/slab.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/version.h>
65#include <linux/string.h> 64#include <linux/string.h>
66#include <linux/wait.h> 65#include <linux/wait.h>
67#include <asm/io.h> 66#include <asm/io.h>
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 6afc6e5dee9b..340ab4ee4b67 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4535,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
4535 StatusRid status_rid; 4535 StatusRid status_rid;
4536 int i; 4536 int i;
4537 4537
4538 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4538 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4539 return -ENOMEM; 4539 return -ENOMEM;
4540 memset(file->private_data, 0, sizeof(struct proc_data));
4541 data = (struct proc_data *)file->private_data; 4540 data = (struct proc_data *)file->private_data;
4542 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4541 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4543 kfree (file->private_data); 4542 kfree (file->private_data);
@@ -4615,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode,
4615 int i, j; 4614 int i, j;
4616 u32 *vals = stats.vals; 4615 u32 *vals = stats.vals;
4617 4616
4618 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4617 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4619 return -ENOMEM; 4618 return -ENOMEM;
4620 memset(file->private_data, 0, sizeof(struct proc_data));
4621 data = (struct proc_data *)file->private_data; 4619 data = (struct proc_data *)file->private_data;
4622 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) { 4620 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4623 kfree (file->private_data); 4621 kfree (file->private_data);
@@ -4881,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
4881 struct airo_info *ai = dev->priv; 4879 struct airo_info *ai = dev->priv;
4882 int i; 4880 int i;
4883 4881
4884 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4882 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4885 return -ENOMEM; 4883 return -ENOMEM;
4886 memset(file->private_data, 0, sizeof(struct proc_data));
4887 data = (struct proc_data *)file->private_data; 4884 data = (struct proc_data *)file->private_data;
4888 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4885 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4889 kfree (file->private_data); 4886 kfree (file->private_data);
4890 return -ENOMEM; 4887 return -ENOMEM;
4891 } 4888 }
4892 if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4889 if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
4893 kfree (data->rbuffer); 4890 kfree (data->rbuffer);
4894 kfree (file->private_data); 4891 kfree (file->private_data);
4895 return -ENOMEM; 4892 return -ENOMEM;
4896 } 4893 }
4897 memset( data->wbuffer, 0, 2048 );
4898 data->maxwritelen = 2048; 4894 data->maxwritelen = 2048;
4899 data->on_close = proc_config_on_close; 4895 data->on_close = proc_config_on_close;
4900 4896
@@ -5155,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
5155 int j=0; 5151 int j=0;
5156 int rc; 5152 int rc;
5157 5153
5158 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5154 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5159 return -ENOMEM; 5155 return -ENOMEM;
5160 memset(file->private_data, 0, sizeof(struct proc_data));
5161 memset(&wkr, 0, sizeof(wkr)); 5156 memset(&wkr, 0, sizeof(wkr));
5162 data = (struct proc_data *)file->private_data; 5157 data = (struct proc_data *)file->private_data;
5163 if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) { 5158 if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5164 kfree (file->private_data); 5159 kfree (file->private_data);
5165 return -ENOMEM; 5160 return -ENOMEM;
5166 } 5161 }
5167 memset(data->rbuffer, 0, 180);
5168 data->writelen = 0; 5162 data->writelen = 0;
5169 data->maxwritelen = 80; 5163 data->maxwritelen = 80;
5170 if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) { 5164 if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5171 kfree (data->rbuffer); 5165 kfree (data->rbuffer);
5172 kfree (file->private_data); 5166 kfree (file->private_data);
5173 return -ENOMEM; 5167 return -ENOMEM;
5174 } 5168 }
5175 memset( data->wbuffer, 0, 80 );
5176 data->on_close = proc_wepkey_on_close; 5169 data->on_close = proc_wepkey_on_close;
5177 5170
5178 ptr = data->rbuffer; 5171 ptr = data->rbuffer;
@@ -5203,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5203 char *ptr; 5196 char *ptr;
5204 SsidRid SSID_rid; 5197 SsidRid SSID_rid;
5205 5198
5206 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5199 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5207 return -ENOMEM; 5200 return -ENOMEM;
5208 memset(file->private_data, 0, sizeof(struct proc_data));
5209 data = (struct proc_data *)file->private_data; 5201 data = (struct proc_data *)file->private_data;
5210 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5202 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5211 kfree (file->private_data); 5203 kfree (file->private_data);
@@ -5213,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5213 } 5205 }
5214 data->writelen = 0; 5206 data->writelen = 0;
5215 data->maxwritelen = 33*3; 5207 data->maxwritelen = 33*3;
5216 if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) { 5208 if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) {
5217 kfree (data->rbuffer); 5209 kfree (data->rbuffer);
5218 kfree (file->private_data); 5210 kfree (file->private_data);
5219 return -ENOMEM; 5211 return -ENOMEM;
5220 } 5212 }
5221 memset( data->wbuffer, 0, 33*3 );
5222 data->on_close = proc_SSID_on_close; 5213 data->on_close = proc_SSID_on_close;
5223 5214
5224 readSsidRid(ai, &SSID_rid); 5215 readSsidRid(ai, &SSID_rid);
@@ -5247,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5247 char *ptr; 5238 char *ptr;
5248 APListRid APList_rid; 5239 APListRid APList_rid;
5249 5240
5250 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5241 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5251 return -ENOMEM; 5242 return -ENOMEM;
5252 memset(file->private_data, 0, sizeof(struct proc_data));
5253 data = (struct proc_data *)file->private_data; 5243 data = (struct proc_data *)file->private_data;
5254 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5244 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5255 kfree (file->private_data); 5245 kfree (file->private_data);
@@ -5257,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5257 } 5247 }
5258 data->writelen = 0; 5248 data->writelen = 0;
5259 data->maxwritelen = 4*6*3; 5249 data->maxwritelen = 4*6*3;
5260 if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) { 5250 if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5261 kfree (data->rbuffer); 5251 kfree (data->rbuffer);
5262 kfree (file->private_data); 5252 kfree (file->private_data);
5263 return -ENOMEM; 5253 return -ENOMEM;
5264 } 5254 }
5265 memset( data->wbuffer, 0, data->maxwritelen );
5266 data->on_close = proc_APList_on_close; 5255 data->on_close = proc_APList_on_close;
5267 5256
5268 readAPListRid(ai, &APList_rid); 5257 readAPListRid(ai, &APList_rid);
@@ -5297,9 +5286,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5297 /* If doLoseSync is not 1, we won't do a Lose Sync */ 5286 /* If doLoseSync is not 1, we won't do a Lose Sync */
5298 int doLoseSync = -1; 5287 int doLoseSync = -1;
5299 5288
5300 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5289 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5301 return -ENOMEM; 5290 return -ENOMEM;
5302 memset(file->private_data, 0, sizeof(struct proc_data));
5303 data = (struct proc_data *)file->private_data; 5291 data = (struct proc_data *)file->private_data;
5304 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) { 5292 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5305 kfree (file->private_data); 5293 kfree (file->private_data);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 96ed8da8661d..e328547599dc 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -170,12 +170,11 @@ static dev_link_t *airo_attach(void)
170 DEBUG(0, "airo_attach()\n"); 170 DEBUG(0, "airo_attach()\n");
171 171
172 /* Initialize the dev_link_t structure */ 172 /* Initialize the dev_link_t structure */
173 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 173 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
174 if (!link) { 174 if (!link) {
175 printk(KERN_ERR "airo_cs: no memory for new device\n"); 175 printk(KERN_ERR "airo_cs: no memory for new device\n");
176 return NULL; 176 return NULL;
177 } 177 }
178 memset(link, 0, sizeof(struct dev_link_t));
179 178
180 /* Interrupt setup */ 179 /* Interrupt setup */
181 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 180 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -194,13 +193,12 @@ static dev_link_t *airo_attach(void)
194 link->conf.IntType = INT_MEMORY_AND_IO; 193 link->conf.IntType = INT_MEMORY_AND_IO;
195 194
196 /* Allocate space for private device-specific data */ 195 /* Allocate space for private device-specific data */
197 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 196 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
198 if (!local) { 197 if (!local) {
199 printk(KERN_ERR "airo_cs: no memory for new device\n"); 198 printk(KERN_ERR "airo_cs: no memory for new device\n");
200 kfree (link); 199 kfree (link);
201 return NULL; 200 return NULL;
202 } 201 }
203 memset(local, 0, sizeof(local_info_t));
204 link->priv = local; 202 link->priv = local;
205 203
206 /* Register with Card Services */ 204 /* Register with Card Services */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 1fbe027d26b6..a3e23527fe7f 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_device *dev,
2217 int k,i,j; 2217 int k,i,j;
2218 2218
2219 dwrq->length = sizeof(struct iw_range); 2219 dwrq->length = sizeof(struct iw_range);
2220 memset(range, 0, sizeof(range)); 2220 memset(range, 0, sizeof(struct iw_range));
2221 range->min_nwid = 0x0000; 2221 range->min_nwid = 0x0000;
2222 range->max_nwid = 0x0000; 2222 range->max_nwid = 0x0000;
2223 range->num_channels = 0; 2223 range->num_channels = 0;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 195cb36619e8..1bd13146c644 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -180,12 +180,11 @@ static dev_link_t *atmel_attach(void)
180 DEBUG(0, "atmel_attach()\n"); 180 DEBUG(0, "atmel_attach()\n");
181 181
182 /* Initialize the dev_link_t structure */ 182 /* Initialize the dev_link_t structure */
183 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 183 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
184 if (!link) { 184 if (!link) {
185 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 185 printk(KERN_ERR "atmel_cs: no memory for new device\n");
186 return NULL; 186 return NULL;
187 } 187 }
188 memset(link, 0, sizeof(struct dev_link_t));
189 188
190 /* Interrupt setup */ 189 /* Interrupt setup */
191 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 190 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -204,13 +203,12 @@ static dev_link_t *atmel_attach(void)
204 link->conf.IntType = INT_MEMORY_AND_IO; 203 link->conf.IntType = INT_MEMORY_AND_IO;
205 204
206 /* Allocate space for private device-specific data */ 205 /* Allocate space for private device-specific data */
207 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 206 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
208 if (!local) { 207 if (!local) {
209 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 208 printk(KERN_ERR "atmel_cs: no memory for new device\n");
210 kfree (link); 209 kfree (link);
211 return NULL; 210 return NULL;
212 } 211 }
213 memset(local, 0, sizeof(local_info_t));
214 link->priv = local; 212 link->priv = local;
215 213
216 /* Register with Card Services */ 214 /* Register with Card Services */
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
index 6a96cd9f2685..3d2ea61033be 100644
--- a/drivers/net/wireless/hostap/hostap.c
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -13,7 +13,6 @@
13 */ 13 */
14 14
15#include <linux/config.h> 15#include <linux/config.h>
16#include <linux/version.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 59fc15572395..abfae7fedebc 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -31,7 +31,6 @@
31 31
32 32
33#include <linux/config.h> 33#include <linux/config.h>
34#include <linux/version.h>
35 34
36#include <asm/delay.h> 35#include <asm/delay.h>
37#include <asm/uaccess.h> 36#include <asm/uaccess.h>
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index da0c80fb941c..2e85bdced2dd 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -5,7 +5,6 @@
5 * Andy Warner <andyw@pobox.com> */ 5 * Andy Warner <andyw@pobox.com> */
6 6
7#include <linux/config.h> 7#include <linux/config.h>
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/if.h> 10#include <linux/if.h>
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 78d67b408b2f..94fe2449f099 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -8,7 +8,6 @@
8 8
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/if.h> 13#include <linux/if.h>
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index ad7f8cd76db9..a2e6214169e9 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,17 +167,16 @@ that only one external action is invoked at a time.
167 167
168#include "ipw2100.h" 168#include "ipw2100.h"
169 169
170#define IPW2100_VERSION "1.1.0" 170#define IPW2100_VERSION "1.1.3"
171 171
172#define DRV_NAME "ipw2100" 172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION 173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
176
177 176
178/* Debugging stuff */ 177/* Debugging stuff */
179#ifdef CONFIG_IPW_DEBUG 178#ifdef CONFIG_IPW_DEBUG
180#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */ 179#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
181#endif 180#endif
182 181
183MODULE_DESCRIPTION(DRV_DESCRIPTION); 182MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -220,18 +219,18 @@ do { \
220} while (0) 219} while (0)
221#else 220#else
222#define IPW_DEBUG(level, message...) do {} while (0) 221#define IPW_DEBUG(level, message...) do {} while (0)
223#endif /* CONFIG_IPW_DEBUG */ 222#endif /* CONFIG_IPW_DEBUG */
224 223
225#ifdef CONFIG_IPW_DEBUG 224#ifdef CONFIG_IPW_DEBUG
226static const char *command_types[] = { 225static const char *command_types[] = {
227 "undefined", 226 "undefined",
228 "unused", /* HOST_ATTENTION */ 227 "unused", /* HOST_ATTENTION */
229 "HOST_COMPLETE", 228 "HOST_COMPLETE",
230 "unused", /* SLEEP */ 229 "unused", /* SLEEP */
231 "unused", /* HOST_POWER_DOWN */ 230 "unused", /* HOST_POWER_DOWN */
232 "unused", 231 "unused",
233 "SYSTEM_CONFIG", 232 "SYSTEM_CONFIG",
234 "unused", /* SET_IMR */ 233 "unused", /* SET_IMR */
235 "SSID", 234 "SSID",
236 "MANDATORY_BSSID", 235 "MANDATORY_BSSID",
237 "AUTHENTICATION_TYPE", 236 "AUTHENTICATION_TYPE",
@@ -277,17 +276,16 @@ static const char *command_types[] = {
277 "GROUP_ORDINALS", 276 "GROUP_ORDINALS",
278 "SHORT_RETRY_LIMIT", 277 "SHORT_RETRY_LIMIT",
279 "LONG_RETRY_LIMIT", 278 "LONG_RETRY_LIMIT",
280 "unused", /* SAVE_CALIBRATION */ 279 "unused", /* SAVE_CALIBRATION */
281 "unused", /* RESTORE_CALIBRATION */ 280 "unused", /* RESTORE_CALIBRATION */
282 "undefined", 281 "undefined",
283 "undefined", 282 "undefined",
284 "undefined", 283 "undefined",
285 "HOST_PRE_POWER_DOWN", 284 "HOST_PRE_POWER_DOWN",
286 "unused", /* HOST_INTERRUPT_COALESCING */ 285 "unused", /* HOST_INTERRUPT_COALESCING */
287 "undefined", 286 "undefined",
288 "CARD_DISABLE_PHY_OFF", 287 "CARD_DISABLE_PHY_OFF",
289 "MSDU_TX_RATES" 288 "MSDU_TX_RATES" "undefined",
290 "undefined",
291 "undefined", 289 "undefined",
292 "SET_STATION_STAT_BITS", 290 "SET_STATION_STAT_BITS",
293 "CLEAR_STATIONS_STAT_BITS", 291 "CLEAR_STATIONS_STAT_BITS",
@@ -298,7 +296,6 @@ static const char *command_types[] = {
298}; 296};
299#endif 297#endif
300 298
301
302/* Pre-decl until we get the code solid and then we can clean it up */ 299/* Pre-decl until we get the code solid and then we can clean it up */
303static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); 300static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
304static void ipw2100_tx_send_data(struct ipw2100_priv *priv); 301static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -321,11 +318,10 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
321static int ipw2100_ucode_download(struct ipw2100_priv *priv, 318static int ipw2100_ucode_download(struct ipw2100_priv *priv,
322 struct ipw2100_fw *fw); 319 struct ipw2100_fw *fw);
323static void ipw2100_wx_event_work(struct ipw2100_priv *priv); 320static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
324static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev); 321static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
325static struct iw_handler_def ipw2100_wx_handler_def; 322static struct iw_handler_def ipw2100_wx_handler_def;
326 323
327 324static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
328static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
329{ 325{
330 *val = readl((void __iomem *)(dev->base_addr + reg)); 326 *val = readl((void __iomem *)(dev->base_addr + reg));
331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val); 327 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
@@ -337,13 +333,14 @@ static inline void write_register(struct net_device *dev, u32 reg, u32 val)
337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val); 333 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
338} 334}
339 335
340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val) 336static inline void read_register_word(struct net_device *dev, u32 reg,
337 u16 * val)
341{ 338{
342 *val = readw((void __iomem *)(dev->base_addr + reg)); 339 *val = readw((void __iomem *)(dev->base_addr + reg));
343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val); 340 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
344} 341}
345 342
346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val) 343static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
347{ 344{
348 *val = readb((void __iomem *)(dev->base_addr + reg)); 345 *val = readb((void __iomem *)(dev->base_addr + reg));
349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val); 346 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
@@ -355,14 +352,13 @@ static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val); 352 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
356} 353}
357 354
358
359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val) 355static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
360{ 356{
361 writeb(val, (void __iomem *)(dev->base_addr + reg)); 357 writeb(val, (void __iomem *)(dev->base_addr + reg));
362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val); 358 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
363} 359}
364 360
365static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val) 361static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 * val)
366{ 362{
367 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 363 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
368 addr & IPW_REG_INDIRECT_ADDR_MASK); 364 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -376,7 +372,7 @@ static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
376 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 372 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
377} 373}
378 374
379static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val) 375static inline void read_nic_word(struct net_device *dev, u32 addr, u16 * val)
380{ 376{
381 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 377 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
382 addr & IPW_REG_INDIRECT_ADDR_MASK); 378 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -390,7 +386,7 @@ static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
390 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 386 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
391} 387}
392 388
393static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val) 389static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 * val)
394{ 390{
395 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 391 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
396 addr & IPW_REG_INDIRECT_ADDR_MASK); 392 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -416,7 +412,7 @@ static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
416} 412}
417 413
418static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len, 414static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
419 const u8 *buf) 415 const u8 * buf)
420{ 416{
421 u32 aligned_addr; 417 u32 aligned_addr;
422 u32 aligned_len; 418 u32 aligned_len;
@@ -431,32 +427,30 @@ static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
431 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 427 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
432 aligned_addr); 428 aligned_addr);
433 for (i = dif_len; i < 4; i++, buf++) 429 for (i = dif_len; i < 4; i++, buf++)
434 write_register_byte( 430 write_register_byte(dev,
435 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, 431 IPW_REG_INDIRECT_ACCESS_DATA + i,
436 *buf); 432 *buf);
437 433
438 len -= dif_len; 434 len -= dif_len;
439 aligned_addr += 4; 435 aligned_addr += 4;
440 } 436 }
441 437
442 /* read DWs through autoincrement registers */ 438 /* read DWs through autoincrement registers */
443 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 439 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
444 aligned_addr);
445 aligned_len = len & (~0x3); 440 aligned_len = len & (~0x3);
446 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 441 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
447 write_register( 442 write_register(dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *) buf);
448 dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
449 443
450 /* copy the last nibble */ 444 /* copy the last nibble */
451 dif_len = len - aligned_len; 445 dif_len = len - aligned_len;
452 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr); 446 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
453 for (i = 0; i < dif_len; i++, buf++) 447 for (i = 0; i < dif_len; i++, buf++)
454 write_register_byte( 448 write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
455 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf); 449 *buf);
456} 450}
457 451
458static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len, 452static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
459 u8 *buf) 453 u8 * buf)
460{ 454{
461 u32 aligned_addr; 455 u32 aligned_addr;
462 u32 aligned_len; 456 u32 aligned_len;
@@ -471,39 +465,38 @@ static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
471 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 465 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
472 aligned_addr); 466 aligned_addr);
473 for (i = dif_len; i < 4; i++, buf++) 467 for (i = dif_len; i < 4; i++, buf++)
474 read_register_byte( 468 read_register_byte(dev,
475 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf); 469 IPW_REG_INDIRECT_ACCESS_DATA + i,
470 buf);
476 471
477 len -= dif_len; 472 len -= dif_len;
478 aligned_addr += 4; 473 aligned_addr += 4;
479 } 474 }
480 475
481 /* read DWs through autoincrement registers */ 476 /* read DWs through autoincrement registers */
482 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 477 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
483 aligned_addr);
484 aligned_len = len & (~0x3); 478 aligned_len = len & (~0x3);
485 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 479 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
486 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, 480 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, (u32 *) buf);
487 (u32 *)buf);
488 481
489 /* copy the last nibble */ 482 /* copy the last nibble */
490 dif_len = len - aligned_len; 483 dif_len = len - aligned_len;
491 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 484 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
492 aligned_addr);
493 for (i = 0; i < dif_len; i++, buf++) 485 for (i = 0; i < dif_len; i++, buf++)
494 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + 486 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
495 i, buf);
496} 487}
497 488
498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev) 489static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
499{ 490{
500 return (dev->base_addr && 491 return (dev->base_addr &&
501 (readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START)) 492 (readl
493 ((void __iomem *)(dev->base_addr +
494 IPW_REG_DOA_DEBUG_AREA_START))
502 == IPW_DATA_DOA_DEBUG_VALUE)); 495 == IPW_DATA_DOA_DEBUG_VALUE));
503} 496}
504 497
505static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord, 498static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
506 void *val, u32 *len) 499 void *val, u32 * len)
507{ 500{
508 struct ipw2100_ordinals *ordinals = &priv->ordinals; 501 struct ipw2100_ordinals *ordinals = &priv->ordinals;
509 u32 addr; 502 u32 addr;
@@ -529,8 +522,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
529 return -EINVAL; 522 return -EINVAL;
530 } 523 }
531 524
532 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 525 read_nic_dword(priv->net_dev,
533 &addr); 526 ordinals->table1_addr + (ord << 2), &addr);
534 read_nic_dword(priv->net_dev, addr, val); 527 read_nic_dword(priv->net_dev, addr, val);
535 528
536 *len = IPW_ORD_TAB_1_ENTRY_SIZE; 529 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
@@ -543,8 +536,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
543 ord -= IPW_START_ORD_TAB_2; 536 ord -= IPW_START_ORD_TAB_2;
544 537
545 /* get the address of statistic */ 538 /* get the address of statistic */
546 read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3), 539 read_nic_dword(priv->net_dev,
547 &addr); 540 ordinals->table2_addr + (ord << 3), &addr);
548 541
549 /* get the second DW of statistics ; 542 /* get the second DW of statistics ;
550 * two 16-bit words - first is length, second is count */ 543 * two 16-bit words - first is length, second is count */
@@ -553,10 +546,10 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
553 &field_info); 546 &field_info);
554 547
555 /* get each entry length */ 548 /* get each entry length */
556 field_len = *((u16 *)&field_info); 549 field_len = *((u16 *) & field_info);
557 550
558 /* get number of entries */ 551 /* get number of entries */
559 field_count = *(((u16 *)&field_info) + 1); 552 field_count = *(((u16 *) & field_info) + 1);
560 553
561 /* abort if no enought memory */ 554 /* abort if no enought memory */
562 total_length = field_len * field_count; 555 total_length = field_len * field_count;
@@ -581,8 +574,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
581 return -EINVAL; 574 return -EINVAL;
582} 575}
583 576
584static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val, 577static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 * val,
585 u32 *len) 578 u32 * len)
586{ 579{
587 struct ipw2100_ordinals *ordinals = &priv->ordinals; 580 struct ipw2100_ordinals *ordinals = &priv->ordinals;
588 u32 addr; 581 u32 addr;
@@ -594,8 +587,8 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
594 return -EINVAL; 587 return -EINVAL;
595 } 588 }
596 589
597 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 590 read_nic_dword(priv->net_dev,
598 &addr); 591 ordinals->table1_addr + (ord << 2), &addr);
599 592
600 write_nic_dword(priv->net_dev, addr, *val); 593 write_nic_dword(priv->net_dev, addr, *val);
601 594
@@ -612,7 +605,7 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
612} 605}
613 606
614static char *snprint_line(char *buf, size_t count, 607static char *snprint_line(char *buf, size_t count,
615 const u8 *data, u32 len, u32 ofs) 608 const u8 * data, u32 len, u32 ofs)
616{ 609{
617 int out, i, j, l; 610 int out, i, j, l;
618 char c; 611 char c;
@@ -646,7 +639,7 @@ static char *snprint_line(char *buf, size_t count,
646 return buf; 639 return buf;
647} 640}
648 641
649static void printk_buf(int level, const u8 *data, u32 len) 642static void printk_buf(int level, const u8 * data, u32 len)
650{ 643{
651 char line[81]; 644 char line[81];
652 u32 ofs = 0; 645 u32 ofs = 0;
@@ -662,8 +655,6 @@ static void printk_buf(int level, const u8 *data, u32 len)
662 } 655 }
663} 656}
664 657
665
666
667#define MAX_RESET_BACKOFF 10 658#define MAX_RESET_BACKOFF 10
668 659
669static inline void schedule_reset(struct ipw2100_priv *priv) 660static inline void schedule_reset(struct ipw2100_priv *priv)
@@ -703,7 +694,7 @@ static inline void schedule_reset(struct ipw2100_priv *priv)
703 694
704#define HOST_COMPLETE_TIMEOUT (2 * HZ) 695#define HOST_COMPLETE_TIMEOUT (2 * HZ)
705static int ipw2100_hw_send_command(struct ipw2100_priv *priv, 696static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
706 struct host_command * cmd) 697 struct host_command *cmd)
707{ 698{
708 struct list_head *element; 699 struct list_head *element;
709 struct ipw2100_tx_packet *packet; 700 struct ipw2100_tx_packet *packet;
@@ -713,25 +704,28 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
713 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 704 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
714 command_types[cmd->host_command], cmd->host_command, 705 command_types[cmd->host_command], cmd->host_command,
715 cmd->host_command_length); 706 cmd->host_command_length);
716 printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters, 707 printk_buf(IPW_DL_HC, (u8 *) cmd->host_command_parameters,
717 cmd->host_command_length); 708 cmd->host_command_length);
718 709
719 spin_lock_irqsave(&priv->low_lock, flags); 710 spin_lock_irqsave(&priv->low_lock, flags);
720 711
721 if (priv->fatal_error) { 712 if (priv->fatal_error) {
722 IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n"); 713 IPW_DEBUG_INFO
714 ("Attempt to send command while hardware in fatal error condition.\n");
723 err = -EIO; 715 err = -EIO;
724 goto fail_unlock; 716 goto fail_unlock;
725 } 717 }
726 718
727 if (!(priv->status & STATUS_RUNNING)) { 719 if (!(priv->status & STATUS_RUNNING)) {
728 IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n"); 720 IPW_DEBUG_INFO
721 ("Attempt to send command while hardware is not running.\n");
729 err = -EIO; 722 err = -EIO;
730 goto fail_unlock; 723 goto fail_unlock;
731 } 724 }
732 725
733 if (priv->status & STATUS_CMD_ACTIVE) { 726 if (priv->status & STATUS_CMD_ACTIVE) {
734 IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n"); 727 IPW_DEBUG_INFO
728 ("Attempt to send command while another command is pending.\n");
735 err = -EBUSY; 729 err = -EBUSY;
736 goto fail_unlock; 730 goto fail_unlock;
737 } 731 }
@@ -752,7 +746,8 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
752 /* initialize the firmware command packet */ 746 /* initialize the firmware command packet */
753 packet->info.c_struct.cmd->host_command_reg = cmd->host_command; 747 packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
754 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1; 748 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
755 packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length; 749 packet->info.c_struct.cmd->host_command_len_reg =
750 cmd->host_command_length;
756 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence; 751 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
757 752
758 memcpy(packet->info.c_struct.cmd->host_command_params_reg, 753 memcpy(packet->info.c_struct.cmd->host_command_params_reg,
@@ -776,13 +771,15 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
776 * then there is a problem. 771 * then there is a problem.
777 */ 772 */
778 773
779 err = wait_event_interruptible_timeout( 774 err =
780 priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE), 775 wait_event_interruptible_timeout(priv->wait_command_queue,
781 HOST_COMPLETE_TIMEOUT); 776 !(priv->
777 status & STATUS_CMD_ACTIVE),
778 HOST_COMPLETE_TIMEOUT);
782 779
783 if (err == 0) { 780 if (err == 0) {
784 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 781 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
785 HOST_COMPLETE_TIMEOUT / (HZ / 100)); 782 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
786 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT; 783 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
787 priv->status &= ~STATUS_CMD_ACTIVE; 784 priv->status &= ~STATUS_CMD_ACTIVE;
788 schedule_reset(priv); 785 schedule_reset(priv);
@@ -804,13 +801,12 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
804 801
805 return 0; 802 return 0;
806 803
807 fail_unlock: 804 fail_unlock:
808 spin_unlock_irqrestore(&priv->low_lock, flags); 805 spin_unlock_irqrestore(&priv->low_lock, flags);
809 806
810 return err; 807 return err;
811} 808}
812 809
813
814/* 810/*
815 * Verify the values and data access of the hardware 811 * Verify the values and data access of the hardware
816 * No locks needed or used. No functions called. 812 * No locks needed or used. No functions called.
@@ -825,8 +821,7 @@ static int ipw2100_verify(struct ipw2100_priv *priv)
825 821
826 /* Domain 0 check - all values should be DOA_DEBUG */ 822 /* Domain 0 check - all values should be DOA_DEBUG */
827 for (address = IPW_REG_DOA_DEBUG_AREA_START; 823 for (address = IPW_REG_DOA_DEBUG_AREA_START;
828 address < IPW_REG_DOA_DEBUG_AREA_END; 824 address < IPW_REG_DOA_DEBUG_AREA_END; address += sizeof(u32)) {
829 address += sizeof(u32)) {
830 read_register(priv->net_dev, address, &data1); 825 read_register(priv->net_dev, address, &data1);
831 if (data1 != IPW_DATA_DOA_DEBUG_VALUE) 826 if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
832 return -EIO; 827 return -EIO;
@@ -898,7 +893,6 @@ static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
898 return -EIO; 893 return -EIO;
899} 894}
900 895
901
902/********************************************************************* 896/*********************************************************************
903 Procedure : sw_reset_and_clock 897 Procedure : sw_reset_and_clock
904 Purpose : Asserts s/w reset, asserts clock initialization 898 Purpose : Asserts s/w reset, asserts clock initialization
@@ -975,17 +969,16 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
975 969
976 if (priv->fatal_error) { 970 if (priv->fatal_error) {
977 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after " 971 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
978 "fatal error %d. Interface must be brought down.\n", 972 "fatal error %d. Interface must be brought down.\n",
979 priv->net_dev->name, priv->fatal_error); 973 priv->net_dev->name, priv->fatal_error);
980 return -EINVAL; 974 return -EINVAL;
981 } 975 }
982
983#ifdef CONFIG_PM 976#ifdef CONFIG_PM
984 if (!ipw2100_firmware.version) { 977 if (!ipw2100_firmware.version) {
985 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 978 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
986 if (err) { 979 if (err) {
987 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 980 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
988 priv->net_dev->name, err); 981 priv->net_dev->name, err);
989 priv->fatal_error = IPW2100_ERR_FW_LOAD; 982 priv->fatal_error = IPW2100_ERR_FW_LOAD;
990 goto fail; 983 goto fail;
991 } 984 }
@@ -994,7 +987,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
994 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 987 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
995 if (err) { 988 if (err) {
996 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 989 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
997 priv->net_dev->name, err); 990 priv->net_dev->name, err);
998 priv->fatal_error = IPW2100_ERR_FW_LOAD; 991 priv->fatal_error = IPW2100_ERR_FW_LOAD;
999 goto fail; 992 goto fail;
1000 } 993 }
@@ -1005,21 +998,20 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1005 err = sw_reset_and_clock(priv); 998 err = sw_reset_and_clock(priv);
1006 if (err) { 999 if (err) {
1007 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n", 1000 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
1008 priv->net_dev->name, err); 1001 priv->net_dev->name, err);
1009 goto fail; 1002 goto fail;
1010 } 1003 }
1011 1004
1012 err = ipw2100_verify(priv); 1005 err = ipw2100_verify(priv);
1013 if (err) { 1006 if (err) {
1014 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n", 1007 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
1015 priv->net_dev->name, err); 1008 priv->net_dev->name, err);
1016 goto fail; 1009 goto fail;
1017 } 1010 }
1018 1011
1019 /* Hold ARC */ 1012 /* Hold ARC */
1020 write_nic_dword(priv->net_dev, 1013 write_nic_dword(priv->net_dev,
1021 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1014 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x80000000);
1022 0x80000000);
1023 1015
1024 /* allow ARC to run */ 1016 /* allow ARC to run */
1025 write_register(priv->net_dev, IPW_REG_RESET_REG, 0); 1017 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
@@ -1034,13 +1026,13 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1034 1026
1035 /* release ARC */ 1027 /* release ARC */
1036 write_nic_dword(priv->net_dev, 1028 write_nic_dword(priv->net_dev,
1037 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1029 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x00000000);
1038 0x00000000);
1039 1030
1040 /* s/w reset and clock stabilization (again!!!) */ 1031 /* s/w reset and clock stabilization (again!!!) */
1041 err = sw_reset_and_clock(priv); 1032 err = sw_reset_and_clock(priv);
1042 if (err) { 1033 if (err) {
1043 printk(KERN_ERR DRV_NAME ": %s: sw_reset_and_clock failed: %d\n", 1034 printk(KERN_ERR DRV_NAME
1035 ": %s: sw_reset_and_clock failed: %d\n",
1044 priv->net_dev->name, err); 1036 priv->net_dev->name, err);
1045 goto fail; 1037 goto fail;
1046 } 1038 }
@@ -1049,10 +1041,9 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1049 err = ipw2100_fw_download(priv, &ipw2100_firmware); 1041 err = ipw2100_fw_download(priv, &ipw2100_firmware);
1050 if (err) { 1042 if (err) {
1051 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n", 1043 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
1052 priv->net_dev->name, err); 1044 priv->net_dev->name, err);
1053 goto fail; 1045 goto fail;
1054 } 1046 }
1055
1056#ifndef CONFIG_PM 1047#ifndef CONFIG_PM
1057 /* 1048 /*
1058 * When the .resume method of the driver is called, the other 1049 * When the .resume method of the driver is called, the other
@@ -1084,7 +1075,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1084 1075
1085 return 0; 1076 return 0;
1086 1077
1087 fail: 1078 fail:
1088 ipw2100_release_firmware(priv, &ipw2100_firmware); 1079 ipw2100_release_firmware(priv, &ipw2100_firmware);
1089 return err; 1080 return err;
1090} 1081}
@@ -1105,7 +1096,6 @@ static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
1105 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0); 1096 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
1106} 1097}
1107 1098
1108
1109static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv) 1099static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
1110{ 1100{
1111 struct ipw2100_ordinals *ord = &priv->ordinals; 1101 struct ipw2100_ordinals *ord = &priv->ordinals;
@@ -1177,11 +1167,10 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1177 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1 1167 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
1178 */ 1168 */
1179 len = sizeof(addr); 1169 len = sizeof(addr);
1180 if (ipw2100_get_ordinal( 1170 if (ipw2100_get_ordinal
1181 priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, 1171 (priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, &addr, &len)) {
1182 &addr, &len)) {
1183 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1172 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1184 __LINE__); 1173 __LINE__);
1185 return -EIO; 1174 return -EIO;
1186 } 1175 }
1187 1176
@@ -1194,7 +1183,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1194 priv->eeprom_version = (val >> 24) & 0xFF; 1183 priv->eeprom_version = (val >> 24) & 0xFF;
1195 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version); 1184 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
1196 1185
1197 /* 1186 /*
1198 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware 1187 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
1199 * 1188 *
1200 * notice that the EEPROM bit is reverse polarity, i.e. 1189 * notice that the EEPROM bit is reverse polarity, i.e.
@@ -1206,8 +1195,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1206 priv->hw_features |= HW_FEATURE_RFKILL; 1195 priv->hw_features |= HW_FEATURE_RFKILL;
1207 1196
1208 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n", 1197 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
1209 (priv->hw_features & HW_FEATURE_RFKILL) ? 1198 (priv->hw_features & HW_FEATURE_RFKILL) ? "" : "not ");
1210 "" : "not ");
1211 1199
1212 return 0; 1200 return 0;
1213} 1201}
@@ -1234,7 +1222,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1234 * fw & dino ucode 1222 * fw & dino ucode
1235 */ 1223 */
1236 if (ipw2100_download_firmware(priv)) { 1224 if (ipw2100_download_firmware(priv)) {
1237 printk(KERN_ERR DRV_NAME ": %s: Failed to power on the adapter.\n", 1225 printk(KERN_ERR DRV_NAME
1226 ": %s: Failed to power on the adapter.\n",
1238 priv->net_dev->name); 1227 priv->net_dev->name);
1239 return -EIO; 1228 return -EIO;
1240 } 1229 }
@@ -1293,7 +1282,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1293 i ? "SUCCESS" : "FAILED"); 1282 i ? "SUCCESS" : "FAILED");
1294 1283
1295 if (!i) { 1284 if (!i) {
1296 printk(KERN_WARNING DRV_NAME ": %s: Firmware did not initialize.\n", 1285 printk(KERN_WARNING DRV_NAME
1286 ": %s: Firmware did not initialize.\n",
1297 priv->net_dev->name); 1287 priv->net_dev->name);
1298 return -EIO; 1288 return -EIO;
1299 } 1289 }
@@ -1326,7 +1316,6 @@ static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
1326 priv->fatal_error = 0; 1316 priv->fatal_error = 0;
1327} 1317}
1328 1318
1329
1330/* NOTE: Our interrupt is disabled when this method is called */ 1319/* NOTE: Our interrupt is disabled when this method is called */
1331static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv) 1320static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1332{ 1321{
@@ -1350,19 +1339,19 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1350 1339
1351 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 1340 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1352 break; 1341 break;
1353 } while(i--); 1342 } while (i--);
1354 1343
1355 priv->status &= ~STATUS_RESET_PENDING; 1344 priv->status &= ~STATUS_RESET_PENDING;
1356 1345
1357 if (!i) { 1346 if (!i) {
1358 IPW_DEBUG_INFO("exit - waited too long for master assert stop\n"); 1347 IPW_DEBUG_INFO
1348 ("exit - waited too long for master assert stop\n");
1359 return -EIO; 1349 return -EIO;
1360 } 1350 }
1361 1351
1362 write_register(priv->net_dev, IPW_REG_RESET_REG, 1352 write_register(priv->net_dev, IPW_REG_RESET_REG,
1363 IPW_AUX_HOST_RESET_REG_SW_RESET); 1353 IPW_AUX_HOST_RESET_REG_SW_RESET);
1364 1354
1365
1366 /* Reset any fatal_error conditions */ 1355 /* Reset any fatal_error conditions */
1367 ipw2100_reset_fatalerror(priv); 1356 ipw2100_reset_fatalerror(priv);
1368 1357
@@ -1415,7 +1404,6 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
1415 return -EIO; 1404 return -EIO;
1416} 1405}
1417 1406
1418
1419static int ipw2100_enable_adapter(struct ipw2100_priv *priv) 1407static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1420{ 1408{
1421 struct host_command cmd = { 1409 struct host_command cmd = {
@@ -1445,9 +1433,8 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1445 1433
1446 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED); 1434 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
1447 if (err) { 1435 if (err) {
1448 IPW_DEBUG_INFO( 1436 IPW_DEBUG_INFO("%s: card not responding to init command.\n",
1449 "%s: card not responding to init command.\n", 1437 priv->net_dev->name);
1450 priv->net_dev->name);
1451 goto fail_up; 1438 goto fail_up;
1452 } 1439 }
1453 1440
@@ -1456,7 +1443,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1456 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); 1443 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
1457 } 1444 }
1458 1445
1459fail_up: 1446 fail_up:
1460 up(&priv->adapter_sem); 1447 up(&priv->adapter_sem);
1461 return err; 1448 return err;
1462} 1449}
@@ -1488,7 +1475,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1488 1475
1489 err = ipw2100_hw_phy_off(priv); 1476 err = ipw2100_hw_phy_off(priv);
1490 if (err) 1477 if (err)
1491 printk(KERN_WARNING DRV_NAME ": Error disabling radio %d\n", err); 1478 printk(KERN_WARNING DRV_NAME
1479 ": Error disabling radio %d\n", err);
1492 1480
1493 /* 1481 /*
1494 * If in D0-standby mode going directly to D3 may cause a 1482 * If in D0-standby mode going directly to D3 may cause a
@@ -1566,7 +1554,6 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1566 return 0; 1554 return 0;
1567} 1555}
1568 1556
1569
1570static int ipw2100_disable_adapter(struct ipw2100_priv *priv) 1557static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1571{ 1558{
1572 struct host_command cmd = { 1559 struct host_command cmd = {
@@ -1593,19 +1580,21 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1593 1580
1594 err = ipw2100_hw_send_command(priv, &cmd); 1581 err = ipw2100_hw_send_command(priv, &cmd);
1595 if (err) { 1582 if (err) {
1596 printk(KERN_WARNING DRV_NAME ": exit - failed to send CARD_DISABLE command\n"); 1583 printk(KERN_WARNING DRV_NAME
1584 ": exit - failed to send CARD_DISABLE command\n");
1597 goto fail_up; 1585 goto fail_up;
1598 } 1586 }
1599 1587
1600 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED); 1588 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
1601 if (err) { 1589 if (err) {
1602 printk(KERN_WARNING DRV_NAME ": exit - card failed to change to DISABLED\n"); 1590 printk(KERN_WARNING DRV_NAME
1591 ": exit - card failed to change to DISABLED\n");
1603 goto fail_up; 1592 goto fail_up;
1604 } 1593 }
1605 1594
1606 IPW_DEBUG_INFO("TODO: implement scan state machine\n"); 1595 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1607 1596
1608fail_up: 1597 fail_up:
1609 up(&priv->adapter_sem); 1598 up(&priv->adapter_sem);
1610 return err; 1599 return err;
1611} 1600}
@@ -1627,7 +1616,7 @@ static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
1627 1616
1628 if (!(priv->config & CFG_ASSOCIATE)) 1617 if (!(priv->config & CFG_ASSOCIATE))
1629 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE; 1618 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
1630 if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled) 1619 if ((priv->ieee->sec.flags & SEC_ENABLED) && priv->ieee->sec.enabled)
1631 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL; 1620 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
1632 if (priv->config & CFG_PASSIVE_SCAN) 1621 if (priv->config & CFG_PASSIVE_SCAN)
1633 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE; 1622 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
@@ -1709,8 +1698,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1709 (priv->status & STATUS_RESET_PENDING)) { 1698 (priv->status & STATUS_RESET_PENDING)) {
1710 /* Power cycle the card ... */ 1699 /* Power cycle the card ... */
1711 if (ipw2100_power_cycle_adapter(priv)) { 1700 if (ipw2100_power_cycle_adapter(priv)) {
1712 printk(KERN_WARNING DRV_NAME ": %s: Could not cycle adapter.\n", 1701 printk(KERN_WARNING DRV_NAME
1713 priv->net_dev->name); 1702 ": %s: Could not cycle adapter.\n",
1703 priv->net_dev->name);
1714 rc = 1; 1704 rc = 1;
1715 goto exit; 1705 goto exit;
1716 } 1706 }
@@ -1719,8 +1709,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1719 1709
1720 /* Load the firmware, start the clocks, etc. */ 1710 /* Load the firmware, start the clocks, etc. */
1721 if (ipw2100_start_adapter(priv)) { 1711 if (ipw2100_start_adapter(priv)) {
1722 printk(KERN_ERR DRV_NAME ": %s: Failed to start the firmware.\n", 1712 printk(KERN_ERR DRV_NAME
1723 priv->net_dev->name); 1713 ": %s: Failed to start the firmware.\n",
1714 priv->net_dev->name);
1724 rc = 1; 1715 rc = 1;
1725 goto exit; 1716 goto exit;
1726 } 1717 }
@@ -1729,16 +1720,18 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1729 1720
1730 /* Determine capabilities of this particular HW configuration */ 1721 /* Determine capabilities of this particular HW configuration */
1731 if (ipw2100_get_hw_features(priv)) { 1722 if (ipw2100_get_hw_features(priv)) {
1732 printk(KERN_ERR DRV_NAME ": %s: Failed to determine HW features.\n", 1723 printk(KERN_ERR DRV_NAME
1733 priv->net_dev->name); 1724 ": %s: Failed to determine HW features.\n",
1725 priv->net_dev->name);
1734 rc = 1; 1726 rc = 1;
1735 goto exit; 1727 goto exit;
1736 } 1728 }
1737 1729
1738 lock = LOCK_NONE; 1730 lock = LOCK_NONE;
1739 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) { 1731 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
1740 printk(KERN_ERR DRV_NAME ": %s: Failed to clear ordinal lock.\n", 1732 printk(KERN_ERR DRV_NAME
1741 priv->net_dev->name); 1733 ": %s: Failed to clear ordinal lock.\n",
1734 priv->net_dev->name);
1742 rc = 1; 1735 rc = 1;
1743 goto exit; 1736 goto exit;
1744 } 1737 }
@@ -1764,7 +1757,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1764 * HOST_COMPLETE */ 1757 * HOST_COMPLETE */
1765 if (ipw2100_adapter_setup(priv)) { 1758 if (ipw2100_adapter_setup(priv)) {
1766 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n", 1759 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n",
1767 priv->net_dev->name); 1760 priv->net_dev->name);
1768 rc = 1; 1761 rc = 1;
1769 goto exit; 1762 goto exit;
1770 } 1763 }
@@ -1773,20 +1766,19 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1773 /* Enable the adapter - sends HOST_COMPLETE */ 1766 /* Enable the adapter - sends HOST_COMPLETE */
1774 if (ipw2100_enable_adapter(priv)) { 1767 if (ipw2100_enable_adapter(priv)) {
1775 printk(KERN_ERR DRV_NAME ": " 1768 printk(KERN_ERR DRV_NAME ": "
1776 "%s: failed in call to enable adapter.\n", 1769 "%s: failed in call to enable adapter.\n",
1777 priv->net_dev->name); 1770 priv->net_dev->name);
1778 ipw2100_hw_stop_adapter(priv); 1771 ipw2100_hw_stop_adapter(priv);
1779 rc = 1; 1772 rc = 1;
1780 goto exit; 1773 goto exit;
1781 } 1774 }
1782 1775
1783
1784 /* Start a scan . . . */ 1776 /* Start a scan . . . */
1785 ipw2100_set_scan_options(priv); 1777 ipw2100_set_scan_options(priv);
1786 ipw2100_start_scan(priv); 1778 ipw2100_start_scan(priv);
1787 } 1779 }
1788 1780
1789 exit: 1781 exit:
1790 return rc; 1782 return rc;
1791} 1783}
1792 1784
@@ -1802,8 +1794,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1802 unsigned long flags; 1794 unsigned long flags;
1803 union iwreq_data wrqu = { 1795 union iwreq_data wrqu = {
1804 .ap_addr = { 1796 .ap_addr = {
1805 .sa_family = ARPHRD_ETHER 1797 .sa_family = ARPHRD_ETHER}
1806 }
1807 }; 1798 };
1808 int associated = priv->status & STATUS_ASSOCIATED; 1799 int associated = priv->status & STATUS_ASSOCIATED;
1809 1800
@@ -1842,7 +1833,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1842 1833
1843#ifdef ACPI_CSTATE_LIMIT_DEFINED 1834#ifdef ACPI_CSTATE_LIMIT_DEFINED
1844 if (priv->config & CFG_C3_DISABLED) { 1835 if (priv->config & CFG_C3_DISABLED) {
1845 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 1836 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
1846 acpi_set_cstate_limit(priv->cstate_limit); 1837 acpi_set_cstate_limit(priv->cstate_limit);
1847 priv->config &= ~CFG_C3_DISABLED; 1838 priv->config &= ~CFG_C3_DISABLED;
1848 } 1839 }
@@ -1862,14 +1853,12 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1862 unsigned long flags; 1853 unsigned long flags;
1863 union iwreq_data wrqu = { 1854 union iwreq_data wrqu = {
1864 .ap_addr = { 1855 .ap_addr = {
1865 .sa_family = ARPHRD_ETHER 1856 .sa_family = ARPHRD_ETHER}
1866 }
1867 }; 1857 };
1868 int associated = priv->status & STATUS_ASSOCIATED; 1858 int associated = priv->status & STATUS_ASSOCIATED;
1869 1859
1870 spin_lock_irqsave(&priv->low_lock, flags); 1860 spin_lock_irqsave(&priv->low_lock, flags);
1871 IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n", 1861 IPW_DEBUG_INFO(": %s: Restarting adapter.\n", priv->net_dev->name);
1872 priv->net_dev->name);
1873 priv->resets++; 1862 priv->resets++;
1874 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); 1863 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1875 priv->status |= STATUS_SECURITY_UPDATED; 1864 priv->status |= STATUS_SECURITY_UPDATED;
@@ -1894,7 +1883,6 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1894 1883
1895} 1884}
1896 1885
1897
1898static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) 1886static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1899{ 1887{
1900 1888
@@ -1904,7 +1892,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1904 u32 txrate; 1892 u32 txrate;
1905 u32 chan; 1893 u32 chan;
1906 char *txratename; 1894 char *txratename;
1907 u8 bssid[ETH_ALEN]; 1895 u8 bssid[ETH_ALEN];
1908 1896
1909 /* 1897 /*
1910 * TBD: BSSID is usually 00:00:00:00:00:00 here and not 1898 * TBD: BSSID is usually 00:00:00:00:00:00 here and not
@@ -1918,16 +1906,15 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1918 essid, &essid_len); 1906 essid, &essid_len);
1919 if (ret) { 1907 if (ret) {
1920 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1908 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1921 __LINE__); 1909 __LINE__);
1922 return; 1910 return;
1923 } 1911 }
1924 1912
1925 len = sizeof(u32); 1913 len = sizeof(u32);
1926 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, 1914 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &txrate, &len);
1927 &txrate, &len);
1928 if (ret) { 1915 if (ret) {
1929 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1916 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1930 __LINE__); 1917 __LINE__);
1931 return; 1918 return;
1932 } 1919 }
1933 1920
@@ -1935,19 +1922,18 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1935 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len); 1922 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
1936 if (ret) { 1923 if (ret) {
1937 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1924 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1938 __LINE__); 1925 __LINE__);
1939 return; 1926 return;
1940 } 1927 }
1941 len = ETH_ALEN; 1928 len = ETH_ALEN;
1942 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); 1929 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
1943 if (ret) { 1930 if (ret) {
1944 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1931 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1945 __LINE__); 1932 __LINE__);
1946 return; 1933 return;
1947 } 1934 }
1948 memcpy(priv->ieee->bssid, bssid, ETH_ALEN); 1935 memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
1949 1936
1950
1951 switch (txrate) { 1937 switch (txrate) {
1952 case TX_RATE_1_MBIT: 1938 case TX_RATE_1_MBIT:
1953 txratename = "1Mbps"; 1939 txratename = "1Mbps";
@@ -1974,7 +1960,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1974 1960
1975 /* now we copy read ssid into dev */ 1961 /* now we copy read ssid into dev */
1976 if (!(priv->config & CFG_STATIC_ESSID)) { 1962 if (!(priv->config & CFG_STATIC_ESSID)) {
1977 priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE); 1963 priv->essid_len = min((u8) essid_len, (u8) IW_ESSID_MAX_SIZE);
1978 memcpy(priv->essid, essid, priv->essid_len); 1964 memcpy(priv->essid, essid, priv->essid_len);
1979 } 1965 }
1980 priv->channel = chan; 1966 priv->channel = chan;
@@ -1986,7 +1972,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1986 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10); 1972 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
1987} 1973}
1988 1974
1989
1990static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, 1975static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1991 int length, int batch_mode) 1976 int length, int batch_mode)
1992{ 1977{
@@ -2001,8 +1986,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2001 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len)); 1986 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
2002 1987
2003 if (ssid_len) 1988 if (ssid_len)
2004 memcpy((char*)cmd.host_command_parameters, 1989 memcpy(cmd.host_command_parameters, essid, ssid_len);
2005 essid, ssid_len);
2006 1990
2007 if (!batch_mode) { 1991 if (!batch_mode) {
2008 err = ipw2100_disable_adapter(priv); 1992 err = ipw2100_disable_adapter(priv);
@@ -2014,7 +1998,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2014 * disable auto association -- so we cheat by setting a bogus SSID */ 1998 * disable auto association -- so we cheat by setting a bogus SSID */
2015 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) { 1999 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
2016 int i; 2000 int i;
2017 u8 *bogus = (u8*)cmd.host_command_parameters; 2001 u8 *bogus = (u8 *) cmd.host_command_parameters;
2018 for (i = 0; i < IW_ESSID_MAX_SIZE; i++) 2002 for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
2019 bogus[i] = 0x18 + i; 2003 bogus[i] = 0x18 + i;
2020 cmd.host_command_length = IW_ESSID_MAX_SIZE; 2004 cmd.host_command_length = IW_ESSID_MAX_SIZE;
@@ -2025,8 +2009,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2025 2009
2026 err = ipw2100_hw_send_command(priv, &cmd); 2010 err = ipw2100_hw_send_command(priv, &cmd);
2027 if (!err) { 2011 if (!err) {
2028 memset(priv->essid + ssid_len, 0, 2012 memset(priv->essid + ssid_len, 0, IW_ESSID_MAX_SIZE - ssid_len);
2029 IW_ESSID_MAX_SIZE - ssid_len);
2030 memcpy(priv->essid, essid, ssid_len); 2013 memcpy(priv->essid, essid, ssid_len);
2031 priv->essid_len = ssid_len; 2014 priv->essid_len = ssid_len;
2032 } 2015 }
@@ -2071,14 +2054,14 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2071static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) 2054static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2072{ 2055{
2073 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n", 2056 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
2074 priv->net_dev->name); 2057 priv->net_dev->name);
2075 2058
2076 /* RF_KILL is now enabled (else we wouldn't be here) */ 2059 /* RF_KILL is now enabled (else we wouldn't be here) */
2077 priv->status |= STATUS_RF_KILL_HW; 2060 priv->status |= STATUS_RF_KILL_HW;
2078 2061
2079#ifdef ACPI_CSTATE_LIMIT_DEFINED 2062#ifdef ACPI_CSTATE_LIMIT_DEFINED
2080 if (priv->config & CFG_C3_DISABLED) { 2063 if (priv->config & CFG_C3_DISABLED) {
2081 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 2064 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
2082 acpi_set_cstate_limit(priv->cstate_limit); 2065 acpi_set_cstate_limit(priv->cstate_limit);
2083 priv->config &= ~CFG_C3_DISABLED; 2066 priv->config &= ~CFG_C3_DISABLED;
2084 } 2067 }
@@ -2102,16 +2085,16 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2102#define IPW2100_HANDLER(v, f) { v, f, # v } 2085#define IPW2100_HANDLER(v, f) { v, f, # v }
2103struct ipw2100_status_indicator { 2086struct ipw2100_status_indicator {
2104 int status; 2087 int status;
2105 void (*cb)(struct ipw2100_priv *priv, u32 status); 2088 void (*cb) (struct ipw2100_priv * priv, u32 status);
2106 char *name; 2089 char *name;
2107}; 2090};
2108#else 2091#else
2109#define IPW2100_HANDLER(v, f) { v, f } 2092#define IPW2100_HANDLER(v, f) { v, f }
2110struct ipw2100_status_indicator { 2093struct ipw2100_status_indicator {
2111 int status; 2094 int status;
2112 void (*cb)(struct ipw2100_priv *priv, u32 status); 2095 void (*cb) (struct ipw2100_priv * priv, u32 status);
2113}; 2096};
2114#endif /* CONFIG_IPW_DEBUG */ 2097#endif /* CONFIG_IPW_DEBUG */
2115 2098
2116static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status) 2099static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2117{ 2100{
@@ -2135,7 +2118,6 @@ static const struct ipw2100_status_indicator status_handlers[] = {
2135 IPW2100_HANDLER(-1, NULL) 2118 IPW2100_HANDLER(-1, NULL)
2136}; 2119};
2137 2120
2138
2139static void isr_status_change(struct ipw2100_priv *priv, int status) 2121static void isr_status_change(struct ipw2100_priv *priv, int status)
2140{ 2122{
2141 int i; 2123 int i;
@@ -2153,7 +2135,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2153 for (i = 0; status_handlers[i].status != -1; i++) { 2135 for (i = 0; status_handlers[i].status != -1; i++) {
2154 if (status == status_handlers[i].status) { 2136 if (status == status_handlers[i].status) {
2155 IPW_DEBUG_NOTIF("Status change: %s\n", 2137 IPW_DEBUG_NOTIF("Status change: %s\n",
2156 status_handlers[i].name); 2138 status_handlers[i].name);
2157 if (status_handlers[i].cb) 2139 if (status_handlers[i].cb)
2158 status_handlers[i].cb(priv, status); 2140 status_handlers[i].cb(priv, status);
2159 priv->wstats.status = status; 2141 priv->wstats.status = status;
@@ -2164,9 +2146,8 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2164 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status); 2146 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
2165} 2147}
2166 2148
2167static void isr_rx_complete_command( 2149static void isr_rx_complete_command(struct ipw2100_priv *priv,
2168 struct ipw2100_priv *priv, 2150 struct ipw2100_cmd_header *cmd)
2169 struct ipw2100_cmd_header *cmd)
2170{ 2151{
2171#ifdef CONFIG_IPW_DEBUG 2152#ifdef CONFIG_IPW_DEBUG
2172 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) { 2153 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
@@ -2196,10 +2177,8 @@ static const char *frame_types[] = {
2196}; 2177};
2197#endif 2178#endif
2198 2179
2199 2180static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
2200static inline int ipw2100_alloc_skb( 2181 struct ipw2100_rx_packet *packet)
2201 struct ipw2100_priv *priv,
2202 struct ipw2100_rx_packet *packet)
2203{ 2182{
2204 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx)); 2183 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
2205 if (!packet->skb) 2184 if (!packet->skb)
@@ -2215,7 +2194,6 @@ static inline int ipw2100_alloc_skb(
2215 return 0; 2194 return 0;
2216} 2195}
2217 2196
2218
2219#define SEARCH_ERROR 0xffffffff 2197#define SEARCH_ERROR 0xffffffff
2220#define SEARCH_FAIL 0xfffffffe 2198#define SEARCH_FAIL 0xfffffffe
2221#define SEARCH_SUCCESS 0xfffffff0 2199#define SEARCH_SUCCESS 0xfffffff0
@@ -2229,10 +2207,10 @@ static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
2229 if (priv->snapshot[0]) 2207 if (priv->snapshot[0])
2230 return 1; 2208 return 1;
2231 for (i = 0; i < 0x30; i++) { 2209 for (i = 0; i < 0x30; i++) {
2232 priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC); 2210 priv->snapshot[i] = (u8 *) kmalloc(0x1000, GFP_ATOMIC);
2233 if (!priv->snapshot[i]) { 2211 if (!priv->snapshot[i]) {
2234 IPW_DEBUG_INFO("%s: Error allocating snapshot " 2212 IPW_DEBUG_INFO("%s: Error allocating snapshot "
2235 "buffer %d\n", priv->net_dev->name, i); 2213 "buffer %d\n", priv->net_dev->name, i);
2236 while (i > 0) 2214 while (i > 0)
2237 kfree(priv->snapshot[--i]); 2215 kfree(priv->snapshot[--i]);
2238 priv->snapshot[0] = NULL; 2216 priv->snapshot[0] = NULL;
@@ -2253,7 +2231,7 @@ static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
2253 priv->snapshot[0] = NULL; 2231 priv->snapshot[0] = NULL;
2254} 2232}
2255 2233
2256static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf, 2234static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
2257 size_t len, int mode) 2235 size_t len, int mode)
2258{ 2236{
2259 u32 i, j; 2237 u32 i, j;
@@ -2270,9 +2248,9 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2270 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) { 2248 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
2271 read_nic_dword(priv->net_dev, i, &tmp); 2249 read_nic_dword(priv->net_dev, i, &tmp);
2272 if (mode == SEARCH_SNAPSHOT) 2250 if (mode == SEARCH_SNAPSHOT)
2273 *(u32 *)SNAPSHOT_ADDR(i) = tmp; 2251 *(u32 *) SNAPSHOT_ADDR(i) = tmp;
2274 if (ret == SEARCH_FAIL) { 2252 if (ret == SEARCH_FAIL) {
2275 d = (u8*)&tmp; 2253 d = (u8 *) & tmp;
2276 for (j = 0; j < 4; j++) { 2254 for (j = 0; j < 4; j++) {
2277 if (*s != *d) { 2255 if (*s != *d) {
2278 s = in_buf; 2256 s = in_buf;
@@ -2310,8 +2288,7 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2310static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH]; 2288static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
2311#endif 2289#endif
2312 2290
2313static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, 2291static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
2314 int i)
2315{ 2292{
2316#ifdef CONFIG_IPW_DEBUG_C3 2293#ifdef CONFIG_IPW_DEBUG_C3
2317 struct ipw2100_status *status = &priv->status_queue.drv[i]; 2294 struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2322,11 +2299,11 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2322 int limit; 2299 int limit;
2323#endif 2300#endif
2324 2301
2325 IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at " 2302 IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
2326 "0x%04zX.\n", i * sizeof(struct ipw2100_status)); 2303 i * sizeof(struct ipw2100_status));
2327 2304
2328#ifdef ACPI_CSTATE_LIMIT_DEFINED 2305#ifdef ACPI_CSTATE_LIMIT_DEFINED
2329 IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n"); 2306 IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
2330 limit = acpi_get_cstate_limit(); 2307 limit = acpi_get_cstate_limit();
2331 if (limit > 2) { 2308 if (limit > 2) {
2332 priv->cstate_limit = limit; 2309 priv->cstate_limit = limit;
@@ -2346,9 +2323,9 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2346 2323
2347 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 2324 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
2348 break; 2325 break;
2349 } while (j--); 2326 } while (j--);
2350 2327
2351 match = ipw2100_match_buf(priv, (u8*)status, 2328 match = ipw2100_match_buf(priv, (u8 *) status,
2352 sizeof(struct ipw2100_status), 2329 sizeof(struct ipw2100_status),
2353 SEARCH_SNAPSHOT); 2330 SEARCH_SNAPSHOT);
2354 if (match < SEARCH_SUCCESS) 2331 if (match < SEARCH_SUCCESS)
@@ -2360,7 +2337,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2360 IPW_DEBUG_INFO("%s: No DMA status match in " 2337 IPW_DEBUG_INFO("%s: No DMA status match in "
2361 "Firmware.\n", priv->net_dev->name); 2338 "Firmware.\n", priv->net_dev->name);
2362 2339
2363 printk_buf((u8*)priv->status_queue.drv, 2340 printk_buf((u8 *) priv->status_queue.drv,
2364 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH); 2341 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
2365#endif 2342#endif
2366 2343
@@ -2392,26 +2369,26 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2392 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); 2369 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2393 return; 2370 return;
2394 } 2371 }
2395 2372#ifdef CONFIG_IPW2100_MONITOR
2396 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR && 2373 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2374 priv->config & CFG_CRC_CHECK &&
2397 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { 2375 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2398 IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); 2376 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2399 priv->ieee->stats.rx_errors++; 2377 priv->ieee->stats.rx_errors++;
2400 return; 2378 return;
2401 } 2379 }
2380#endif
2402 2381
2403 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && 2382 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2404 !(priv->status & STATUS_ASSOCIATED))) { 2383 !(priv->status & STATUS_ASSOCIATED))) {
2405 IPW_DEBUG_DROP("Dropping packet while not associated.\n"); 2384 IPW_DEBUG_DROP("Dropping packet while not associated.\n");
2406 priv->wstats.discard.misc++; 2385 priv->wstats.discard.misc++;
2407 return; 2386 return;
2408 } 2387 }
2409 2388
2410
2411 pci_unmap_single(priv->pci_dev, 2389 pci_unmap_single(priv->pci_dev,
2412 packet->dma_addr, 2390 packet->dma_addr,
2413 sizeof(struct ipw2100_rx), 2391 sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
2414 PCI_DMA_FROMDEVICE);
2415 2392
2416 skb_put(packet->skb, status->frame_size); 2393 skb_put(packet->skb, status->frame_size);
2417 2394
@@ -2438,8 +2415,8 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2438 /* We need to allocate a new SKB and attach it to the RDB. */ 2415 /* We need to allocate a new SKB and attach it to the RDB. */
2439 if (unlikely(ipw2100_alloc_skb(priv, packet))) { 2416 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
2440 printk(KERN_WARNING DRV_NAME ": " 2417 printk(KERN_WARNING DRV_NAME ": "
2441 "%s: Unable to allocate SKB onto RBD ring - disabling " 2418 "%s: Unable to allocate SKB onto RBD ring - disabling "
2442 "adapter.\n", priv->net_dev->name); 2419 "adapter.\n", priv->net_dev->name);
2443 /* TODO: schedule adapter shutdown */ 2420 /* TODO: schedule adapter shutdown */
2444 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n"); 2421 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2445 } 2422 }
@@ -2534,11 +2511,11 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2534 2511
2535 /* Sync the DMA for the STATUS buffer so CPU is sure to get 2512 /* Sync the DMA for the STATUS buffer so CPU is sure to get
2536 * the correct values */ 2513 * the correct values */
2537 pci_dma_sync_single_for_cpu( 2514 pci_dma_sync_single_for_cpu(priv->pci_dev,
2538 priv->pci_dev, 2515 sq->nic +
2539 sq->nic + sizeof(struct ipw2100_status) * i, 2516 sizeof(struct ipw2100_status) * i,
2540 sizeof(struct ipw2100_status), 2517 sizeof(struct ipw2100_status),
2541 PCI_DMA_FROMDEVICE); 2518 PCI_DMA_FROMDEVICE);
2542 2519
2543 /* Sync the DMA for the RX buffer so CPU is sure to get 2520 /* Sync the DMA for the RX buffer so CPU is sure to get
2544 * the correct values */ 2521 * the correct values */
@@ -2552,8 +2529,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2552 } 2529 }
2553 2530
2554 u = packet->rxp; 2531 u = packet->rxp;
2555 frame_type = sq->drv[i].status_fields & 2532 frame_type = sq->drv[i].status_fields & STATUS_TYPE_MASK;
2556 STATUS_TYPE_MASK;
2557 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM; 2533 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
2558 stats.len = sq->drv[i].frame_size; 2534 stats.len = sq->drv[i].frame_size;
2559 2535
@@ -2562,16 +2538,14 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2562 stats.mask |= IEEE80211_STATMASK_RSSI; 2538 stats.mask |= IEEE80211_STATMASK_RSSI;
2563 stats.freq = IEEE80211_24GHZ_BAND; 2539 stats.freq = IEEE80211_24GHZ_BAND;
2564 2540
2565 IPW_DEBUG_RX( 2541 IPW_DEBUG_RX("%s: '%s' frame type received (%d).\n",
2566 "%s: '%s' frame type received (%d).\n", 2542 priv->net_dev->name, frame_types[frame_type],
2567 priv->net_dev->name, frame_types[frame_type], 2543 stats.len);
2568 stats.len);
2569 2544
2570 switch (frame_type) { 2545 switch (frame_type) {
2571 case COMMAND_STATUS_VAL: 2546 case COMMAND_STATUS_VAL:
2572 /* Reset Rx watchdog */ 2547 /* Reset Rx watchdog */
2573 isr_rx_complete_command( 2548 isr_rx_complete_command(priv, &u->rx_data.command);
2574 priv, &u->rx_data.command);
2575 break; 2549 break;
2576 2550
2577 case STATUS_CHANGE_VAL: 2551 case STATUS_CHANGE_VAL:
@@ -2588,12 +2562,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2588#endif 2562#endif
2589 if (stats.len < sizeof(u->rx_data.header)) 2563 if (stats.len < sizeof(u->rx_data.header))
2590 break; 2564 break;
2591 switch (WLAN_FC_GET_TYPE(u->rx_data.header. 2565 switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
2592 frame_ctl)) {
2593 case IEEE80211_FTYPE_MGMT: 2566 case IEEE80211_FTYPE_MGMT:
2594 ieee80211_rx_mgt(priv->ieee, 2567 ieee80211_rx_mgt(priv->ieee,
2595 &u->rx_data.header, 2568 &u->rx_data.header, &stats);
2596 &stats);
2597 break; 2569 break;
2598 2570
2599 case IEEE80211_FTYPE_CTL: 2571 case IEEE80211_FTYPE_CTL:
@@ -2607,7 +2579,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2607 break; 2579 break;
2608 } 2580 }
2609 2581
2610 increment: 2582 increment:
2611 /* clear status field associated with this RBD */ 2583 /* clear status field associated with this RBD */
2612 rxq->drv[i].status.info.field = 0; 2584 rxq->drv[i].status.info.field = 0;
2613 2585
@@ -2619,12 +2591,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2619 rxq->next = (i ? i : rxq->entries) - 1; 2591 rxq->next = (i ? i : rxq->entries) - 1;
2620 2592
2621 write_register(priv->net_dev, 2593 write_register(priv->net_dev,
2622 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, 2594 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, rxq->next);
2623 rxq->next);
2624 } 2595 }
2625} 2596}
2626 2597
2627
2628/* 2598/*
2629 * __ipw2100_tx_process 2599 * __ipw2100_tx_process
2630 * 2600 *
@@ -2667,7 +2637,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2667static inline int __ipw2100_tx_process(struct ipw2100_priv *priv) 2637static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2668{ 2638{
2669 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2639 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2670 struct ipw2100_bd *tbd; 2640 struct ipw2100_bd *tbd;
2671 struct list_head *element; 2641 struct list_head *element;
2672 struct ipw2100_tx_packet *packet; 2642 struct ipw2100_tx_packet *packet;
2673 int descriptors_used; 2643 int descriptors_used;
@@ -2680,7 +2650,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2680 element = priv->fw_pend_list.next; 2650 element = priv->fw_pend_list.next;
2681 2651
2682 packet = list_entry(element, struct ipw2100_tx_packet, list); 2652 packet = list_entry(element, struct ipw2100_tx_packet, list);
2683 tbd = &txq->drv[packet->index]; 2653 tbd = &txq->drv[packet->index];
2684 2654
2685 /* Determine how many TBD entries must be finished... */ 2655 /* Determine how many TBD entries must be finished... */
2686 switch (packet->type) { 2656 switch (packet->type) {
@@ -2693,14 +2663,14 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2693 case DATA: 2663 case DATA:
2694 /* DATA uses two slots; advance and loop position. */ 2664 /* DATA uses two slots; advance and loop position. */
2695 descriptors_used = tbd->num_fragments; 2665 descriptors_used = tbd->num_fragments;
2696 frag_num = tbd->num_fragments - 1; 2666 frag_num = tbd->num_fragments - 1;
2697 e = txq->oldest + frag_num; 2667 e = txq->oldest + frag_num;
2698 e %= txq->entries; 2668 e %= txq->entries;
2699 break; 2669 break;
2700 2670
2701 default: 2671 default:
2702 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n", 2672 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",
2703 priv->net_dev->name); 2673 priv->net_dev->name);
2704 return 0; 2674 return 0;
2705 } 2675 }
2706 2676
@@ -2716,13 +2686,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2716 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n", 2686 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",
2717 priv->net_dev->name); 2687 priv->net_dev->name);
2718 2688
2719 /* 2689 /*
2720 * txq->next is the index of the last packet written txq->oldest is 2690 * txq->next is the index of the last packet written txq->oldest is
2721 * the index of the r is the index of the next packet to be read by 2691 * the index of the r is the index of the next packet to be read by
2722 * firmware 2692 * firmware
2723 */ 2693 */
2724 2694
2725
2726 /* 2695 /*
2727 * Quick graphic to help you visualize the following 2696 * Quick graphic to help you visualize the following
2728 * if / else statement 2697 * if / else statement
@@ -2750,23 +2719,20 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2750#ifdef CONFIG_IPW_DEBUG 2719#ifdef CONFIG_IPW_DEBUG
2751 { 2720 {
2752 int i = txq->oldest; 2721 int i = txq->oldest;
2753 IPW_DEBUG_TX( 2722 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2754 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2723 &txq->drv[i],
2755 &txq->drv[i], 2724 (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
2756 (u32)(txq->nic + i * sizeof(struct ipw2100_bd)), 2725 txq->drv[i].host_addr, txq->drv[i].buf_length);
2757 txq->drv[i].host_addr,
2758 txq->drv[i].buf_length);
2759 2726
2760 if (packet->type == DATA) { 2727 if (packet->type == DATA) {
2761 i = (i + 1) % txq->entries; 2728 i = (i + 1) % txq->entries;
2762 2729
2763 IPW_DEBUG_TX( 2730 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2764 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2731 &txq->drv[i],
2765 &txq->drv[i], 2732 (u32) (txq->nic + i *
2766 (u32)(txq->nic + i * 2733 sizeof(struct ipw2100_bd)),
2767 sizeof(struct ipw2100_bd)), 2734 (u32) txq->drv[i].host_addr,
2768 (u32)txq->drv[i].host_addr, 2735 txq->drv[i].buf_length);
2769 txq->drv[i].buf_length);
2770 } 2736 }
2771 } 2737 }
2772#endif 2738#endif
@@ -2780,23 +2746,18 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2780 priv->net_dev->name, txq->oldest, packet->index); 2746 priv->net_dev->name, txq->oldest, packet->index);
2781 2747
2782 /* DATA packet; we have to unmap and free the SKB */ 2748 /* DATA packet; we have to unmap and free the SKB */
2783 priv->ieee->stats.tx_packets++;
2784 for (i = 0; i < frag_num; i++) { 2749 for (i = 0; i < frag_num; i++) {
2785 tbd = &txq->drv[(packet->index + 1 + i) % 2750 tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];
2786 txq->entries];
2787 2751
2788 IPW_DEBUG_TX( 2752 IPW_DEBUG_TX("TX%d P=%08x L=%d\n",
2789 "TX%d P=%08x L=%d\n", 2753 (packet->index + 1 + i) % txq->entries,
2790 (packet->index + 1 + i) % txq->entries, 2754 tbd->host_addr, tbd->buf_length);
2791 tbd->host_addr, tbd->buf_length);
2792 2755
2793 pci_unmap_single(priv->pci_dev, 2756 pci_unmap_single(priv->pci_dev,
2794 tbd->host_addr, 2757 tbd->host_addr,
2795 tbd->buf_length, 2758 tbd->buf_length, PCI_DMA_TODEVICE);
2796 PCI_DMA_TODEVICE);
2797 } 2759 }
2798 2760
2799 priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
2800 ieee80211_txb_free(packet->info.d_struct.txb); 2761 ieee80211_txb_free(packet->info.d_struct.txb);
2801 packet->info.d_struct.txb = NULL; 2762 packet->info.d_struct.txb = NULL;
2802 2763
@@ -2805,13 +2766,8 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2805 2766
2806 /* We have a free slot in the Tx queue, so wake up the 2767 /* We have a free slot in the Tx queue, so wake up the
2807 * transmit layer if it is stopped. */ 2768 * transmit layer if it is stopped. */
2808 if (priv->status & STATUS_ASSOCIATED && 2769 if (priv->status & STATUS_ASSOCIATED)
2809 netif_queue_stopped(priv->net_dev)) {
2810 IPW_DEBUG_INFO(KERN_INFO
2811 "%s: Waking net queue.\n",
2812 priv->net_dev->name);
2813 netif_wake_queue(priv->net_dev); 2770 netif_wake_queue(priv->net_dev);
2814 }
2815 2771
2816 /* A packet was processed by the hardware, so update the 2772 /* A packet was processed by the hardware, so update the
2817 * watchdog */ 2773 * watchdog */
@@ -2829,11 +2785,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2829#ifdef CONFIG_IPW_DEBUG 2785#ifdef CONFIG_IPW_DEBUG
2830 if (packet->info.c_struct.cmd->host_command_reg < 2786 if (packet->info.c_struct.cmd->host_command_reg <
2831 sizeof(command_types) / sizeof(*command_types)) 2787 sizeof(command_types) / sizeof(*command_types))
2832 IPW_DEBUG_TX( 2788 IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
2833 "Command '%s (%d)' processed: %d.\n", 2789 command_types[packet->info.c_struct.cmd->
2834 command_types[packet->info.c_struct.cmd->host_command_reg], 2790 host_command_reg],
2835 packet->info.c_struct.cmd->host_command_reg, 2791 packet->info.c_struct.cmd->
2836 packet->info.c_struct.cmd->cmd_status_reg); 2792 host_command_reg,
2793 packet->info.c_struct.cmd->cmd_status_reg);
2837#endif 2794#endif
2838 2795
2839 list_add_tail(element, &priv->msg_free_list); 2796 list_add_tail(element, &priv->msg_free_list);
@@ -2848,17 +2805,17 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2848 SET_STAT(&priv->txq_stat, txq->available); 2805 SET_STAT(&priv->txq_stat, txq->available);
2849 2806
2850 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n", 2807 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
2851 jiffies - packet->jiffy_start); 2808 jiffies - packet->jiffy_start);
2852 2809
2853 return (!list_empty(&priv->fw_pend_list)); 2810 return (!list_empty(&priv->fw_pend_list));
2854} 2811}
2855 2812
2856
2857static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv) 2813static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2858{ 2814{
2859 int i = 0; 2815 int i = 0;
2860 2816
2861 while (__ipw2100_tx_process(priv) && i < 200) i++; 2817 while (__ipw2100_tx_process(priv) && i < 200)
2818 i++;
2862 2819
2863 if (i == 200) { 2820 if (i == 200) {
2864 printk(KERN_WARNING DRV_NAME ": " 2821 printk(KERN_WARNING DRV_NAME ": "
@@ -2867,7 +2824,6 @@ static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2867 } 2824 }
2868} 2825}
2869 2826
2870
2871static void ipw2100_tx_send_commands(struct ipw2100_priv *priv) 2827static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2872{ 2828{
2873 struct list_head *element; 2829 struct list_head *element;
@@ -2892,13 +2848,12 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2892 list_del(element); 2848 list_del(element);
2893 DEC_STAT(&priv->msg_pend_stat); 2849 DEC_STAT(&priv->msg_pend_stat);
2894 2850
2895 packet = list_entry(element, 2851 packet = list_entry(element, struct ipw2100_tx_packet, list);
2896 struct ipw2100_tx_packet, list);
2897 2852
2898 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n", 2853 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
2899 &txq->drv[txq->next], 2854 &txq->drv[txq->next],
2900 (void*)(txq->nic + txq->next * 2855 (void *)(txq->nic + txq->next *
2901 sizeof(struct ipw2100_bd))); 2856 sizeof(struct ipw2100_bd)));
2902 2857
2903 packet->index = txq->next; 2858 packet->index = txq->next;
2904 2859
@@ -2911,8 +2866,8 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2911 * with f/w debug version */ 2866 * with f/w debug version */
2912 tbd->num_fragments = 1; 2867 tbd->num_fragments = 1;
2913 tbd->status.info.field = 2868 tbd->status.info.field =
2914 IPW_BD_STATUS_TX_FRAME_COMMAND | 2869 IPW_BD_STATUS_TX_FRAME_COMMAND |
2915 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2870 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
2916 2871
2917 /* update TBD queue counters */ 2872 /* update TBD queue counters */
2918 txq->next++; 2873 txq->next++;
@@ -2934,7 +2889,6 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2934 } 2889 }
2935} 2890}
2936 2891
2937
2938/* 2892/*
2939 * ipw2100_tx_send_data 2893 * ipw2100_tx_send_data
2940 * 2894 *
@@ -2946,7 +2900,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2946 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2900 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2947 struct ipw2100_bd *tbd; 2901 struct ipw2100_bd *tbd;
2948 int next = txq->next; 2902 int next = txq->next;
2949 int i = 0; 2903 int i = 0;
2950 struct ipw2100_data_header *ipw_hdr; 2904 struct ipw2100_data_header *ipw_hdr;
2951 struct ieee80211_hdr_3addr *hdr; 2905 struct ieee80211_hdr_3addr *hdr;
2952 2906
@@ -2958,20 +2912,18 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2958 * maintained between the r and w indexes 2912 * maintained between the r and w indexes
2959 */ 2913 */
2960 element = priv->tx_pend_list.next; 2914 element = priv->tx_pend_list.next;
2961 packet = list_entry(element, struct ipw2100_tx_packet, list); 2915 packet = list_entry(element, struct ipw2100_tx_packet, list);
2962 2916
2963 if (unlikely(1 + packet->info.d_struct.txb->nr_frags > 2917 if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
2964 IPW_MAX_BDS)) { 2918 IPW_MAX_BDS)) {
2965 /* TODO: Support merging buffers if more than 2919 /* TODO: Support merging buffers if more than
2966 * IPW_MAX_BDS are used */ 2920 * IPW_MAX_BDS are used */
2967 IPW_DEBUG_INFO( 2921 IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded. "
2968 "%s: Maximum BD theshold exceeded. " 2922 "Increase fragmentation level.\n",
2969 "Increase fragmentation level.\n", 2923 priv->net_dev->name);
2970 priv->net_dev->name);
2971 } 2924 }
2972 2925
2973 if (txq->available <= 3 + 2926 if (txq->available <= 3 + packet->info.d_struct.txb->nr_frags) {
2974 packet->info.d_struct.txb->nr_frags) {
2975 IPW_DEBUG_TX("no room in tx_queue\n"); 2927 IPW_DEBUG_TX("no room in tx_queue\n");
2976 break; 2928 break;
2977 } 2929 }
@@ -2985,7 +2937,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2985 2937
2986 ipw_hdr = packet->info.d_struct.data; 2938 ipw_hdr = packet->info.d_struct.data;
2987 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb-> 2939 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
2988 fragments[0]->data; 2940 fragments[0]->data;
2989 2941
2990 if (priv->ieee->iw_mode == IW_MODE_INFRA) { 2942 if (priv->ieee->iw_mode == IW_MODE_INFRA) {
2991 /* To DS: Addr1 = BSSID, Addr2 = SA, 2943 /* To DS: Addr1 = BSSID, Addr2 = SA,
@@ -3007,7 +2959,8 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3007 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted; 2959 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
3008 if (packet->info.d_struct.txb->nr_frags > 1) 2960 if (packet->info.d_struct.txb->nr_frags > 1)
3009 ipw_hdr->fragment_size = 2961 ipw_hdr->fragment_size =
3010 packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN; 2962 packet->info.d_struct.txb->frag_size -
2963 IEEE80211_3ADDR_LEN;
3011 else 2964 else
3012 ipw_hdr->fragment_size = 0; 2965 ipw_hdr->fragment_size = 0;
3013 2966
@@ -3015,54 +2968,53 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3015 tbd->buf_length = sizeof(struct ipw2100_data_header); 2968 tbd->buf_length = sizeof(struct ipw2100_data_header);
3016 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags; 2969 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
3017 tbd->status.info.field = 2970 tbd->status.info.field =
3018 IPW_BD_STATUS_TX_FRAME_802_3 | 2971 IPW_BD_STATUS_TX_FRAME_802_3 |
3019 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2972 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3020 txq->next++; 2973 txq->next++;
3021 txq->next %= txq->entries; 2974 txq->next %= txq->entries;
3022 2975
3023 IPW_DEBUG_TX( 2976 IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
3024 "data header tbd TX%d P=%08x L=%d\n", 2977 packet->index, tbd->host_addr, tbd->buf_length);
3025 packet->index, tbd->host_addr,
3026 tbd->buf_length);
3027#ifdef CONFIG_IPW_DEBUG 2978#ifdef CONFIG_IPW_DEBUG
3028 if (packet->info.d_struct.txb->nr_frags > 1) 2979 if (packet->info.d_struct.txb->nr_frags > 1)
3029 IPW_DEBUG_FRAG("fragment Tx: %d frames\n", 2980 IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
3030 packet->info.d_struct.txb->nr_frags); 2981 packet->info.d_struct.txb->nr_frags);
3031#endif 2982#endif
3032 2983
3033 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) { 2984 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
3034 tbd = &txq->drv[txq->next]; 2985 tbd = &txq->drv[txq->next];
3035 if (i == packet->info.d_struct.txb->nr_frags - 1) 2986 if (i == packet->info.d_struct.txb->nr_frags - 1)
3036 tbd->status.info.field = 2987 tbd->status.info.field =
3037 IPW_BD_STATUS_TX_FRAME_802_3 | 2988 IPW_BD_STATUS_TX_FRAME_802_3 |
3038 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2989 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
3039 else 2990 else
3040 tbd->status.info.field = 2991 tbd->status.info.field =
3041 IPW_BD_STATUS_TX_FRAME_802_3 | 2992 IPW_BD_STATUS_TX_FRAME_802_3 |
3042 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2993 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3043 2994
3044 tbd->buf_length = packet->info.d_struct.txb-> 2995 tbd->buf_length = packet->info.d_struct.txb->
3045 fragments[i]->len - IEEE80211_3ADDR_LEN; 2996 fragments[i]->len - IEEE80211_3ADDR_LEN;
3046 2997
3047 tbd->host_addr = pci_map_single( 2998 tbd->host_addr = pci_map_single(priv->pci_dev,
3048 priv->pci_dev, 2999 packet->info.d_struct.
3049 packet->info.d_struct.txb->fragments[i]->data + 3000 txb->fragments[i]->
3050 IEEE80211_3ADDR_LEN, 3001 data +
3051 tbd->buf_length, 3002 IEEE80211_3ADDR_LEN,
3052 PCI_DMA_TODEVICE); 3003 tbd->buf_length,
3004 PCI_DMA_TODEVICE);
3053 3005
3054 IPW_DEBUG_TX( 3006 IPW_DEBUG_TX("data frag tbd TX%d P=%08x L=%d\n",
3055 "data frag tbd TX%d P=%08x L=%d\n", 3007 txq->next, tbd->host_addr,
3056 txq->next, tbd->host_addr, tbd->buf_length); 3008 tbd->buf_length);
3057 3009
3058 pci_dma_sync_single_for_device( 3010 pci_dma_sync_single_for_device(priv->pci_dev,
3059 priv->pci_dev, tbd->host_addr, 3011 tbd->host_addr,
3060 tbd->buf_length, 3012 tbd->buf_length,
3061 PCI_DMA_TODEVICE); 3013 PCI_DMA_TODEVICE);
3062 3014
3063 txq->next++; 3015 txq->next++;
3064 txq->next %= txq->entries; 3016 txq->next %= txq->entries;
3065 } 3017 }
3066 3018
3067 txq->available -= 1 + packet->info.d_struct.txb->nr_frags; 3019 txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
3068 SET_STAT(&priv->txq_stat, txq->available); 3020 SET_STAT(&priv->txq_stat, txq->available);
@@ -3078,7 +3030,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3078 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX, 3030 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3079 txq->next); 3031 txq->next);
3080 } 3032 }
3081 return; 3033 return;
3082} 3034}
3083 3035
3084static void ipw2100_irq_tasklet(struct ipw2100_priv *priv) 3036static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
@@ -3106,11 +3058,9 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3106 3058
3107 if (inta & IPW2100_INTA_FATAL_ERROR) { 3059 if (inta & IPW2100_INTA_FATAL_ERROR) {
3108 printk(KERN_WARNING DRV_NAME 3060 printk(KERN_WARNING DRV_NAME
3109 ": Fatal interrupt. Scheduling firmware restart.\n"); 3061 ": Fatal interrupt. Scheduling firmware restart.\n");
3110 priv->inta_other++; 3062 priv->inta_other++;
3111 write_register( 3063 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FATAL_ERROR);
3112 dev, IPW_REG_INTA,
3113 IPW2100_INTA_FATAL_ERROR);
3114 3064
3115 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error); 3065 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
3116 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n", 3066 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
@@ -3125,11 +3075,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3125 } 3075 }
3126 3076
3127 if (inta & IPW2100_INTA_PARITY_ERROR) { 3077 if (inta & IPW2100_INTA_PARITY_ERROR) {
3128 printk(KERN_ERR DRV_NAME ": ***** PARITY ERROR INTERRUPT !!!! \n"); 3078 printk(KERN_ERR DRV_NAME
3079 ": ***** PARITY ERROR INTERRUPT !!!! \n");
3129 priv->inta_other++; 3080 priv->inta_other++;
3130 write_register( 3081 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
3131 dev, IPW_REG_INTA,
3132 IPW2100_INTA_PARITY_ERROR);
3133 } 3082 }
3134 3083
3135 if (inta & IPW2100_INTA_RX_TRANSFER) { 3084 if (inta & IPW2100_INTA_RX_TRANSFER) {
@@ -3137,9 +3086,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3137 3086
3138 priv->rx_interrupts++; 3087 priv->rx_interrupts++;
3139 3088
3140 write_register( 3089 write_register(dev, IPW_REG_INTA, IPW2100_INTA_RX_TRANSFER);
3141 dev, IPW_REG_INTA,
3142 IPW2100_INTA_RX_TRANSFER);
3143 3090
3144 __ipw2100_rx_process(priv); 3091 __ipw2100_rx_process(priv);
3145 __ipw2100_tx_complete(priv); 3092 __ipw2100_tx_complete(priv);
@@ -3150,8 +3097,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3150 3097
3151 priv->tx_interrupts++; 3098 priv->tx_interrupts++;
3152 3099
3153 write_register(dev, IPW_REG_INTA, 3100 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_TRANSFER);
3154 IPW2100_INTA_TX_TRANSFER);
3155 3101
3156 __ipw2100_tx_complete(priv); 3102 __ipw2100_tx_complete(priv);
3157 ipw2100_tx_send_commands(priv); 3103 ipw2100_tx_send_commands(priv);
@@ -3161,9 +3107,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3161 if (inta & IPW2100_INTA_TX_COMPLETE) { 3107 if (inta & IPW2100_INTA_TX_COMPLETE) {
3162 IPW_DEBUG_ISR("TX complete\n"); 3108 IPW_DEBUG_ISR("TX complete\n");
3163 priv->inta_other++; 3109 priv->inta_other++;
3164 write_register( 3110 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_COMPLETE);
3165 dev, IPW_REG_INTA,
3166 IPW2100_INTA_TX_COMPLETE);
3167 3111
3168 __ipw2100_tx_complete(priv); 3112 __ipw2100_tx_complete(priv);
3169 } 3113 }
@@ -3171,9 +3115,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3171 if (inta & IPW2100_INTA_EVENT_INTERRUPT) { 3115 if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
3172 /* ipw2100_handle_event(dev); */ 3116 /* ipw2100_handle_event(dev); */
3173 priv->inta_other++; 3117 priv->inta_other++;
3174 write_register( 3118 write_register(dev, IPW_REG_INTA, IPW2100_INTA_EVENT_INTERRUPT);
3175 dev, IPW_REG_INTA,
3176 IPW2100_INTA_EVENT_INTERRUPT);
3177 } 3119 }
3178 3120
3179 if (inta & IPW2100_INTA_FW_INIT_DONE) { 3121 if (inta & IPW2100_INTA_FW_INIT_DONE) {
@@ -3183,30 +3125,25 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3183 read_register(dev, IPW_REG_INTA, &tmp); 3125 read_register(dev, IPW_REG_INTA, &tmp);
3184 if (tmp & (IPW2100_INTA_FATAL_ERROR | 3126 if (tmp & (IPW2100_INTA_FATAL_ERROR |
3185 IPW2100_INTA_PARITY_ERROR)) { 3127 IPW2100_INTA_PARITY_ERROR)) {
3186 write_register( 3128 write_register(dev, IPW_REG_INTA,
3187 dev, IPW_REG_INTA, 3129 IPW2100_INTA_FATAL_ERROR |
3188 IPW2100_INTA_FATAL_ERROR | 3130 IPW2100_INTA_PARITY_ERROR);
3189 IPW2100_INTA_PARITY_ERROR);
3190 } 3131 }
3191 3132
3192 write_register(dev, IPW_REG_INTA, 3133 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FW_INIT_DONE);
3193 IPW2100_INTA_FW_INIT_DONE);
3194 } 3134 }
3195 3135
3196 if (inta & IPW2100_INTA_STATUS_CHANGE) { 3136 if (inta & IPW2100_INTA_STATUS_CHANGE) {
3197 IPW_DEBUG_ISR("Status change interrupt\n"); 3137 IPW_DEBUG_ISR("Status change interrupt\n");
3198 priv->inta_other++; 3138 priv->inta_other++;
3199 write_register( 3139 write_register(dev, IPW_REG_INTA, IPW2100_INTA_STATUS_CHANGE);
3200 dev, IPW_REG_INTA,
3201 IPW2100_INTA_STATUS_CHANGE);
3202 } 3140 }
3203 3141
3204 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) { 3142 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
3205 IPW_DEBUG_ISR("slave host mode interrupt\n"); 3143 IPW_DEBUG_ISR("slave host mode interrupt\n");
3206 priv->inta_other++; 3144 priv->inta_other++;
3207 write_register( 3145 write_register(dev, IPW_REG_INTA,
3208 dev, IPW_REG_INTA, 3146 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3209 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3210 } 3147 }
3211 3148
3212 priv->in_isr--; 3149 priv->in_isr--;
@@ -3217,9 +3154,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3217 IPW_DEBUG_ISR("exit\n"); 3154 IPW_DEBUG_ISR("exit\n");
3218} 3155}
3219 3156
3220 3157static irqreturn_t ipw2100_interrupt(int irq, void *data, struct pt_regs *regs)
3221static irqreturn_t ipw2100_interrupt(int irq, void *data,
3222 struct pt_regs *regs)
3223{ 3158{
3224 struct ipw2100_priv *priv = data; 3159 struct ipw2100_priv *priv = data;
3225 u32 inta, inta_mask; 3160 u32 inta, inta_mask;
@@ -3227,7 +3162,7 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3227 if (!data) 3162 if (!data)
3228 return IRQ_NONE; 3163 return IRQ_NONE;
3229 3164
3230 spin_lock(&priv->low_lock); 3165 spin_lock(&priv->low_lock);
3231 3166
3232 /* We check to see if we should be ignoring interrupts before 3167 /* We check to see if we should be ignoring interrupts before
3233 * we touch the hardware. During ucode load if we try and handle 3168 * we touch the hardware. During ucode load if we try and handle
@@ -3261,10 +3196,10 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3261 ipw2100_disable_interrupts(priv); 3196 ipw2100_disable_interrupts(priv);
3262 3197
3263 tasklet_schedule(&priv->irq_tasklet); 3198 tasklet_schedule(&priv->irq_tasklet);
3264 spin_unlock(&priv->low_lock); 3199 spin_unlock(&priv->low_lock);
3265 3200
3266 return IRQ_HANDLED; 3201 return IRQ_HANDLED;
3267 none: 3202 none:
3268 spin_unlock(&priv->low_lock); 3203 spin_unlock(&priv->low_lock);
3269 return IRQ_NONE; 3204 return IRQ_NONE;
3270} 3205}
@@ -3294,10 +3229,8 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3294 3229
3295 packet->info.d_struct.txb = txb; 3230 packet->info.d_struct.txb = txb;
3296 3231
3297 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", 3232 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", txb->fragments[0]->len);
3298 txb->fragments[0]->len); 3233 printk_buf(IPW_DL_TX, txb->fragments[0]->data, txb->fragments[0]->len);
3299 printk_buf(IPW_DL_TX, txb->fragments[0]->data,
3300 txb->fragments[0]->len);
3301 3234
3302 packet->jiffy_start = jiffies; 3235 packet->jiffy_start = jiffies;
3303 3236
@@ -3312,22 +3245,23 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3312 spin_unlock_irqrestore(&priv->low_lock, flags); 3245 spin_unlock_irqrestore(&priv->low_lock, flags);
3313 return 0; 3246 return 0;
3314 3247
3315 fail_unlock: 3248 fail_unlock:
3316 netif_stop_queue(dev); 3249 netif_stop_queue(dev);
3317 spin_unlock_irqrestore(&priv->low_lock, flags); 3250 spin_unlock_irqrestore(&priv->low_lock, flags);
3318 return 1; 3251 return 1;
3319} 3252}
3320 3253
3321
3322static int ipw2100_msg_allocate(struct ipw2100_priv *priv) 3254static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3323{ 3255{
3324 int i, j, err = -EINVAL; 3256 int i, j, err = -EINVAL;
3325 void *v; 3257 void *v;
3326 dma_addr_t p; 3258 dma_addr_t p;
3327 3259
3328 priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc( 3260 priv->msg_buffers =
3329 IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), 3261 (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE *
3330 GFP_KERNEL); 3262 sizeof(struct
3263 ipw2100_tx_packet),
3264 GFP_KERNEL);
3331 if (!priv->msg_buffers) { 3265 if (!priv->msg_buffers) {
3332 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " 3266 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
3333 "buffers.\n", priv->net_dev->name); 3267 "buffers.\n", priv->net_dev->name);
@@ -3335,15 +3269,12 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3335 } 3269 }
3336 3270
3337 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { 3271 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3338 v = pci_alloc_consistent( 3272 v = pci_alloc_consistent(priv->pci_dev,
3339 priv->pci_dev, 3273 sizeof(struct ipw2100_cmd_header), &p);
3340 sizeof(struct ipw2100_cmd_header),
3341 &p);
3342 if (!v) { 3274 if (!v) {
3343 printk(KERN_ERR DRV_NAME ": " 3275 printk(KERN_ERR DRV_NAME ": "
3344 "%s: PCI alloc failed for msg " 3276 "%s: PCI alloc failed for msg "
3345 "buffers.\n", 3277 "buffers.\n", priv->net_dev->name);
3346 priv->net_dev->name);
3347 err = -ENOMEM; 3278 err = -ENOMEM;
3348 break; 3279 break;
3349 } 3280 }
@@ -3352,7 +3283,7 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3352 3283
3353 priv->msg_buffers[i].type = COMMAND; 3284 priv->msg_buffers[i].type = COMMAND;
3354 priv->msg_buffers[i].info.c_struct.cmd = 3285 priv->msg_buffers[i].info.c_struct.cmd =
3355 (struct ipw2100_cmd_header*)v; 3286 (struct ipw2100_cmd_header *)v;
3356 priv->msg_buffers[i].info.c_struct.cmd_phys = p; 3287 priv->msg_buffers[i].info.c_struct.cmd_phys = p;
3357 } 3288 }
3358 3289
@@ -3360,11 +3291,11 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3360 return 0; 3291 return 0;
3361 3292
3362 for (j = 0; j < i; j++) { 3293 for (j = 0; j < i; j++) {
3363 pci_free_consistent( 3294 pci_free_consistent(priv->pci_dev,
3364 priv->pci_dev, 3295 sizeof(struct ipw2100_cmd_header),
3365 sizeof(struct ipw2100_cmd_header), 3296 priv->msg_buffers[j].info.c_struct.cmd,
3366 priv->msg_buffers[j].info.c_struct.cmd, 3297 priv->msg_buffers[j].info.c_struct.
3367 priv->msg_buffers[j].info.c_struct.cmd_phys); 3298 cmd_phys);
3368 } 3299 }
3369 3300
3370 kfree(priv->msg_buffers); 3301 kfree(priv->msg_buffers);
@@ -3398,7 +3329,8 @@ static void ipw2100_msg_free(struct ipw2100_priv *priv)
3398 pci_free_consistent(priv->pci_dev, 3329 pci_free_consistent(priv->pci_dev,
3399 sizeof(struct ipw2100_cmd_header), 3330 sizeof(struct ipw2100_cmd_header),
3400 priv->msg_buffers[i].info.c_struct.cmd, 3331 priv->msg_buffers[i].info.c_struct.cmd,
3401 priv->msg_buffers[i].info.c_struct.cmd_phys); 3332 priv->msg_buffers[i].info.c_struct.
3333 cmd_phys);
3402 } 3334 }
3403 3335
3404 kfree(priv->msg_buffers); 3336 kfree(priv->msg_buffers);
@@ -3424,6 +3356,7 @@ static ssize_t show_pci(struct device *d, struct device_attribute *attr,
3424 3356
3425 return out - buf; 3357 return out - buf;
3426} 3358}
3359
3427static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL); 3360static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
3428 3361
3429static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 3362static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
@@ -3432,209 +3365,269 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
3432 struct ipw2100_priv *p = d->driver_data; 3365 struct ipw2100_priv *p = d->driver_data;
3433 return sprintf(buf, "0x%08x\n", (int)p->config); 3366 return sprintf(buf, "0x%08x\n", (int)p->config);
3434} 3367}
3368
3435static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 3369static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
3436 3370
3437static ssize_t show_status(struct device *d, struct device_attribute *attr, 3371static ssize_t show_status(struct device *d, struct device_attribute *attr,
3438 char *buf) 3372 char *buf)
3439{ 3373{
3440 struct ipw2100_priv *p = d->driver_data; 3374 struct ipw2100_priv *p = d->driver_data;
3441 return sprintf(buf, "0x%08x\n", (int)p->status); 3375 return sprintf(buf, "0x%08x\n", (int)p->status);
3442} 3376}
3377
3443static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 3378static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3444 3379
3445static ssize_t show_capability(struct device *d, struct device_attribute *attr, 3380static ssize_t show_capability(struct device *d, struct device_attribute *attr,
3446 char *buf) 3381 char *buf)
3447{ 3382{
3448 struct ipw2100_priv *p = d->driver_data; 3383 struct ipw2100_priv *p = d->driver_data;
3449 return sprintf(buf, "0x%08x\n", (int)p->capability); 3384 return sprintf(buf, "0x%08x\n", (int)p->capability);
3450} 3385}
3451static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3452 3386
3387static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3453 3388
3454#define IPW2100_REG(x) { IPW_ ##x, #x } 3389#define IPW2100_REG(x) { IPW_ ##x, #x }
3455static const struct { 3390static const struct {
3456 u32 addr; 3391 u32 addr;
3457 const char *name; 3392 const char *name;
3458} hw_data[] = { 3393} hw_data[] = {
3459 IPW2100_REG(REG_GP_CNTRL), 3394IPW2100_REG(REG_GP_CNTRL),
3460 IPW2100_REG(REG_GPIO), 3395 IPW2100_REG(REG_GPIO),
3461 IPW2100_REG(REG_INTA), 3396 IPW2100_REG(REG_INTA),
3462 IPW2100_REG(REG_INTA_MASK), 3397 IPW2100_REG(REG_INTA_MASK), IPW2100_REG(REG_RESET_REG),};
3463 IPW2100_REG(REG_RESET_REG),
3464};
3465#define IPW2100_NIC(x, s) { x, #x, s } 3398#define IPW2100_NIC(x, s) { x, #x, s }
3466static const struct { 3399static const struct {
3467 u32 addr; 3400 u32 addr;
3468 const char *name; 3401 const char *name;
3469 size_t size; 3402 size_t size;
3470} nic_data[] = { 3403} nic_data[] = {
3471 IPW2100_NIC(IPW2100_CONTROL_REG, 2), 3404IPW2100_NIC(IPW2100_CONTROL_REG, 2),
3472 IPW2100_NIC(0x210014, 1), 3405 IPW2100_NIC(0x210014, 1), IPW2100_NIC(0x210000, 1),};
3473 IPW2100_NIC(0x210000, 1),
3474};
3475#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d } 3406#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
3476static const struct { 3407static const struct {
3477 u8 index; 3408 u8 index;
3478 const char *name; 3409 const char *name;
3479 const char *desc; 3410 const char *desc;
3480} ord_data[] = { 3411} ord_data[] = {
3481 IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"), 3412IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
3482 IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"), 3413 IPW2100_ORD(STAT_TX_HOST_COMPLETE,
3483 IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"), 3414 "successful Host Tx's (MSDU)"),
3484 IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"), 3415 IPW2100_ORD(STAT_TX_DIR_DATA,
3485 IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"), 3416 "successful Directed Tx's (MSDU)"),
3486 IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"), 3417 IPW2100_ORD(STAT_TX_DIR_DATA1,
3487 IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"), 3418 "successful Directed Tx's (MSDU) @ 1MB"),
3488 IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"), 3419 IPW2100_ORD(STAT_TX_DIR_DATA2,
3489 IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"), 3420 "successful Directed Tx's (MSDU) @ 2MB"),
3490 IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"), 3421 IPW2100_ORD(STAT_TX_DIR_DATA5_5,
3491 IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"), 3422 "successful Directed Tx's (MSDU) @ 5_5MB"),
3492 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"), 3423 IPW2100_ORD(STAT_TX_DIR_DATA11,
3493 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"), 3424 "successful Directed Tx's (MSDU) @ 11MB"),
3494 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"), 3425 IPW2100_ORD(STAT_TX_NODIR_DATA1,
3495 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"), 3426 "successful Non_Directed Tx's (MSDU) @ 1MB"),
3496 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"), 3427 IPW2100_ORD(STAT_TX_NODIR_DATA2,
3497 IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"), 3428 "successful Non_Directed Tx's (MSDU) @ 2MB"),
3498 IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"), 3429 IPW2100_ORD(STAT_TX_NODIR_DATA5_5,
3499 IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"), 3430 "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
3500 IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"), 3431 IPW2100_ORD(STAT_TX_NODIR_DATA11,
3501 IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"), 3432 "successful Non_Directed Tx's (MSDU) @ 11MB"),
3502 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"), 3433 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
3503 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"), 3434 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
3504 IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"), 3435 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
3505 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"), 3436 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
3506 IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"), 3437 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
3507 IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"), 3438 IPW2100_ORD(STAT_TX_ASSN_RESP,
3508 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"), 3439 "successful Association response Tx's"),
3509 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"), 3440 IPW2100_ORD(STAT_TX_REASSN,
3510 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"), 3441 "successful Reassociation Tx's"),
3511 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"), 3442 IPW2100_ORD(STAT_TX_REASSN_RESP,
3512 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"), 3443 "successful Reassociation response Tx's"),
3513 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"), 3444 IPW2100_ORD(STAT_TX_PROBE,
3514 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"), 3445 "probes successfully transmitted"),
3515 IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"), 3446 IPW2100_ORD(STAT_TX_PROBE_RESP,
3516 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"), 3447 "probe responses successfully transmitted"),
3517 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"), 3448 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
3518 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"), 3449 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
3519 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"), 3450 IPW2100_ORD(STAT_TX_DISASSN,
3520 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"), 3451 "successful Disassociation TX"),
3521 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"), 3452 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
3522 IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"), 3453 IPW2100_ORD(STAT_TX_DEAUTH,
3523 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"), 3454 "successful Deauthentication TX"),
3524 IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"), 3455 IPW2100_ORD(STAT_TX_TOTAL_BYTES,
3525 IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"), 3456 "Total successful Tx data bytes"),
3526 IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"), 3457 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
3527 IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"), 3458 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
3528 IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"), 3459 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
3529 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"), 3460 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
3530 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), 3461 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
3531 IPW2100_ORD(STAT_RX_CTS, "Rx CTS"), 3462 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
3532 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"), 3463 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,
3533 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"), 3464 "times max tries in a hop failed"),
3534 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"), 3465 IPW2100_ORD(STAT_TX_DISASSN_FAIL,
3535 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"), 3466 "times disassociation failed"),
3536 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"), 3467 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
3537 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"), 3468 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
3538 IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"), 3469 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
3539 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"), 3470 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
3540 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"), 3471 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
3541 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"), 3472 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
3542 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"), 3473 IPW2100_ORD(STAT_RX_DIR_DATA5_5,
3543 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"), 3474 "directed packets at 5.5MB"),
3544 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"), 3475 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
3545 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"), 3476 IPW2100_ORD(STAT_RX_NODIR_DATA, "nondirected packets"),
3546 IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"), 3477 IPW2100_ORD(STAT_RX_NODIR_DATA1,
3547 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"), 3478 "nondirected packets at 1MB"),
3548 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"), 3479 IPW2100_ORD(STAT_RX_NODIR_DATA2,
3549 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"), 3480 "nondirected packets at 2MB"),
3550 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"), 3481 IPW2100_ORD(STAT_RX_NODIR_DATA5_5,
3551 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"), 3482 "nondirected packets at 5.5MB"),
3552 IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"), 3483 IPW2100_ORD(STAT_RX_NODIR_DATA11,
3553 IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"), 3484 "nondirected packets at 11MB"),
3554 IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"), 3485 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
3555 IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"), 3486 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), IPW2100_ORD(STAT_RX_CTS,
3556 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"), 3487 "Rx CTS"),
3557 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"), 3488 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
3558 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"), 3489 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
3559 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"), 3490 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
3560 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"), 3491 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
3561 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"), 3492 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
3562 IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"), 3493 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
3563 IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"), 3494 IPW2100_ORD(STAT_RX_REASSN_RESP,
3564 IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"), 3495 "Reassociation response Rx's"),
3565 IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"), 3496 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
3566 IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"), 3497 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
3567 IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"), 3498 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
3568 IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"), 3499 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
3569 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"), 3500 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
3570 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"), 3501 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
3571 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"), 3502 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
3572 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"), 3503 IPW2100_ORD(STAT_RX_TOTAL_BYTES,
3573 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"), 3504 "Total rx data bytes received"),
3574 IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"), 3505 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
3575 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"), 3506 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
3576 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"), 3507 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
3577 IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"), 3508 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
3578 IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"), 3509 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
3579 IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"), 3510 IPW2100_ORD(STAT_RX_DUPLICATE1,
3580 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"), 3511 "duplicate rx packets at 1MB"),
3581 IPW2100_ORD(STAT_AP_ASSNS, "associations"), 3512 IPW2100_ORD(STAT_RX_DUPLICATE2,
3582 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"), 3513 "duplicate rx packets at 2MB"),
3583 IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"), 3514 IPW2100_ORD(STAT_RX_DUPLICATE5_5,
3584 IPW2100_ORD(STAT_FULL_SCANS, "full scans"), 3515 "duplicate rx packets at 5.5MB"),
3585 IPW2100_ORD(CARD_DISABLED, "Card Disabled"), 3516 IPW2100_ORD(STAT_RX_DUPLICATE11,
3586 IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"), 3517 "duplicate rx packets at 11MB"),
3587 IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"), 3518 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
3588 IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"), 3519 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
3589 IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"), 3520 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
3590 IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"), 3521 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
3591 IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"), 3522 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL,
3592 IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"), 3523 "rx frames with invalid protocol"),
3593 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"), 3524 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
3594 IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"), 3525 IPW2100_ORD(STAT_RX_NO_BUFFER,
3595 IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"), 3526 "rx frames rejected due to no buffer"),
3596 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"), 3527 IPW2100_ORD(STAT_RX_MISSING_FRAG,
3597 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"), 3528 "rx frames dropped due to missing fragment"),
3598 IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"), 3529 IPW2100_ORD(STAT_RX_ORPHAN_FRAG,
3599 IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"), 3530 "rx frames dropped due to non-sequential fragment"),
3600 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"), 3531 IPW2100_ORD(STAT_RX_ORPHAN_FRAME,
3601 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"), 3532 "rx frames dropped due to unmatched 1st frame"),
3602 IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"), 3533 IPW2100_ORD(STAT_RX_FRAG_AGEOUT,
3603 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"), 3534 "rx frames dropped due to uncompleted frame"),
3604 IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"), 3535 IPW2100_ORD(STAT_RX_ICV_ERRORS,
3605 IPW2100_ORD(RTC_TIME, "current RTC time"), 3536 "ICV errors during decryption"),
3606 IPW2100_ORD(PORT_TYPE, "operating mode"), 3537 IPW2100_ORD(STAT_PSP_SUSPENSION, "times adapter suspended"),
3607 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"), 3538 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
3608 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"), 3539 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT,
3609 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"), 3540 "poll response timeouts"),
3610 IPW2100_ORD(BASIC_RATES, "basic tx rates"), 3541 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT,
3611 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"), 3542 "timeouts waiting for last {broad,multi}cast pkt"),
3612 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"), 3543 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
3613 IPW2100_ORD(CAPABILITIES, "Management frame capability field"), 3544 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
3614 IPW2100_ORD(AUTH_TYPE, "Type of authentication"), 3545 IPW2100_ORD(STAT_PSP_STATION_ID, "PSP Station ID"),
3615 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"), 3546 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
3616 IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"), 3547 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,
3617 IPW2100_ORD(INT_MODE, "International mode"), 3548 "current calculation of % missed beacons"),
3618 IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"), 3549 IPW2100_ORD(STAT_PERCENT_RETRIES,
3619 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"), 3550 "current calculation of % missed tx retries"),
3620 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"), 3551 IPW2100_ORD(ASSOCIATED_AP_PTR,
3621 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"), 3552 "0 if not associated, else pointer to AP table entry"),
3622 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"), 3553 IPW2100_ORD(AVAILABLE_AP_CNT,
3623 IPW2100_ORD(MAC_VERSION, "MAC Version"), 3554 "AP's decsribed in the AP table"),
3624 IPW2100_ORD(MAC_REVISION, "MAC Revision"), 3555 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
3625 IPW2100_ORD(RADIO_VERSION, "Radio Version"), 3556 IPW2100_ORD(STAT_AP_ASSNS, "associations"),
3626 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"), 3557 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
3627 IPW2100_ORD(UCODE_VERSION, "Ucode Version"), 3558 IPW2100_ORD(STAT_ASSN_RESP_FAIL,
3628}; 3559 "failures due to response fail"),
3629 3560 IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
3561 IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
3562 IPW2100_ORD(STAT_ROAM_INHIBIT,
3563 "times roaming was inhibited due to activity"),
3564 IPW2100_ORD(RSSI_AT_ASSN,
3565 "RSSI of associated AP at time of association"),
3566 IPW2100_ORD(STAT_ASSN_CAUSE1,
3567 "reassociation: no probe response or TX on hop"),
3568 IPW2100_ORD(STAT_ASSN_CAUSE2,
3569 "reassociation: poor tx/rx quality"),
3570 IPW2100_ORD(STAT_ASSN_CAUSE3,
3571 "reassociation: tx/rx quality (excessive AP load"),
3572 IPW2100_ORD(STAT_ASSN_CAUSE4,
3573 "reassociation: AP RSSI level"),
3574 IPW2100_ORD(STAT_ASSN_CAUSE5,
3575 "reassociations due to load leveling"),
3576 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
3577 IPW2100_ORD(STAT_AUTH_RESP_FAIL,
3578 "times authentication response failed"),
3579 IPW2100_ORD(STATION_TABLE_CNT,
3580 "entries in association table"),
3581 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
3582 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
3583 IPW2100_ORD(COUNTRY_CODE,
3584 "IEEE country code as recv'd from beacon"),
3585 IPW2100_ORD(COUNTRY_CHANNELS,
3586 "channels suported by country"),
3587 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
3588 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
3589 IPW2100_ORD(ANTENNA_DIVERSITY,
3590 "TRUE if antenna diversity is disabled"),
3591 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
3592 IPW2100_ORD(OUR_FREQ,
3593 "current radio freq lower digits - channel ID"),
3594 IPW2100_ORD(RTC_TIME, "current RTC time"),
3595 IPW2100_ORD(PORT_TYPE, "operating mode"),
3596 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
3597 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
3598 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
3599 IPW2100_ORD(BASIC_RATES, "basic tx rates"),
3600 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
3601 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
3602 IPW2100_ORD(CAPABILITIES,
3603 "Management frame capability field"),
3604 IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
3605 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
3606 IPW2100_ORD(RTS_THRESHOLD,
3607 "Min packet length for RTS handshaking"),
3608 IPW2100_ORD(INT_MODE, "International mode"),
3609 IPW2100_ORD(FRAGMENTATION_THRESHOLD,
3610 "protocol frag threshold"),
3611 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
3612 "EEPROM offset in SRAM"),
3613 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE,
3614 "EEPROM size in SRAM"),
3615 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
3616 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS,
3617 "EEPROM IBSS 11b channel set"),
3618 IPW2100_ORD(MAC_VERSION, "MAC Version"),
3619 IPW2100_ORD(MAC_REVISION, "MAC Revision"),
3620 IPW2100_ORD(RADIO_VERSION, "Radio Version"),
3621 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
3622 IPW2100_ORD(UCODE_VERSION, "Ucode Version"),};
3630 3623
3631static ssize_t show_registers(struct device *d, struct device_attribute *attr, 3624static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3632 char *buf) 3625 char *buf)
3633{ 3626{
3634 int i; 3627 int i;
3635 struct ipw2100_priv *priv = dev_get_drvdata(d); 3628 struct ipw2100_priv *priv = dev_get_drvdata(d);
3636 struct net_device *dev = priv->net_dev; 3629 struct net_device *dev = priv->net_dev;
3637 char * out = buf; 3630 char *out = buf;
3638 u32 val = 0; 3631 u32 val = 0;
3639 3632
3640 out += sprintf(out, "%30s [Address ] : Hex\n", "Register"); 3633 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
@@ -3647,15 +3640,15 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3647 3640
3648 return out - buf; 3641 return out - buf;
3649} 3642}
3650static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3651 3643
3644static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3652 3645
3653static ssize_t show_hardware(struct device *d, struct device_attribute *attr, 3646static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3654 char *buf) 3647 char *buf)
3655{ 3648{
3656 struct ipw2100_priv *priv = dev_get_drvdata(d); 3649 struct ipw2100_priv *priv = dev_get_drvdata(d);
3657 struct net_device *dev = priv->net_dev; 3650 struct net_device *dev = priv->net_dev;
3658 char * out = buf; 3651 char *out = buf;
3659 int i; 3652 int i;
3660 3653
3661 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry"); 3654 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
@@ -3688,11 +3681,11 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3688 } 3681 }
3689 return out - buf; 3682 return out - buf;
3690} 3683}
3691static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3692 3684
3685static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3693 3686
3694static ssize_t show_memory(struct device *d, struct device_attribute *attr, 3687static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3695 char *buf) 3688 char *buf)
3696{ 3689{
3697 struct ipw2100_priv *priv = dev_get_drvdata(d); 3690 struct ipw2100_priv *priv = dev_get_drvdata(d);
3698 struct net_device *dev = priv->net_dev; 3691 struct net_device *dev = priv->net_dev;
@@ -3708,10 +3701,13 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3708 /* sysfs provides us PAGE_SIZE buffer */ 3701 /* sysfs provides us PAGE_SIZE buffer */
3709 while (len < PAGE_SIZE - 128 && loop < 0x30000) { 3702 while (len < PAGE_SIZE - 128 && loop < 0x30000) {
3710 3703
3711 if (priv->snapshot[0]) for (i = 0; i < 4; i++) 3704 if (priv->snapshot[0])
3712 buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4); 3705 for (i = 0; i < 4; i++)
3713 else for (i = 0; i < 4; i++) 3706 buffer[i] =
3714 read_nic_dword(dev, loop + i * 4, &buffer[i]); 3707 *(u32 *) SNAPSHOT_ADDR(loop + i * 4);
3708 else
3709 for (i = 0; i < 4; i++)
3710 read_nic_dword(dev, loop + i * 4, &buffer[i]);
3715 3711
3716 if (priv->dump_raw) 3712 if (priv->dump_raw)
3717 len += sprintf(buf + len, 3713 len += sprintf(buf + len,
@@ -3719,26 +3715,26 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3719 "%c%c%c%c" 3715 "%c%c%c%c"
3720 "%c%c%c%c" 3716 "%c%c%c%c"
3721 "%c%c%c%c", 3717 "%c%c%c%c",
3722 ((u8*)buffer)[0x0], 3718 ((u8 *) buffer)[0x0],
3723 ((u8*)buffer)[0x1], 3719 ((u8 *) buffer)[0x1],
3724 ((u8*)buffer)[0x2], 3720 ((u8 *) buffer)[0x2],
3725 ((u8*)buffer)[0x3], 3721 ((u8 *) buffer)[0x3],
3726 ((u8*)buffer)[0x4], 3722 ((u8 *) buffer)[0x4],
3727 ((u8*)buffer)[0x5], 3723 ((u8 *) buffer)[0x5],
3728 ((u8*)buffer)[0x6], 3724 ((u8 *) buffer)[0x6],
3729 ((u8*)buffer)[0x7], 3725 ((u8 *) buffer)[0x7],
3730 ((u8*)buffer)[0x8], 3726 ((u8 *) buffer)[0x8],
3731 ((u8*)buffer)[0x9], 3727 ((u8 *) buffer)[0x9],
3732 ((u8*)buffer)[0xa], 3728 ((u8 *) buffer)[0xa],
3733 ((u8*)buffer)[0xb], 3729 ((u8 *) buffer)[0xb],
3734 ((u8*)buffer)[0xc], 3730 ((u8 *) buffer)[0xc],
3735 ((u8*)buffer)[0xd], 3731 ((u8 *) buffer)[0xd],
3736 ((u8*)buffer)[0xe], 3732 ((u8 *) buffer)[0xe],
3737 ((u8*)buffer)[0xf]); 3733 ((u8 *) buffer)[0xf]);
3738 else 3734 else
3739 len += sprintf(buf + len, "%s\n", 3735 len += sprintf(buf + len, "%s\n",
3740 snprint_line(line, sizeof(line), 3736 snprint_line(line, sizeof(line),
3741 (u8*)buffer, 16, loop)); 3737 (u8 *) buffer, 16, loop));
3742 loop += 16; 3738 loop += 16;
3743 } 3739 }
3744 3740
@@ -3746,44 +3742,44 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3746} 3742}
3747 3743
3748static ssize_t store_memory(struct device *d, struct device_attribute *attr, 3744static ssize_t store_memory(struct device *d, struct device_attribute *attr,
3749 const char *buf, size_t count) 3745 const char *buf, size_t count)
3750{ 3746{
3751 struct ipw2100_priv *priv = dev_get_drvdata(d); 3747 struct ipw2100_priv *priv = dev_get_drvdata(d);
3752 struct net_device *dev = priv->net_dev; 3748 struct net_device *dev = priv->net_dev;
3753 const char *p = buf; 3749 const char *p = buf;
3754 3750
3751 (void) dev; /* kill unused-var warning for debug-only code */
3752
3755 if (count < 1) 3753 if (count < 1)
3756 return count; 3754 return count;
3757 3755
3758 if (p[0] == '1' || 3756 if (p[0] == '1' ||
3759 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) { 3757 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
3760 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n", 3758 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
3761 dev->name); 3759 dev->name);
3762 priv->dump_raw = 1; 3760 priv->dump_raw = 1;
3763 3761
3764 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' && 3762 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
3765 tolower(p[1]) == 'f')) { 3763 tolower(p[1]) == 'f')) {
3766 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n", 3764 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
3767 dev->name); 3765 dev->name);
3768 priv->dump_raw = 0; 3766 priv->dump_raw = 0;
3769 3767
3770 } else if (tolower(p[0]) == 'r') { 3768 } else if (tolower(p[0]) == 'r') {
3771 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", 3769 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", dev->name);
3772 dev->name);
3773 ipw2100_snapshot_free(priv); 3770 ipw2100_snapshot_free(priv);
3774 3771
3775 } else 3772 } else
3776 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, " 3773 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
3777 "reset = clear memory snapshot\n", 3774 "reset = clear memory snapshot\n", dev->name);
3778 dev->name);
3779 3775
3780 return count; 3776 return count;
3781} 3777}
3782static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
3783 3778
3779static DEVICE_ATTR(memory, S_IWUSR | S_IRUGO, show_memory, store_memory);
3784 3780
3785static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, 3781static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3786 char *buf) 3782 char *buf)
3787{ 3783{
3788 struct ipw2100_priv *priv = dev_get_drvdata(d); 3784 struct ipw2100_priv *priv = dev_get_drvdata(d);
3789 u32 val = 0; 3785 u32 val = 0;
@@ -3791,6 +3787,9 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3791 u32 val_len; 3787 u32 val_len;
3792 static int loop = 0; 3788 static int loop = 0;
3793 3789
3790 if (priv->status & STATUS_RF_KILL_MASK)
3791 return 0;
3792
3794 if (loop >= sizeof(ord_data) / sizeof(*ord_data)) 3793 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3795 loop = 0; 3794 loop = 0;
3796 3795
@@ -3814,14 +3813,14 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3814 3813
3815 return len; 3814 return len;
3816} 3815}
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3818 3816
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3819 3818
3820static ssize_t show_stats(struct device *d, struct device_attribute *attr, 3819static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3821 char *buf) 3820 char *buf)
3822{ 3821{
3823 struct ipw2100_priv *priv = dev_get_drvdata(d); 3822 struct ipw2100_priv *priv = dev_get_drvdata(d);
3824 char * out = buf; 3823 char *out = buf;
3825 3824
3826 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n", 3825 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
3827 priv->interrupts, priv->tx_interrupts, 3826 priv->interrupts, priv->tx_interrupts,
@@ -3835,8 +3834,8 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3835 3834
3836 return out - buf; 3835 return out - buf;
3837} 3836}
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3839 3837
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3840 3839
3841static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) 3840static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3842{ 3841{
@@ -3864,19 +3863,18 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3864 priv->last_mode = priv->ieee->iw_mode; 3863 priv->last_mode = priv->ieee->iw_mode;
3865 priv->net_dev->type = ARPHRD_IEEE80211; 3864 priv->net_dev->type = ARPHRD_IEEE80211;
3866 break; 3865 break;
3867#endif /* CONFIG_IPW2100_MONITOR */ 3866#endif /* CONFIG_IPW2100_MONITOR */
3868 } 3867 }
3869 3868
3870 priv->ieee->iw_mode = mode; 3869 priv->ieee->iw_mode = mode;
3871 3870
3872#ifdef CONFIG_PM 3871#ifdef CONFIG_PM
3873 /* Indicate ipw2100_download_firmware download firmware 3872 /* Indicate ipw2100_download_firmware download firmware
3874 * from disk instead of memory. */ 3873 * from disk instead of memory. */
3875 ipw2100_firmware.version = 0; 3874 ipw2100_firmware.version = 0;
3876#endif 3875#endif
3877 3876
3878 printk(KERN_INFO "%s: Reseting on mode change.\n", 3877 printk(KERN_INFO "%s: Reseting on mode change.\n", priv->net_dev->name);
3879 priv->net_dev->name);
3880 priv->reset_backoff = 0; 3878 priv->reset_backoff = 0;
3881 schedule_reset(priv); 3879 schedule_reset(priv);
3882 3880
@@ -3884,12 +3882,12 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3884} 3882}
3885 3883
3886static ssize_t show_internals(struct device *d, struct device_attribute *attr, 3884static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3887 char *buf) 3885 char *buf)
3888{ 3886{
3889 struct ipw2100_priv *priv = dev_get_drvdata(d); 3887 struct ipw2100_priv *priv = dev_get_drvdata(d);
3890 int len = 0; 3888 int len = 0;
3891 3889
3892#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x) 3890#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" y "\n", priv-> x)
3893 3891
3894 if (priv->status & STATUS_ASSOCIATED) 3892 if (priv->status & STATUS_ASSOCIATED)
3895 len += sprintf(buf + len, "connected: %lu\n", 3893 len += sprintf(buf + len, "connected: %lu\n",
@@ -3897,55 +3895,60 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3897 else 3895 else
3898 len += sprintf(buf + len, "not connected\n"); 3896 len += sprintf(buf + len, "not connected\n");
3899 3897
3900 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p); 3898 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p");
3901 DUMP_VAR(status, 08lx); 3899 DUMP_VAR(status, "08lx");
3902 DUMP_VAR(config, 08lx); 3900 DUMP_VAR(config, "08lx");
3903 DUMP_VAR(capability, 08lx); 3901 DUMP_VAR(capability, "08lx");
3904 3902
3905 len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc); 3903 len +=
3904 sprintf(buf + len, "last_rtc: %lu\n",
3905 (unsigned long)priv->last_rtc);
3906 3906
3907 DUMP_VAR(fatal_error, d); 3907 DUMP_VAR(fatal_error, "d");
3908 DUMP_VAR(stop_hang_check, d); 3908 DUMP_VAR(stop_hang_check, "d");
3909 DUMP_VAR(stop_rf_kill, d); 3909 DUMP_VAR(stop_rf_kill, "d");
3910 DUMP_VAR(messages_sent, d); 3910 DUMP_VAR(messages_sent, "d");
3911 3911
3912 DUMP_VAR(tx_pend_stat.value, d); 3912 DUMP_VAR(tx_pend_stat.value, "d");
3913 DUMP_VAR(tx_pend_stat.hi, d); 3913 DUMP_VAR(tx_pend_stat.hi, "d");
3914 3914
3915 DUMP_VAR(tx_free_stat.value, d); 3915 DUMP_VAR(tx_free_stat.value, "d");
3916 DUMP_VAR(tx_free_stat.lo, d); 3916 DUMP_VAR(tx_free_stat.lo, "d");
3917 3917
3918 DUMP_VAR(msg_free_stat.value, d); 3918 DUMP_VAR(msg_free_stat.value, "d");
3919 DUMP_VAR(msg_free_stat.lo, d); 3919 DUMP_VAR(msg_free_stat.lo, "d");
3920 3920
3921 DUMP_VAR(msg_pend_stat.value, d); 3921 DUMP_VAR(msg_pend_stat.value, "d");
3922 DUMP_VAR(msg_pend_stat.hi, d); 3922 DUMP_VAR(msg_pend_stat.hi, "d");
3923 3923
3924 DUMP_VAR(fw_pend_stat.value, d); 3924 DUMP_VAR(fw_pend_stat.value, "d");
3925 DUMP_VAR(fw_pend_stat.hi, d); 3925 DUMP_VAR(fw_pend_stat.hi, "d");
3926 3926
3927 DUMP_VAR(txq_stat.value, d); 3927 DUMP_VAR(txq_stat.value, "d");
3928 DUMP_VAR(txq_stat.lo, d); 3928 DUMP_VAR(txq_stat.lo, "d");
3929 3929
3930 DUMP_VAR(ieee->scans, d); 3930 DUMP_VAR(ieee->scans, "d");
3931 DUMP_VAR(reset_backoff, d); 3931 DUMP_VAR(reset_backoff, "d");
3932 3932
3933 return len; 3933 return len;
3934} 3934}
3935static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3936 3935
3936static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3937 3937
3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, 3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3939 char *buf) 3939 char *buf)
3940{ 3940{
3941 struct ipw2100_priv *priv = dev_get_drvdata(d); 3941 struct ipw2100_priv *priv = dev_get_drvdata(d);
3942 char essid[IW_ESSID_MAX_SIZE + 1]; 3942 char essid[IW_ESSID_MAX_SIZE + 1];
3943 u8 bssid[ETH_ALEN]; 3943 u8 bssid[ETH_ALEN];
3944 u32 chan = 0; 3944 u32 chan = 0;
3945 char * out = buf; 3945 char *out = buf;
3946 int length; 3946 int length;
3947 int ret; 3947 int ret;
3948 3948
3949 if (priv->status & STATUS_RF_KILL_MASK)
3950 return 0;
3951
3949 memset(essid, 0, sizeof(essid)); 3952 memset(essid, 0, sizeof(essid));
3950 memset(bssid, 0, sizeof(bssid)); 3953 memset(bssid, 0, sizeof(bssid));
3951 3954
@@ -3976,8 +3979,8 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3976 3979
3977 return out - buf; 3980 return out - buf;
3978} 3981}
3979static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3980 3982
3983static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3981 3984
3982#ifdef CONFIG_IPW_DEBUG 3985#ifdef CONFIG_IPW_DEBUG
3983static ssize_t show_debug_level(struct device_driver *d, char *buf) 3986static ssize_t show_debug_level(struct device_driver *d, char *buf)
@@ -3985,8 +3988,8 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
3985 return sprintf(buf, "0x%08X\n", ipw2100_debug_level); 3988 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3986} 3989}
3987 3990
3988static ssize_t store_debug_level(struct device_driver *d, const char *buf, 3991static ssize_t store_debug_level(struct device_driver *d,
3989 size_t count) 3992 const char *buf, size_t count)
3990{ 3993{
3991 char *p = (char *)buf; 3994 char *p = (char *)buf;
3992 u32 val; 3995 u32 val;
@@ -3999,28 +4002,26 @@ static ssize_t store_debug_level(struct device_driver *d, const char *buf,
3999 } else 4002 } else
4000 val = simple_strtoul(p, &p, 10); 4003 val = simple_strtoul(p, &p, 10);
4001 if (p == buf) 4004 if (p == buf)
4002 IPW_DEBUG_INFO(DRV_NAME 4005 IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf);
4003 ": %s is not in hex or decimal form.\n", buf);
4004 else 4006 else
4005 ipw2100_debug_level = val; 4007 ipw2100_debug_level = val;
4006 4008
4007 return strnlen(buf, count); 4009 return strnlen(buf, count);
4008} 4010}
4011
4009static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, 4012static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
4010 store_debug_level); 4013 store_debug_level);
4011#endif /* CONFIG_IPW_DEBUG */ 4014#endif /* CONFIG_IPW_DEBUG */
4012
4013 4015
4014static ssize_t show_fatal_error(struct device *d, 4016static ssize_t show_fatal_error(struct device *d,
4015 struct device_attribute *attr, char *buf) 4017 struct device_attribute *attr, char *buf)
4016{ 4018{
4017 struct ipw2100_priv *priv = dev_get_drvdata(d); 4019 struct ipw2100_priv *priv = dev_get_drvdata(d);
4018 char *out = buf; 4020 char *out = buf;
4019 int i; 4021 int i;
4020 4022
4021 if (priv->fatal_error) 4023 if (priv->fatal_error)
4022 out += sprintf(out, "0x%08X\n", 4024 out += sprintf(out, "0x%08X\n", priv->fatal_error);
4023 priv->fatal_error);
4024 else 4025 else
4025 out += sprintf(out, "0\n"); 4026 out += sprintf(out, "0\n");
4026 4027
@@ -4038,24 +4039,26 @@ static ssize_t show_fatal_error(struct device *d,
4038} 4039}
4039 4040
4040static ssize_t store_fatal_error(struct device *d, 4041static ssize_t store_fatal_error(struct device *d,
4041 struct device_attribute *attr, const char *buf, size_t count) 4042 struct device_attribute *attr, const char *buf,
4043 size_t count)
4042{ 4044{
4043 struct ipw2100_priv *priv = dev_get_drvdata(d); 4045 struct ipw2100_priv *priv = dev_get_drvdata(d);
4044 schedule_reset(priv); 4046 schedule_reset(priv);
4045 return count; 4047 return count;
4046} 4048}
4047static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
4048 4049
4050static DEVICE_ATTR(fatal_error, S_IWUSR | S_IRUGO, show_fatal_error,
4051 store_fatal_error);
4049 4052
4050static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 4053static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
4051 char *buf) 4054 char *buf)
4052{ 4055{
4053 struct ipw2100_priv *priv = dev_get_drvdata(d); 4056 struct ipw2100_priv *priv = dev_get_drvdata(d);
4054 return sprintf(buf, "%d\n", priv->ieee->scan_age); 4057 return sprintf(buf, "%d\n", priv->ieee->scan_age);
4055} 4058}
4056 4059
4057static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, 4060static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4058 const char *buf, size_t count) 4061 const char *buf, size_t count)
4059{ 4062{
4060 struct ipw2100_priv *priv = dev_get_drvdata(d); 4063 struct ipw2100_priv *priv = dev_get_drvdata(d);
4061 struct net_device *dev = priv->net_dev; 4064 struct net_device *dev = priv->net_dev;
@@ -4065,6 +4068,8 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4065 unsigned long val; 4068 unsigned long val;
4066 char *p = buffer; 4069 char *p = buffer;
4067 4070
4071 (void) dev; /* kill unused-var warning for debug-only code */
4072
4068 IPW_DEBUG_INFO("enter\n"); 4073 IPW_DEBUG_INFO("enter\n");
4069 4074
4070 strncpy(buffer, buf, len); 4075 strncpy(buffer, buf, len);
@@ -4078,8 +4083,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4078 } else 4083 } else
4079 val = simple_strtoul(p, &p, 10); 4084 val = simple_strtoul(p, &p, 10);
4080 if (p == buffer) { 4085 if (p == buffer) {
4081 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", 4086 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
4082 dev->name);
4083 } else { 4087 } else {
4084 priv->ieee->scan_age = val; 4088 priv->ieee->scan_age = val;
4085 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age); 4089 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
@@ -4088,11 +4092,11 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4088 IPW_DEBUG_INFO("exit\n"); 4092 IPW_DEBUG_INFO("exit\n");
4089 return len; 4093 return len;
4090} 4094}
4091static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4092 4095
4096static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4093 4097
4094static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, 4098static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4095 char *buf) 4099 char *buf)
4096{ 4100{
4097 /* 0 - RF kill not enabled 4101 /* 0 - RF kill not enabled
4098 1 - SW based RF kill active (sysfs) 4102 1 - SW based RF kill active (sysfs)
@@ -4100,7 +4104,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4100 3 - Both HW and SW baed RF kill active */ 4104 3 - Both HW and SW baed RF kill active */
4101 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data; 4105 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
4102 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) | 4106 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
4103 (rf_kill_active(priv) ? 0x2 : 0x0); 4107 (rf_kill_active(priv) ? 0x2 : 0x0);
4104 return sprintf(buf, "%i\n", val); 4108 return sprintf(buf, "%i\n", val);
4105} 4109}
4106 4110
@@ -4108,7 +4112,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4108{ 4112{
4109 if ((disable_radio ? 1 : 0) == 4113 if ((disable_radio ? 1 : 0) ==
4110 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 4114 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
4111 return 0 ; 4115 return 0;
4112 4116
4113 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 4117 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4114 disable_radio ? "OFF" : "ON"); 4118 disable_radio ? "OFF" : "ON");
@@ -4126,8 +4130,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4126 /* Make sure the RF_KILL check timer is running */ 4130 /* Make sure the RF_KILL check timer is running */
4127 priv->stop_rf_kill = 0; 4131 priv->stop_rf_kill = 0;
4128 cancel_delayed_work(&priv->rf_kill); 4132 cancel_delayed_work(&priv->rf_kill);
4129 queue_delayed_work(priv->workqueue, &priv->rf_kill, 4133 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
4130 HZ);
4131 } else 4134 } else
4132 schedule_reset(priv); 4135 schedule_reset(priv);
4133 } 4136 }
@@ -4137,14 +4140,14 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4137} 4140}
4138 4141
4139static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, 4142static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
4140 const char *buf, size_t count) 4143 const char *buf, size_t count)
4141{ 4144{
4142 struct ipw2100_priv *priv = dev_get_drvdata(d); 4145 struct ipw2100_priv *priv = dev_get_drvdata(d);
4143 ipw_radio_kill_sw(priv, buf[0] == '1'); 4146 ipw_radio_kill_sw(priv, buf[0] == '1');
4144 return count; 4147 return count;
4145} 4148}
4146static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
4147 4149
4150static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
4148 4151
4149static struct attribute *ipw2100_sysfs_entries[] = { 4152static struct attribute *ipw2100_sysfs_entries[] = {
4150 &dev_attr_hardware.attr, 4153 &dev_attr_hardware.attr,
@@ -4168,7 +4171,6 @@ static struct attribute_group ipw2100_attribute_group = {
4168 .attrs = ipw2100_sysfs_entries, 4171 .attrs = ipw2100_sysfs_entries,
4169}; 4172};
4170 4173
4171
4172static int status_queue_allocate(struct ipw2100_priv *priv, int entries) 4174static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4173{ 4175{
4174 struct ipw2100_status_queue *q = &priv->status_queue; 4176 struct ipw2100_status_queue *q = &priv->status_queue;
@@ -4176,11 +4178,11 @@ static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4176 IPW_DEBUG_INFO("enter\n"); 4178 IPW_DEBUG_INFO("enter\n");
4177 4179
4178 q->size = entries * sizeof(struct ipw2100_status); 4180 q->size = entries * sizeof(struct ipw2100_status);
4179 q->drv = (struct ipw2100_status *)pci_alloc_consistent( 4181 q->drv =
4180 priv->pci_dev, q->size, &q->nic); 4182 (struct ipw2100_status *)pci_alloc_consistent(priv->pci_dev,
4183 q->size, &q->nic);
4181 if (!q->drv) { 4184 if (!q->drv) {
4182 IPW_DEBUG_WARNING( 4185 IPW_DEBUG_WARNING("Can not allocate status queue.\n");
4183 "Can not allocate status queue.\n");
4184 return -ENOMEM; 4186 return -ENOMEM;
4185 } 4187 }
4186 4188
@@ -4196,9 +4198,9 @@ static void status_queue_free(struct ipw2100_priv *priv)
4196 IPW_DEBUG_INFO("enter\n"); 4198 IPW_DEBUG_INFO("enter\n");
4197 4199
4198 if (priv->status_queue.drv) { 4200 if (priv->status_queue.drv) {
4199 pci_free_consistent( 4201 pci_free_consistent(priv->pci_dev, priv->status_queue.size,
4200 priv->pci_dev, priv->status_queue.size, 4202 priv->status_queue.drv,
4201 priv->status_queue.drv, priv->status_queue.nic); 4203 priv->status_queue.nic);
4202 priv->status_queue.drv = NULL; 4204 priv->status_queue.drv = NULL;
4203 } 4205 }
4204 4206
@@ -4216,7 +4218,8 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4216 q->size = entries * sizeof(struct ipw2100_bd); 4218 q->size = entries * sizeof(struct ipw2100_bd);
4217 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic); 4219 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
4218 if (!q->drv) { 4220 if (!q->drv) {
4219 IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n"); 4221 IPW_DEBUG_INFO
4222 ("can't allocate shared memory for buffer descriptors\n");
4220 return -ENOMEM; 4223 return -ENOMEM;
4221 } 4224 }
4222 memset(q->drv, 0, q->size); 4225 memset(q->drv, 0, q->size);
@@ -4226,8 +4229,7 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4226 return 0; 4229 return 0;
4227} 4230}
4228 4231
4229static void bd_queue_free(struct ipw2100_priv *priv, 4232static void bd_queue_free(struct ipw2100_priv *priv, struct ipw2100_bd_queue *q)
4230 struct ipw2100_bd_queue *q)
4231{ 4233{
4232 IPW_DEBUG_INFO("enter\n"); 4234 IPW_DEBUG_INFO("enter\n");
4233 4235
@@ -4235,21 +4237,21 @@ static void bd_queue_free(struct ipw2100_priv *priv,
4235 return; 4237 return;
4236 4238
4237 if (q->drv) { 4239 if (q->drv) {
4238 pci_free_consistent(priv->pci_dev, 4240 pci_free_consistent(priv->pci_dev, q->size, q->drv, q->nic);
4239 q->size, q->drv, q->nic);
4240 q->drv = NULL; 4241 q->drv = NULL;
4241 } 4242 }
4242 4243
4243 IPW_DEBUG_INFO("exit\n"); 4244 IPW_DEBUG_INFO("exit\n");
4244} 4245}
4245 4246
4246static void bd_queue_initialize( 4247static void bd_queue_initialize(struct ipw2100_priv *priv,
4247 struct ipw2100_priv *priv, struct ipw2100_bd_queue * q, 4248 struct ipw2100_bd_queue *q, u32 base, u32 size,
4248 u32 base, u32 size, u32 r, u32 w) 4249 u32 r, u32 w)
4249{ 4250{
4250 IPW_DEBUG_INFO("enter\n"); 4251 IPW_DEBUG_INFO("enter\n");
4251 4252
4252 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, (u32)q->nic); 4253 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv,
4254 (u32) q->nic);
4253 4255
4254 write_register(priv->net_dev, base, q->nic); 4256 write_register(priv->net_dev, base, q->nic);
4255 write_register(priv->net_dev, size, q->entries); 4257 write_register(priv->net_dev, size, q->entries);
@@ -4285,32 +4287,38 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4285 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH); 4287 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
4286 if (err) { 4288 if (err) {
4287 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n", 4289 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
4288 priv->net_dev->name); 4290 priv->net_dev->name);
4289 return err; 4291 return err;
4290 } 4292 }
4291 4293
4292 priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc( 4294 priv->tx_buffers =
4293 TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet), 4295 (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH *
4294 GFP_ATOMIC); 4296 sizeof(struct
4297 ipw2100_tx_packet),
4298 GFP_ATOMIC);
4295 if (!priv->tx_buffers) { 4299 if (!priv->tx_buffers) {
4296 printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n", 4300 printk(KERN_ERR DRV_NAME
4301 ": %s: alloc failed form tx buffers.\n",
4297 priv->net_dev->name); 4302 priv->net_dev->name);
4298 bd_queue_free(priv, &priv->tx_queue); 4303 bd_queue_free(priv, &priv->tx_queue);
4299 return -ENOMEM; 4304 return -ENOMEM;
4300 } 4305 }
4301 4306
4302 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4307 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4303 v = pci_alloc_consistent( 4308 v = pci_alloc_consistent(priv->pci_dev,
4304 priv->pci_dev, sizeof(struct ipw2100_data_header), &p); 4309 sizeof(struct ipw2100_data_header),
4310 &p);
4305 if (!v) { 4311 if (!v) {
4306 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx " 4312 printk(KERN_ERR DRV_NAME
4307 "buffers.\n", priv->net_dev->name); 4313 ": %s: PCI alloc failed for tx " "buffers.\n",
4314 priv->net_dev->name);
4308 err = -ENOMEM; 4315 err = -ENOMEM;
4309 break; 4316 break;
4310 } 4317 }
4311 4318
4312 priv->tx_buffers[i].type = DATA; 4319 priv->tx_buffers[i].type = DATA;
4313 priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v; 4320 priv->tx_buffers[i].info.d_struct.data =
4321 (struct ipw2100_data_header *)v;
4314 priv->tx_buffers[i].info.d_struct.data_phys = p; 4322 priv->tx_buffers[i].info.d_struct.data_phys = p;
4315 priv->tx_buffers[i].info.d_struct.txb = NULL; 4323 priv->tx_buffers[i].info.d_struct.txb = NULL;
4316 } 4324 }
@@ -4319,11 +4327,11 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4319 return 0; 4327 return 0;
4320 4328
4321 for (j = 0; j < i; j++) { 4329 for (j = 0; j < i; j++) {
4322 pci_free_consistent( 4330 pci_free_consistent(priv->pci_dev,
4323 priv->pci_dev, 4331 sizeof(struct ipw2100_data_header),
4324 sizeof(struct ipw2100_data_header), 4332 priv->tx_buffers[j].info.d_struct.data,
4325 priv->tx_buffers[j].info.d_struct.data, 4333 priv->tx_buffers[j].info.d_struct.
4326 priv->tx_buffers[j].info.d_struct.data_phys); 4334 data_phys);
4327 } 4335 }
4328 4336
4329 kfree(priv->tx_buffers); 4337 kfree(priv->tx_buffers);
@@ -4356,7 +4364,8 @@ static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
4356 /* We simply drop any SKBs that have been queued for 4364 /* We simply drop any SKBs that have been queued for
4357 * transmit */ 4365 * transmit */
4358 if (priv->tx_buffers[i].info.d_struct.txb) { 4366 if (priv->tx_buffers[i].info.d_struct.txb) {
4359 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4367 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4368 txb);
4360 priv->tx_buffers[i].info.d_struct.txb = NULL; 4369 priv->tx_buffers[i].info.d_struct.txb = NULL;
4361 } 4370 }
4362 4371
@@ -4394,15 +4403,17 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4394 4403
4395 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4404 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4396 if (priv->tx_buffers[i].info.d_struct.txb) { 4405 if (priv->tx_buffers[i].info.d_struct.txb) {
4397 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4406 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4407 txb);
4398 priv->tx_buffers[i].info.d_struct.txb = NULL; 4408 priv->tx_buffers[i].info.d_struct.txb = NULL;
4399 } 4409 }
4400 if (priv->tx_buffers[i].info.d_struct.data) 4410 if (priv->tx_buffers[i].info.d_struct.data)
4401 pci_free_consistent( 4411 pci_free_consistent(priv->pci_dev,
4402 priv->pci_dev, 4412 sizeof(struct ipw2100_data_header),
4403 sizeof(struct ipw2100_data_header), 4413 priv->tx_buffers[i].info.d_struct.
4404 priv->tx_buffers[i].info.d_struct.data, 4414 data,
4405 priv->tx_buffers[i].info.d_struct.data_phys); 4415 priv->tx_buffers[i].info.d_struct.
4416 data_phys);
4406 } 4417 }
4407 4418
4408 kfree(priv->tx_buffers); 4419 kfree(priv->tx_buffers);
@@ -4411,8 +4422,6 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4411 IPW_DEBUG_INFO("exit\n"); 4422 IPW_DEBUG_INFO("exit\n");
4412} 4423}
4413 4424
4414
4415
4416static int ipw2100_rx_allocate(struct ipw2100_priv *priv) 4425static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4417{ 4426{
4418 int i, j, err = -EINVAL; 4427 int i, j, err = -EINVAL;
@@ -4542,14 +4551,13 @@ static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
4542 4551
4543 int err; 4552 int err;
4544 4553
4545 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, 4554 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, mac, &length);
4546 mac, &length);
4547 if (err) { 4555 if (err) {
4548 IPW_DEBUG_INFO("MAC address read failed\n"); 4556 IPW_DEBUG_INFO("MAC address read failed\n");
4549 return -EIO; 4557 return -EIO;
4550 } 4558 }
4551 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n", 4559 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
4552 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4560 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4553 4561
4554 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN); 4562 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
4555 4563
@@ -4576,8 +4584,7 @@ static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
4576 IPW_DEBUG_INFO("enter\n"); 4584 IPW_DEBUG_INFO("enter\n");
4577 4585
4578 if (priv->config & CFG_CUSTOM_MAC) { 4586 if (priv->config & CFG_CUSTOM_MAC) {
4579 memcpy(cmd.host_command_parameters, priv->mac_addr, 4587 memcpy(cmd.host_command_parameters, priv->mac_addr, ETH_ALEN);
4580 ETH_ALEN);
4581 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 4588 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
4582 } else 4589 } else
4583 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr, 4590 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
@@ -4614,7 +4621,8 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4614 if (!batch_mode) { 4621 if (!batch_mode) {
4615 err = ipw2100_disable_adapter(priv); 4622 err = ipw2100_disable_adapter(priv);
4616 if (err) { 4623 if (err) {
4617 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 4624 printk(KERN_ERR DRV_NAME
4625 ": %s: Could not disable adapter %d\n",
4618 priv->net_dev->name, err); 4626 priv->net_dev->name, err);
4619 return err; 4627 return err;
4620 } 4628 }
@@ -4629,7 +4637,6 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4629 return err; 4637 return err;
4630} 4638}
4631 4639
4632
4633static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel, 4640static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4634 int batch_mode) 4641 int batch_mode)
4635{ 4642{
@@ -4660,8 +4667,7 @@ static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4660 4667
4661 err = ipw2100_hw_send_command(priv, &cmd); 4668 err = ipw2100_hw_send_command(priv, &cmd);
4662 if (err) { 4669 if (err) {
4663 IPW_DEBUG_INFO("Failed to set channel to %d", 4670 IPW_DEBUG_INFO("Failed to set channel to %d", channel);
4664 channel);
4665 return err; 4671 return err;
4666 } 4672 }
4667 4673
@@ -4703,15 +4709,14 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4703 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START; 4709 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
4704 4710
4705 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK | 4711 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
4706 IPW_CFG_BSS_MASK | 4712 IPW_CFG_BSS_MASK | IPW_CFG_802_1x_ENABLE;
4707 IPW_CFG_802_1x_ENABLE;
4708 4713
4709 if (!(priv->config & CFG_LONG_PREAMBLE)) 4714 if (!(priv->config & CFG_LONG_PREAMBLE))
4710 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO; 4715 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
4711 4716
4712 err = ipw2100_get_ordinal(priv, 4717 err = ipw2100_get_ordinal(priv,
4713 IPW_ORD_EEPROM_IBSS_11B_CHANNELS, 4718 IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
4714 &ibss_mask, &len); 4719 &ibss_mask, &len);
4715 if (err) 4720 if (err)
4716 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK; 4721 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
4717 4722
@@ -4719,7 +4724,7 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4719 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask; 4724 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
4720 4725
4721 /* 11b only */ 4726 /* 11b only */
4722 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/ 4727 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A; */
4723 4728
4724 err = ipw2100_hw_send_command(priv, &cmd); 4729 err = ipw2100_hw_send_command(priv, &cmd);
4725 if (err) 4730 if (err)
@@ -4783,8 +4788,7 @@ static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
4783 return 0; 4788 return 0;
4784} 4789}
4785 4790
4786static int ipw2100_set_power_mode(struct ipw2100_priv *priv, 4791static int ipw2100_set_power_mode(struct ipw2100_priv *priv, int power_level)
4787 int power_level)
4788{ 4792{
4789 struct host_command cmd = { 4793 struct host_command cmd = {
4790 .host_command = POWER_MODE, 4794 .host_command = POWER_MODE,
@@ -4805,11 +4809,10 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4805 priv->power_mode = IPW_POWER_ENABLED | power_level; 4809 priv->power_mode = IPW_POWER_ENABLED | power_level;
4806 4810
4807#ifdef CONFIG_IPW2100_TX_POWER 4811#ifdef CONFIG_IPW2100_TX_POWER
4808 if (priv->port_type == IBSS && 4812 if (priv->port_type == IBSS && priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4809 priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4810 /* Set beacon interval */ 4813 /* Set beacon interval */
4811 cmd.host_command = TX_POWER_INDEX; 4814 cmd.host_command = TX_POWER_INDEX;
4812 cmd.host_command_parameters[0] = (u32)priv->adhoc_power; 4815 cmd.host_command_parameters[0] = (u32) priv->adhoc_power;
4813 4816
4814 err = ipw2100_hw_send_command(priv, &cmd); 4817 err = ipw2100_hw_send_command(priv, &cmd);
4815 if (err) 4818 if (err)
@@ -4820,7 +4823,6 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4820 return 0; 4823 return 0;
4821} 4824}
4822 4825
4823
4824static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold) 4826static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
4825{ 4827{
4826 struct host_command cmd = { 4828 struct host_command cmd = {
@@ -4925,8 +4927,7 @@ static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
4925 return 0; 4927 return 0;
4926} 4928}
4927 4929
4928 4930static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
4929static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4930 int batch_mode) 4931 int batch_mode)
4931{ 4932{
4932 struct host_command cmd = { 4933 struct host_command cmd = {
@@ -4938,16 +4939,15 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4938 4939
4939#ifdef CONFIG_IPW_DEBUG 4940#ifdef CONFIG_IPW_DEBUG
4940 if (bssid != NULL) 4941 if (bssid != NULL)
4941 IPW_DEBUG_HC( 4942 IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
4942 "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", 4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], 4944 bssid[5]);
4944 bssid[5]);
4945 else 4945 else
4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n"); 4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
4947#endif 4947#endif
4948 /* if BSSID is empty then we disable mandatory bssid mode */ 4948 /* if BSSID is empty then we disable mandatory bssid mode */
4949 if (bssid != NULL) 4949 if (bssid != NULL)
4950 memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN); 4950 memcpy(cmd.host_command_parameters, bssid, ETH_ALEN);
4951 4951
4952 if (!batch_mode) { 4952 if (!batch_mode) {
4953 err = ipw2100_disable_adapter(priv); 4953 err = ipw2100_disable_adapter(priv);
@@ -4963,7 +4963,6 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4963 return err; 4963 return err;
4964} 4964}
4965 4965
4966#ifdef CONFIG_IEEE80211_WPA
4967static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv) 4966static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4968{ 4967{
4969 struct host_command cmd = { 4968 struct host_command cmd = {
@@ -4987,42 +4986,10 @@ static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4987 4986
4988 return err; 4987 return err;
4989} 4988}
4990#endif
4991
4992/*
4993 * Pseudo code for setting up wpa_frame:
4994 */
4995#if 0
4996void x(struct ieee80211_assoc_frame *wpa_assoc)
4997{
4998 struct ipw2100_wpa_assoc_frame frame;
4999 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
5000 IPW_WPA_LISTENINTERVAL |
5001 IPW_WPA_AP_ADDRESS;
5002 frame->capab_info = wpa_assoc->capab_info;
5003 frame->lisen_interval = wpa_assoc->listent_interval;
5004 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
5005
5006 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
5007 * setup here to test it with.
5008 *
5009 * Walk the IEs in the wpa_assoc and figure out the total size of all
5010 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
5011 * the IEs from wpa_frame into frame.
5012 */
5013 frame->var_ie_len = calculate_ie_len(wpa_assoc);
5014 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
5015
5016 ipw2100_set_wpa_ie(priv, &frame, 0);
5017}
5018#endif
5019
5020
5021
5022 4989
5023static int ipw2100_set_wpa_ie(struct ipw2100_priv *, 4990static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
5024 struct ipw2100_wpa_assoc_frame *, int) 4991 struct ipw2100_wpa_assoc_frame *, int)
5025__attribute__ ((unused)); 4992 __attribute__ ((unused));
5026 4993
5027static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv, 4994static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
5028 struct ipw2100_wpa_assoc_frame *wpa_frame, 4995 struct ipw2100_wpa_assoc_frame *wpa_frame,
@@ -5076,7 +5043,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5076 .host_command_length = sizeof(struct security_info_params) 5043 .host_command_length = sizeof(struct security_info_params)
5077 }; 5044 };
5078 struct security_info_params *security = 5045 struct security_info_params *security =
5079 (struct security_info_params *)&cmd.host_command_parameters; 5046 (struct security_info_params *)&cmd.host_command_parameters;
5080 int err; 5047 int err;
5081 memset(security, 0, sizeof(*security)); 5048 memset(security, 0, sizeof(*security));
5082 5049
@@ -5094,25 +5061,25 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5094 break; 5061 break;
5095 case SEC_LEVEL_1: 5062 case SEC_LEVEL_1:
5096 security->allowed_ciphers = IPW_WEP40_CIPHER | 5063 security->allowed_ciphers = IPW_WEP40_CIPHER |
5097 IPW_WEP104_CIPHER; 5064 IPW_WEP104_CIPHER;
5098 break; 5065 break;
5099 case SEC_LEVEL_2: 5066 case SEC_LEVEL_2:
5100 security->allowed_ciphers = IPW_WEP40_CIPHER | 5067 security->allowed_ciphers = IPW_WEP40_CIPHER |
5101 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER; 5068 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
5102 break; 5069 break;
5103 case SEC_LEVEL_2_CKIP: 5070 case SEC_LEVEL_2_CKIP:
5104 security->allowed_ciphers = IPW_WEP40_CIPHER | 5071 security->allowed_ciphers = IPW_WEP40_CIPHER |
5105 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER; 5072 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
5106 break; 5073 break;
5107 case SEC_LEVEL_3: 5074 case SEC_LEVEL_3:
5108 security->allowed_ciphers = IPW_WEP40_CIPHER | 5075 security->allowed_ciphers = IPW_WEP40_CIPHER |
5109 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER; 5076 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
5110 break; 5077 break;
5111 } 5078 }
5112 5079
5113 IPW_DEBUG_HC( 5080 IPW_DEBUG_HC
5114 "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n", 5081 ("SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
5115 security->auth_mode, security->allowed_ciphers, security_level); 5082 security->auth_mode, security->allowed_ciphers, security_level);
5116 5083
5117 security->replay_counters_number = 0; 5084 security->replay_counters_number = 0;
5118 5085
@@ -5130,8 +5097,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5130 return err; 5097 return err;
5131} 5098}
5132 5099
5133static int ipw2100_set_tx_power(struct ipw2100_priv *priv, 5100static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
5134 u32 tx_power)
5135{ 5101{
5136 struct host_command cmd = { 5102 struct host_command cmd = {
5137 .host_command = TX_POWER_INDEX, 5103 .host_command = TX_POWER_INDEX,
@@ -5140,6 +5106,10 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
5140 }; 5106 };
5141 int err = 0; 5107 int err = 0;
5142 5108
5109 if (tx_power != IPW_TX_POWER_DEFAULT)
5110 tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
5111 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
5112
5143 cmd.host_command_parameters[0] = tx_power; 5113 cmd.host_command_parameters[0] = tx_power;
5144 5114
5145 if (priv->ieee->iw_mode == IW_MODE_ADHOC) 5115 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
@@ -5185,7 +5155,6 @@ static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
5185 return 0; 5155 return 0;
5186} 5156}
5187 5157
5188
5189void ipw2100_queues_initialize(struct ipw2100_priv *priv) 5158void ipw2100_queues_initialize(struct ipw2100_priv *priv)
5190{ 5159{
5191 ipw2100_tx_initialize(priv); 5160 ipw2100_tx_initialize(priv);
@@ -5203,13 +5172,12 @@ void ipw2100_queues_free(struct ipw2100_priv *priv)
5203int ipw2100_queues_allocate(struct ipw2100_priv *priv) 5172int ipw2100_queues_allocate(struct ipw2100_priv *priv)
5204{ 5173{
5205 if (ipw2100_tx_allocate(priv) || 5174 if (ipw2100_tx_allocate(priv) ||
5206 ipw2100_rx_allocate(priv) || 5175 ipw2100_rx_allocate(priv) || ipw2100_msg_allocate(priv))
5207 ipw2100_msg_allocate(priv))
5208 goto fail; 5176 goto fail;
5209 5177
5210 return 0; 5178 return 0;
5211 5179
5212 fail: 5180 fail:
5213 ipw2100_tx_free(priv); 5181 ipw2100_tx_free(priv);
5214 ipw2100_rx_free(priv); 5182 ipw2100_rx_free(priv);
5215 ipw2100_msg_free(priv); 5183 ipw2100_msg_free(priv);
@@ -5235,7 +5203,8 @@ static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
5235 if (!batch_mode) { 5203 if (!batch_mode) {
5236 err = ipw2100_disable_adapter(priv); 5204 err = ipw2100_disable_adapter(priv);
5237 if (err) { 5205 if (err) {
5238 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5206 printk(KERN_ERR DRV_NAME
5207 ": %s: Could not disable adapter %d\n",
5239 priv->net_dev->name, err); 5208 priv->net_dev->name, err);
5240 return err; 5209 return err;
5241 } 5210 }
@@ -5262,7 +5231,6 @@ struct ipw2100_wep_key {
5262#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4] 5231#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
5263#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10] 5232#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
5264 5233
5265
5266/** 5234/**
5267 * Set a the wep key 5235 * Set a the wep key
5268 * 5236 *
@@ -5287,11 +5255,11 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5287 .host_command_sequence = 0, 5255 .host_command_sequence = 0,
5288 .host_command_length = sizeof(struct ipw2100_wep_key), 5256 .host_command_length = sizeof(struct ipw2100_wep_key),
5289 }; 5257 };
5290 struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters; 5258 struct ipw2100_wep_key *wep_key = (void *)cmd.host_command_parameters;
5291 int err; 5259 int err;
5292 5260
5293 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n", 5261 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
5294 idx, keylen, len); 5262 idx, keylen, len);
5295 5263
5296 /* NOTE: We don't check cached values in case the firmware was reset 5264 /* NOTE: We don't check cached values in case the firmware was reset
5297 * or some other problem is occuring. If the user is setting the key, 5265 * or some other problem is occuring. If the user is setting the key,
@@ -5308,22 +5276,23 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5308 /* Will be optimized out on debug not being configured in */ 5276 /* Will be optimized out on debug not being configured in */
5309 if (keylen == 0) 5277 if (keylen == 0)
5310 IPW_DEBUG_WEP("%s: Clearing key %d\n", 5278 IPW_DEBUG_WEP("%s: Clearing key %d\n",
5311 priv->net_dev->name, wep_key->idx); 5279 priv->net_dev->name, wep_key->idx);
5312 else if (keylen == 5) 5280 else if (keylen == 5)
5313 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n", 5281 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
5314 priv->net_dev->name, wep_key->idx, wep_key->len, 5282 priv->net_dev->name, wep_key->idx, wep_key->len,
5315 WEP_STR_64(wep_key->key)); 5283 WEP_STR_64(wep_key->key));
5316 else 5284 else
5317 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128 5285 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
5318 "\n", 5286 "\n",
5319 priv->net_dev->name, wep_key->idx, wep_key->len, 5287 priv->net_dev->name, wep_key->idx, wep_key->len,
5320 WEP_STR_128(wep_key->key)); 5288 WEP_STR_128(wep_key->key));
5321 5289
5322 if (!batch_mode) { 5290 if (!batch_mode) {
5323 err = ipw2100_disable_adapter(priv); 5291 err = ipw2100_disable_adapter(priv);
5324 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */ 5292 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
5325 if (err) { 5293 if (err) {
5326 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5294 printk(KERN_ERR DRV_NAME
5295 ": %s: Could not disable adapter %d\n",
5327 priv->net_dev->name, err); 5296 priv->net_dev->name, err);
5328 return err; 5297 return err;
5329 } 5298 }
@@ -5347,7 +5316,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5347 .host_command = WEP_KEY_INDEX, 5316 .host_command = WEP_KEY_INDEX,
5348 .host_command_sequence = 0, 5317 .host_command_sequence = 0,
5349 .host_command_length = 4, 5318 .host_command_length = 4,
5350 .host_command_parameters = { idx }, 5319 .host_command_parameters = {idx},
5351 }; 5320 };
5352 int err; 5321 int err;
5353 5322
@@ -5359,7 +5328,8 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5359 if (!batch_mode) { 5328 if (!batch_mode) {
5360 err = ipw2100_disable_adapter(priv); 5329 err = ipw2100_disable_adapter(priv);
5361 if (err) { 5330 if (err) {
5362 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5331 printk(KERN_ERR DRV_NAME
5332 ": %s: Could not disable adapter %d\n",
5363 priv->net_dev->name, err); 5333 priv->net_dev->name, err);
5364 return err; 5334 return err;
5365 } 5335 }
@@ -5374,9 +5344,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5374 return err; 5344 return err;
5375} 5345}
5376 5346
5377 5347static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
5378static int ipw2100_configure_security(struct ipw2100_priv *priv,
5379 int batch_mode)
5380{ 5348{
5381 int i, err, auth_mode, sec_level, use_group; 5349 int i, err, auth_mode, sec_level, use_group;
5382 5350
@@ -5389,40 +5357,42 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5389 return err; 5357 return err;
5390 } 5358 }
5391 5359
5392 if (!priv->sec.enabled) { 5360 if (!priv->ieee->sec.enabled) {
5393 err = ipw2100_set_security_information( 5361 err =
5394 priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1); 5362 ipw2100_set_security_information(priv, IPW_AUTH_OPEN,
5363 SEC_LEVEL_0, 0, 1);
5395 } else { 5364 } else {
5396 auth_mode = IPW_AUTH_OPEN; 5365 auth_mode = IPW_AUTH_OPEN;
5397 if ((priv->sec.flags & SEC_AUTH_MODE) && 5366 if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
5398 (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) 5367 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
5399 auth_mode = IPW_AUTH_SHARED; 5368 auth_mode = IPW_AUTH_SHARED;
5400 5369
5401 sec_level = SEC_LEVEL_0; 5370 sec_level = SEC_LEVEL_0;
5402 if (priv->sec.flags & SEC_LEVEL) 5371 if (priv->ieee->sec.flags & SEC_LEVEL)
5403 sec_level = priv->sec.level; 5372 sec_level = priv->ieee->sec.level;
5404 5373
5405 use_group = 0; 5374 use_group = 0;
5406 if (priv->sec.flags & SEC_UNICAST_GROUP) 5375 if (priv->ieee->sec.flags & SEC_UNICAST_GROUP)
5407 use_group = priv->sec.unicast_uses_group; 5376 use_group = priv->ieee->sec.unicast_uses_group;
5408 5377
5409 err = ipw2100_set_security_information( 5378 err =
5410 priv, auth_mode, sec_level, use_group, 1); 5379 ipw2100_set_security_information(priv, auth_mode, sec_level,
5380 use_group, 1);
5411 } 5381 }
5412 5382
5413 if (err) 5383 if (err)
5414 goto exit; 5384 goto exit;
5415 5385
5416 if (priv->sec.enabled) { 5386 if (priv->ieee->sec.enabled) {
5417 for (i = 0; i < 4; i++) { 5387 for (i = 0; i < 4; i++) {
5418 if (!(priv->sec.flags & (1 << i))) { 5388 if (!(priv->ieee->sec.flags & (1 << i))) {
5419 memset(priv->sec.keys[i], 0, WEP_KEY_LEN); 5389 memset(priv->ieee->sec.keys[i], 0, WEP_KEY_LEN);
5420 priv->sec.key_sizes[i] = 0; 5390 priv->ieee->sec.key_sizes[i] = 0;
5421 } else { 5391 } else {
5422 err = ipw2100_set_key(priv, i, 5392 err = ipw2100_set_key(priv, i,
5423 priv->sec.keys[i], 5393 priv->ieee->sec.keys[i],
5424 priv->sec.key_sizes[i], 5394 priv->ieee->sec.
5425 1); 5395 key_sizes[i], 1);
5426 if (err) 5396 if (err)
5427 goto exit; 5397 goto exit;
5428 } 5398 }
@@ -5433,14 +5403,16 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5433 5403
5434 /* Always enable privacy so the Host can filter WEP packets if 5404 /* Always enable privacy so the Host can filter WEP packets if
5435 * encrypted data is sent up */ 5405 * encrypted data is sent up */
5436 err = ipw2100_set_wep_flags( 5406 err =
5437 priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1); 5407 ipw2100_set_wep_flags(priv,
5408 priv->ieee->sec.
5409 enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
5438 if (err) 5410 if (err)
5439 goto exit; 5411 goto exit;
5440 5412
5441 priv->status &= ~STATUS_SECURITY_UPDATED; 5413 priv->status &= ~STATUS_SECURITY_UPDATED;
5442 5414
5443 exit: 5415 exit:
5444 if (!batch_mode) 5416 if (!batch_mode)
5445 ipw2100_enable_adapter(priv); 5417 ipw2100_enable_adapter(priv);
5446 5418
@@ -5469,60 +5441,64 @@ static void shim__set_security(struct net_device *dev,
5469 5441
5470 for (i = 0; i < 4; i++) { 5442 for (i = 0; i < 4; i++) {
5471 if (sec->flags & (1 << i)) { 5443 if (sec->flags & (1 << i)) {
5472 priv->sec.key_sizes[i] = sec->key_sizes[i]; 5444 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
5473 if (sec->key_sizes[i] == 0) 5445 if (sec->key_sizes[i] == 0)
5474 priv->sec.flags &= ~(1 << i); 5446 priv->ieee->sec.flags &= ~(1 << i);
5475 else 5447 else
5476 memcpy(priv->sec.keys[i], sec->keys[i], 5448 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
5477 sec->key_sizes[i]); 5449 sec->key_sizes[i]);
5478 priv->sec.flags |= (1 << i); 5450 if (sec->level == SEC_LEVEL_1) {
5479 priv->status |= STATUS_SECURITY_UPDATED; 5451 priv->ieee->sec.flags |= (1 << i);
5452 priv->status |= STATUS_SECURITY_UPDATED;
5453 } else
5454 priv->ieee->sec.flags &= ~(1 << i);
5480 } 5455 }
5481 } 5456 }
5482 5457
5483 if ((sec->flags & SEC_ACTIVE_KEY) && 5458 if ((sec->flags & SEC_ACTIVE_KEY) &&
5484 priv->sec.active_key != sec->active_key) { 5459 priv->ieee->sec.active_key != sec->active_key) {
5485 if (sec->active_key <= 3) { 5460 if (sec->active_key <= 3) {
5486 priv->sec.active_key = sec->active_key; 5461 priv->ieee->sec.active_key = sec->active_key;
5487 priv->sec.flags |= SEC_ACTIVE_KEY; 5462 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
5488 } else 5463 } else
5489 priv->sec.flags &= ~SEC_ACTIVE_KEY; 5464 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
5490 5465
5491 priv->status |= STATUS_SECURITY_UPDATED; 5466 priv->status |= STATUS_SECURITY_UPDATED;
5492 } 5467 }
5493 5468
5494 if ((sec->flags & SEC_AUTH_MODE) && 5469 if ((sec->flags & SEC_AUTH_MODE) &&
5495 (priv->sec.auth_mode != sec->auth_mode)) { 5470 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
5496 priv->sec.auth_mode = sec->auth_mode; 5471 priv->ieee->sec.auth_mode = sec->auth_mode;
5497 priv->sec.flags |= SEC_AUTH_MODE; 5472 priv->ieee->sec.flags |= SEC_AUTH_MODE;
5498 priv->status |= STATUS_SECURITY_UPDATED; 5473 priv->status |= STATUS_SECURITY_UPDATED;
5499 } 5474 }
5500 5475
5501 if (sec->flags & SEC_ENABLED && 5476 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
5502 priv->sec.enabled != sec->enabled) { 5477 priv->ieee->sec.flags |= SEC_ENABLED;
5503 priv->sec.flags |= SEC_ENABLED; 5478 priv->ieee->sec.enabled = sec->enabled;
5504 priv->sec.enabled = sec->enabled;
5505 priv->status |= STATUS_SECURITY_UPDATED; 5479 priv->status |= STATUS_SECURITY_UPDATED;
5506 force_update = 1; 5480 force_update = 1;
5507 } 5481 }
5508 5482
5509 if (sec->flags & SEC_LEVEL && 5483 if (sec->flags & SEC_ENCRYPT)
5510 priv->sec.level != sec->level) { 5484 priv->ieee->sec.encrypt = sec->encrypt;
5511 priv->sec.level = sec->level; 5485
5512 priv->sec.flags |= SEC_LEVEL; 5486 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
5487 priv->ieee->sec.level = sec->level;
5488 priv->ieee->sec.flags |= SEC_LEVEL;
5513 priv->status |= STATUS_SECURITY_UPDATED; 5489 priv->status |= STATUS_SECURITY_UPDATED;
5514 } 5490 }
5515 5491
5516 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n", 5492 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
5517 priv->sec.flags & (1<<8) ? '1' : '0', 5493 priv->ieee->sec.flags & (1 << 8) ? '1' : '0',
5518 priv->sec.flags & (1<<7) ? '1' : '0', 5494 priv->ieee->sec.flags & (1 << 7) ? '1' : '0',
5519 priv->sec.flags & (1<<6) ? '1' : '0', 5495 priv->ieee->sec.flags & (1 << 6) ? '1' : '0',
5520 priv->sec.flags & (1<<5) ? '1' : '0', 5496 priv->ieee->sec.flags & (1 << 5) ? '1' : '0',
5521 priv->sec.flags & (1<<4) ? '1' : '0', 5497 priv->ieee->sec.flags & (1 << 4) ? '1' : '0',
5522 priv->sec.flags & (1<<3) ? '1' : '0', 5498 priv->ieee->sec.flags & (1 << 3) ? '1' : '0',
5523 priv->sec.flags & (1<<2) ? '1' : '0', 5499 priv->ieee->sec.flags & (1 << 2) ? '1' : '0',
5524 priv->sec.flags & (1<<1) ? '1' : '0', 5500 priv->ieee->sec.flags & (1 << 1) ? '1' : '0',
5525 priv->sec.flags & (1<<0) ? '1' : '0'); 5501 priv->ieee->sec.flags & (1 << 0) ? '1' : '0');
5526 5502
5527/* As a temporary work around to enable WPA until we figure out why 5503/* As a temporary work around to enable WPA until we figure out why
5528 * wpa_supplicant toggles the security capability of the driver, which 5504 * wpa_supplicant toggles the security capability of the driver, which
@@ -5531,7 +5507,7 @@ static void shim__set_security(struct net_device *dev,
5531 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/ 5507 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
5532 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) 5508 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5533 ipw2100_configure_security(priv, 0); 5509 ipw2100_configure_security(priv, 0);
5534done: 5510 done:
5535 up(&priv->action_sem); 5511 up(&priv->action_sem);
5536} 5512}
5537 5513
@@ -5556,7 +5532,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5556 5532
5557 return 0; 5533 return 0;
5558 } 5534 }
5559#endif /* CONFIG_IPW2100_MONITOR */ 5535#endif /* CONFIG_IPW2100_MONITOR */
5560 5536
5561 err = ipw2100_read_mac_address(priv); 5537 err = ipw2100_read_mac_address(priv);
5562 if (err) 5538 if (err)
@@ -5576,7 +5552,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5576 return err; 5552 return err;
5577 } 5553 }
5578 5554
5579 err = ipw2100_system_config(priv, batch_mode); 5555 err = ipw2100_system_config(priv, batch_mode);
5580 if (err) 5556 if (err)
5581 return err; 5557 return err;
5582 5558
@@ -5614,8 +5590,10 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5614 return err; 5590 return err;
5615 5591
5616 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 5592 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5617 err = ipw2100_set_ibss_beacon_interval( 5593 err =
5618 priv, priv->beacon_interval, batch_mode); 5594 ipw2100_set_ibss_beacon_interval(priv,
5595 priv->beacon_interval,
5596 batch_mode);
5619 if (err) 5597 if (err)
5620 return err; 5598 return err;
5621 5599
@@ -5625,18 +5603,17 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5625 } 5603 }
5626 5604
5627 /* 5605 /*
5628 err = ipw2100_set_fragmentation_threshold( 5606 err = ipw2100_set_fragmentation_threshold(
5629 priv, priv->frag_threshold, batch_mode); 5607 priv, priv->frag_threshold, batch_mode);
5630 if (err) 5608 if (err)
5631 return err; 5609 return err;
5632 */ 5610 */
5633 5611
5634 IPW_DEBUG_INFO("exit\n"); 5612 IPW_DEBUG_INFO("exit\n");
5635 5613
5636 return 0; 5614 return 0;
5637} 5615}
5638 5616
5639
5640/************************************************************************* 5617/*************************************************************************
5641 * 5618 *
5642 * EXTERNALLY CALLED METHODS 5619 * EXTERNALLY CALLED METHODS
@@ -5669,7 +5646,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
5669 ipw2100_reset_adapter(priv); 5646 ipw2100_reset_adapter(priv);
5670 return 0; 5647 return 0;
5671 5648
5672 done: 5649 done:
5673 up(&priv->action_sem); 5650 up(&priv->action_sem);
5674 return err; 5651 return err;
5675} 5652}
@@ -5708,7 +5685,7 @@ static int ipw2100_close(struct net_device *dev)
5708 /* Flush the TX queue ... */ 5685 /* Flush the TX queue ... */
5709 while (!list_empty(&priv->tx_pend_list)) { 5686 while (!list_empty(&priv->tx_pend_list)) {
5710 element = priv->tx_pend_list.next; 5687 element = priv->tx_pend_list.next;
5711 packet = list_entry(element, struct ipw2100_tx_packet, list); 5688 packet = list_entry(element, struct ipw2100_tx_packet, list);
5712 5689
5713 list_del(element); 5690 list_del(element);
5714 DEC_STAT(&priv->tx_pend_stat); 5691 DEC_STAT(&priv->tx_pend_stat);
@@ -5726,8 +5703,6 @@ static int ipw2100_close(struct net_device *dev)
5726 return 0; 5703 return 0;
5727} 5704}
5728 5705
5729
5730
5731/* 5706/*
5732 * TODO: Fix this function... its just wrong 5707 * TODO: Fix this function... its just wrong
5733 */ 5708 */
@@ -5747,7 +5722,6 @@ static void ipw2100_tx_timeout(struct net_device *dev)
5747 schedule_reset(priv); 5722 schedule_reset(priv);
5748} 5723}
5749 5724
5750
5751/* 5725/*
5752 * TODO: reimplement it so that it reads statistics 5726 * TODO: reimplement it so that it reads statistics
5753 * from the adapter using ordinal tables 5727 * from the adapter using ordinal tables
@@ -5761,11 +5735,10 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5761 return &priv->ieee->stats; 5735 return &priv->ieee->stats;
5762} 5736}
5763 5737
5764/* Support for wpa_supplicant. Will be replaced with WEXT once 5738#if WIRELESS_EXT < 18
5765 * they get WPA support. */ 5739/* Support for wpa_supplicant before WE-18, deprecated. */
5766#ifdef CONFIG_IEEE80211_WPA
5767 5740
5768/* following definitions must match definitions in driver_ipw2100.c */ 5741/* following definitions must match definitions in driver_ipw.c */
5769 5742
5770#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 5743#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5771 5744
@@ -5796,25 +5769,26 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5796struct ipw2100_param { 5769struct ipw2100_param {
5797 u32 cmd; 5770 u32 cmd;
5798 u8 sta_addr[ETH_ALEN]; 5771 u8 sta_addr[ETH_ALEN];
5799 union { 5772 union {
5800 struct { 5773 struct {
5801 u8 name; 5774 u8 name;
5802 u32 value; 5775 u32 value;
5803 } wpa_param; 5776 } wpa_param;
5804 struct { 5777 struct {
5805 u32 len; 5778 u32 len;
5806 u8 *data; 5779 u8 reserved[32];
5780 u8 data[0];
5807 } wpa_ie; 5781 } wpa_ie;
5808 struct{ 5782 struct {
5809 int command; 5783 u32 command;
5810 int reason_code; 5784 u32 reason_code;
5811 } mlme; 5785 } mlme;
5812 struct { 5786 struct {
5813 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN]; 5787 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5814 u8 set_tx; 5788 u8 set_tx;
5815 u32 err; 5789 u32 err;
5816 u8 idx; 5790 u8 idx;
5817 u8 seq[8]; /* sequence counter (set: RX, get: TX) */ 5791 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5818 u16 key_len; 5792 u16 key_len;
5819 u8 key[0]; 5793 u8 key[0];
5820 } crypt; 5794 } crypt;
@@ -5822,38 +5796,24 @@ struct ipw2100_param {
5822 } u; 5796 } u;
5823}; 5797};
5824 5798
5825/* end of driver_ipw2100.c code */ 5799/* end of driver_ipw.c code */
5826 5800#endif /* WIRELESS_EXT < 18 */
5827static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
5828 5801
5829 struct ieee80211_device *ieee = priv->ieee; 5802static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5830 struct ieee80211_security sec = { 5803{
5831 .flags = SEC_LEVEL | SEC_ENABLED, 5804 /* This is called when wpa_supplicant loads and closes the driver
5832 }; 5805 * interface. */
5833 int ret = 0; 5806 priv->ieee->wpa_enabled = value;
5834 5807 return 0;
5835 ieee->wpa_enabled = value;
5836
5837 if (value){
5838 sec.level = SEC_LEVEL_3;
5839 sec.enabled = 1;
5840 } else {
5841 sec.level = SEC_LEVEL_0;
5842 sec.enabled = 0;
5843 }
5844
5845 if (ieee->set_security)
5846 ieee->set_security(ieee->dev, &sec);
5847 else
5848 ret = -EOPNOTSUPP;
5849
5850 return ret;
5851} 5808}
5852 5809
5853#define AUTH_ALG_OPEN_SYSTEM 0x1 5810#if WIRELESS_EXT < 18
5854#define AUTH_ALG_SHARED_KEY 0x2 5811#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
5812#define IW_AUTH_ALG_SHARED_KEY 0x2
5813#endif
5855 5814
5856static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){ 5815static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5816{
5857 5817
5858 struct ieee80211_device *ieee = priv->ieee; 5818 struct ieee80211_device *ieee = priv->ieee;
5859 struct ieee80211_security sec = { 5819 struct ieee80211_security sec = {
@@ -5861,13 +5821,14 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5861 }; 5821 };
5862 int ret = 0; 5822 int ret = 0;
5863 5823
5864 if (value & AUTH_ALG_SHARED_KEY){ 5824 if (value & IW_AUTH_ALG_SHARED_KEY) {
5865 sec.auth_mode = WLAN_AUTH_SHARED_KEY; 5825 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5866 ieee->open_wep = 0; 5826 ieee->open_wep = 0;
5867 } else { 5827 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
5868 sec.auth_mode = WLAN_AUTH_OPEN; 5828 sec.auth_mode = WLAN_AUTH_OPEN;
5869 ieee->open_wep = 1; 5829 ieee->open_wep = 1;
5870 } 5830 } else
5831 return -EINVAL;
5871 5832
5872 if (ieee->set_security) 5833 if (ieee->set_security)
5873 ieee->set_security(ieee->dev, &sec); 5834 ieee->set_security(ieee->dev, &sec);
@@ -5877,103 +5838,135 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5877 return ret; 5838 return ret;
5878} 5839}
5879 5840
5841void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5842 char *wpa_ie, int wpa_ie_len)
5843{
5880 5844
5881static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){ 5845 struct ipw2100_wpa_assoc_frame frame;
5882
5883 struct ipw2100_priv *priv = ieee80211_priv(dev);
5884 int ret=0;
5885 5846
5886 switch(name){ 5847 frame.fixed_ie_mask = 0;
5887 case IPW2100_PARAM_WPA_ENABLED:
5888 ret = ipw2100_wpa_enable(priv, value);
5889 break;
5890 5848
5891 case IPW2100_PARAM_TKIP_COUNTERMEASURES: 5849 /* copy WPA IE */
5892 priv->ieee->tkip_countermeasures=value; 5850 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5893 break; 5851 frame.var_ie_len = wpa_ie_len;
5894 5852
5895 case IPW2100_PARAM_DROP_UNENCRYPTED: 5853 /* make sure WPA is enabled */
5896 priv->ieee->drop_unencrypted=value; 5854 ipw2100_wpa_enable(priv, 1);
5897 break; 5855 ipw2100_set_wpa_ie(priv, &frame, 0);
5856}
5898 5857
5899 case IPW2100_PARAM_PRIVACY_INVOKED: 5858#if WIRELESS_EXT < 18
5900 priv->ieee->privacy_invoked=value; 5859static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5901 break; 5860{
5861 struct ipw2100_priv *priv = ieee80211_priv(dev);
5862 struct ieee80211_crypt_data *crypt;
5863 unsigned long flags;
5864 int ret = 0;
5902 5865
5903 case IPW2100_PARAM_AUTH_ALGS: 5866 switch (name) {
5904 ret = ipw2100_wpa_set_auth_algs(priv, value); 5867 case IPW2100_PARAM_WPA_ENABLED:
5905 break; 5868 ret = ipw2100_wpa_enable(priv, value);
5869 break;
5906 5870
5907 case IPW2100_PARAM_IEEE_802_1X: 5871 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5908 priv->ieee->ieee802_1x=value; 5872 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5873 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
5909 break; 5874 break;
5910 5875
5911 default: 5876 flags = crypt->ops->get_flags(crypt->priv);
5912 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5913 dev->name, name);
5914 ret = -EOPNOTSUPP;
5915 }
5916 5877
5917 return ret; 5878 if (value)
5918} 5879 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5880 else
5881 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5919 5882
5920static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){ 5883 crypt->ops->set_flags(flags, crypt->priv);
5921 5884
5922 struct ipw2100_priv *priv = ieee80211_priv(dev); 5885 break;
5923 int ret=0;
5924 5886
5925 switch(command){ 5887 case IPW2100_PARAM_DROP_UNENCRYPTED:{
5926 case IPW2100_MLME_STA_DEAUTH: 5888 /* See IW_AUTH_DROP_UNENCRYPTED handling for details */
5927 // silently ignore 5889 struct ieee80211_security sec = {
5890 .flags = SEC_ENABLED,
5891 .enabled = value,
5892 };
5893 priv->ieee->drop_unencrypted = value;
5894 /* We only change SEC_LEVEL for open mode. Others
5895 * are set by ipw_wpa_set_encryption.
5896 */
5897 if (!value) {
5898 sec.flags |= SEC_LEVEL;
5899 sec.level = SEC_LEVEL_0;
5900 } else {
5901 sec.flags |= SEC_LEVEL;
5902 sec.level = SEC_LEVEL_1;
5903 }
5904 if (priv->ieee->set_security)
5905 priv->ieee->set_security(priv->ieee->dev, &sec);
5928 break; 5906 break;
5907 }
5929 5908
5930 case IPW2100_MLME_STA_DISASSOC: 5909 case IPW2100_PARAM_PRIVACY_INVOKED:
5931 ipw2100_disassociate_bssid(priv); 5910 priv->ieee->privacy_invoked = value;
5932 break; 5911 break;
5933 5912
5934 default: 5913 case IPW2100_PARAM_AUTH_ALGS:
5935 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n", 5914 ret = ipw2100_wpa_set_auth_algs(priv, value);
5936 dev->name, command); 5915 break;
5937 ret = -EOPNOTSUPP; 5916
5917 case IPW2100_PARAM_IEEE_802_1X:
5918 priv->ieee->ieee802_1x = value;
5919 break;
5920
5921 default:
5922 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5923 dev->name, name);
5924 ret = -EOPNOTSUPP;
5938 } 5925 }
5939 5926
5940 return ret; 5927 return ret;
5941} 5928}
5942 5929
5930static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
5931{
5943 5932
5944void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, 5933 struct ipw2100_priv *priv = ieee80211_priv(dev);
5945 char *wpa_ie, int wpa_ie_len){ 5934 int ret = 0;
5946 5935
5947 struct ipw2100_wpa_assoc_frame frame; 5936 switch (command) {
5937 case IPW2100_MLME_STA_DEAUTH:
5938 // silently ignore
5939 break;
5948 5940
5949 frame.fixed_ie_mask = 0; 5941 case IPW2100_MLME_STA_DISASSOC:
5942 ipw2100_disassociate_bssid(priv);
5943 break;
5950 5944
5951 /* copy WPA IE */ 5945 default:
5952 memcpy(frame.var_ie, wpa_ie, wpa_ie_len); 5946 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
5953 frame.var_ie_len = wpa_ie_len; 5947 dev->name, command);
5948 ret = -EOPNOTSUPP;
5949 }
5954 5950
5955 /* make sure WPA is enabled */ 5951 return ret;
5956 ipw2100_wpa_enable(priv, 1);
5957 ipw2100_set_wpa_ie(priv, &frame, 0);
5958} 5952}
5959 5953
5960
5961static int ipw2100_wpa_set_wpa_ie(struct net_device *dev, 5954static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5962 struct ipw2100_param *param, int plen){ 5955 struct ipw2100_param *param, int plen)
5956{
5963 5957
5964 struct ipw2100_priv *priv = ieee80211_priv(dev); 5958 struct ipw2100_priv *priv = ieee80211_priv(dev);
5965 struct ieee80211_device *ieee = priv->ieee; 5959 struct ieee80211_device *ieee = priv->ieee;
5966 u8 *buf; 5960 u8 *buf;
5967 5961
5968 if (! ieee->wpa_enabled) 5962 if (!ieee->wpa_enabled)
5969 return -EOPNOTSUPP; 5963 return -EOPNOTSUPP;
5970 5964
5971 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || 5965 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5972 (param->u.wpa_ie.len && 5966 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
5973 param->u.wpa_ie.data==NULL))
5974 return -EINVAL; 5967 return -EINVAL;
5975 5968
5976 if (param->u.wpa_ie.len){ 5969 if (param->u.wpa_ie.len) {
5977 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); 5970 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5978 if (buf == NULL) 5971 if (buf == NULL)
5979 return -ENOMEM; 5972 return -ENOMEM;
@@ -5998,8 +5991,9 @@ static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5998/* implementation borrowed from hostap driver */ 5991/* implementation borrowed from hostap driver */
5999 5992
6000static int ipw2100_wpa_set_encryption(struct net_device *dev, 5993static int ipw2100_wpa_set_encryption(struct net_device *dev,
6001 struct ipw2100_param *param, int param_len){ 5994 struct ipw2100_param *param,
6002 5995 int param_len)
5996{
6003 int ret = 0; 5997 int ret = 0;
6004 struct ipw2100_priv *priv = ieee80211_priv(dev); 5998 struct ipw2100_priv *priv = ieee80211_priv(dev);
6005 struct ieee80211_device *ieee = priv->ieee; 5999 struct ieee80211_device *ieee = priv->ieee;
@@ -6014,9 +6008,10 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6014 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0'; 6008 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
6015 6009
6016 if (param_len != 6010 if (param_len !=
6017 (int) ((char *) param->u.crypt.key - (char *) param) + 6011 (int)((char *)param->u.crypt.key - (char *)param) +
6018 param->u.crypt.key_len){ 6012 param->u.crypt.key_len) {
6019 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len); 6013 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
6014 param->u.crypt.key_len);
6020 return -EINVAL; 6015 return -EINVAL;
6021 } 6016 }
6022 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 6017 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -6029,17 +6024,19 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6029 return -EINVAL; 6024 return -EINVAL;
6030 } 6025 }
6031 6026
6027 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
6032 if (strcmp(param->u.crypt.alg, "none") == 0) { 6028 if (strcmp(param->u.crypt.alg, "none") == 0) {
6033 if (crypt){ 6029 if (crypt) {
6034 sec.enabled = 0; 6030 sec.enabled = 0;
6031 sec.encrypt = 0;
6035 sec.level = SEC_LEVEL_0; 6032 sec.level = SEC_LEVEL_0;
6036 sec.flags |= SEC_ENABLED | SEC_LEVEL; 6033 sec.flags |= SEC_LEVEL;
6037 ieee80211_crypt_delayed_deinit(ieee, crypt); 6034 ieee80211_crypt_delayed_deinit(ieee, crypt);
6038 } 6035 }
6039 goto done; 6036 goto done;
6040 } 6037 }
6041 sec.enabled = 1; 6038 sec.enabled = 1;
6042 sec.flags |= SEC_ENABLED; 6039 sec.encrypt = 1;
6043 6040
6044 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 6041 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6045 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { 6042 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
@@ -6054,7 +6051,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6054 } 6051 }
6055 if (ops == NULL) { 6052 if (ops == NULL) {
6056 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n", 6053 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6057 dev->name, param->u.crypt.alg); 6054 dev->name, param->u.crypt.alg);
6058 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG; 6055 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6059 ret = -EINVAL; 6056 ret = -EINVAL;
6060 goto done; 6057 goto done;
@@ -6065,21 +6062,20 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6065 6062
6066 ieee80211_crypt_delayed_deinit(ieee, crypt); 6063 ieee80211_crypt_delayed_deinit(ieee, crypt);
6067 6064
6068 new_crypt = (struct ieee80211_crypt_data *) 6065 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6069 kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6070 if (new_crypt == NULL) { 6066 if (new_crypt == NULL) {
6071 ret = -ENOMEM; 6067 ret = -ENOMEM;
6072 goto done; 6068 goto done;
6073 } 6069 }
6074 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6075 new_crypt->ops = ops; 6070 new_crypt->ops = ops;
6076 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 6071 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6077 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); 6072 new_crypt->priv =
6073 new_crypt->ops->init(param->u.crypt.idx);
6078 6074
6079 if (new_crypt->priv == NULL) { 6075 if (new_crypt->priv == NULL) {
6080 kfree(new_crypt); 6076 kfree(new_crypt);
6081 param->u.crypt.err = 6077 param->u.crypt.err =
6082 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED; 6078 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6083 ret = -EINVAL; 6079 ret = -EINVAL;
6084 goto done; 6080 goto done;
6085 } 6081 }
@@ -6091,24 +6087,25 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6091 (*crypt)->ops->set_key(param->u.crypt.key, 6087 (*crypt)->ops->set_key(param->u.crypt.key,
6092 param->u.crypt.key_len, param->u.crypt.seq, 6088 param->u.crypt.key_len, param->u.crypt.seq,
6093 (*crypt)->priv) < 0) { 6089 (*crypt)->priv) < 0) {
6094 IPW_DEBUG_INFO("%s: key setting failed\n", 6090 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
6095 dev->name);
6096 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED; 6091 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6097 ret = -EINVAL; 6092 ret = -EINVAL;
6098 goto done; 6093 goto done;
6099 } 6094 }
6100 6095
6101 if (param->u.crypt.set_tx){ 6096 if (param->u.crypt.set_tx) {
6102 ieee->tx_keyidx = param->u.crypt.idx; 6097 ieee->tx_keyidx = param->u.crypt.idx;
6103 sec.active_key = param->u.crypt.idx; 6098 sec.active_key = param->u.crypt.idx;
6104 sec.flags |= SEC_ACTIVE_KEY; 6099 sec.flags |= SEC_ACTIVE_KEY;
6105 } 6100 }
6106 6101
6107 if (ops->name != NULL){ 6102 if (ops->name != NULL) {
6108 6103
6109 if (strcmp(ops->name, "WEP") == 0) { 6104 if (strcmp(ops->name, "WEP") == 0) {
6110 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len); 6105 memcpy(sec.keys[param->u.crypt.idx],
6111 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; 6106 param->u.crypt.key, param->u.crypt.key_len);
6107 sec.key_sizes[param->u.crypt.idx] =
6108 param->u.crypt.key_len;
6112 sec.flags |= (1 << param->u.crypt.idx); 6109 sec.flags |= (1 << param->u.crypt.idx);
6113 sec.flags |= SEC_LEVEL; 6110 sec.flags |= SEC_LEVEL;
6114 sec.level = SEC_LEVEL_1; 6111 sec.level = SEC_LEVEL_1;
@@ -6120,7 +6117,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6120 sec.level = SEC_LEVEL_3; 6117 sec.level = SEC_LEVEL_3;
6121 } 6118 }
6122 } 6119 }
6123 done: 6120 done:
6124 if (ieee->set_security) 6121 if (ieee->set_security)
6125 ieee->set_security(ieee->dev, &sec); 6122 ieee->set_security(ieee->dev, &sec);
6126 6123
@@ -6131,8 +6128,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6131 * the callbacks structures used to initialize the 802.11 stack. */ 6128 * the callbacks structures used to initialize the 802.11 stack. */
6132 if (ieee->reset_on_keychange && 6129 if (ieee->reset_on_keychange &&
6133 ieee->iw_mode != IW_MODE_INFRA && 6130 ieee->iw_mode != IW_MODE_INFRA &&
6134 ieee->reset_port && 6131 ieee->reset_port && ieee->reset_port(dev)) {
6135 ieee->reset_port(dev)) {
6136 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name); 6132 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6137 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED; 6133 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6138 return -EINVAL; 6134 return -EINVAL;
@@ -6141,11 +6137,11 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6141 return ret; 6137 return ret;
6142} 6138}
6143 6139
6144 6140static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
6145static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){ 6141{
6146 6142
6147 struct ipw2100_param *param; 6143 struct ipw2100_param *param;
6148 int ret=0; 6144 int ret = 0;
6149 6145
6150 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length); 6146 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6151 6147
@@ -6156,12 +6152,12 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6156 if (param == NULL) 6152 if (param == NULL)
6157 return -ENOMEM; 6153 return -ENOMEM;
6158 6154
6159 if (copy_from_user(param, p->pointer, p->length)){ 6155 if (copy_from_user(param, p->pointer, p->length)) {
6160 kfree(param); 6156 kfree(param);
6161 return -EFAULT; 6157 return -EFAULT;
6162 } 6158 }
6163 6159
6164 switch (param->cmd){ 6160 switch (param->cmd) {
6165 6161
6166 case IPW2100_CMD_SET_WPA_PARAM: 6162 case IPW2100_CMD_SET_WPA_PARAM:
6167 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name, 6163 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
@@ -6182,8 +6178,9 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6182 break; 6178 break;
6183 6179
6184 default: 6180 default:
6185 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA supplicant request: %d\n", 6181 printk(KERN_ERR DRV_NAME
6186 dev->name, param->cmd); 6182 ": %s: Unknown WPA supplicant request: %d\n", dev->name,
6183 param->cmd);
6187 ret = -EOPNOTSUPP; 6184 ret = -EOPNOTSUPP;
6188 6185
6189 } 6186 }
@@ -6194,27 +6191,23 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6194 kfree(param); 6191 kfree(param);
6195 return ret; 6192 return ret;
6196} 6193}
6197#endif /* CONFIG_IEEE80211_WPA */
6198 6194
6199static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 6195static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6200{ 6196{
6201#ifdef CONFIG_IEEE80211_WPA 6197 struct iwreq *wrq = (struct iwreq *)rq;
6202 struct iwreq *wrq = (struct iwreq *) rq; 6198 int ret = -1;
6203 int ret=-1; 6199 switch (cmd) {
6204 switch (cmd){ 6200 case IPW2100_IOCTL_WPA_SUPPLICANT:
6205 case IPW2100_IOCTL_WPA_SUPPLICANT:
6206 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data); 6201 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6207 return ret; 6202 return ret;
6208 6203
6209 default: 6204 default:
6210 return -EOPNOTSUPP; 6205 return -EOPNOTSUPP;
6211 } 6206 }
6212 6207
6213#endif /* CONFIG_IEEE80211_WPA */
6214
6215 return -EOPNOTSUPP; 6208 return -EOPNOTSUPP;
6216} 6209}
6217 6210#endif /* WIRELESS_EXT < 18 */
6218 6211
6219static void ipw_ethtool_get_drvinfo(struct net_device *dev, 6212static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6220 struct ethtool_drvinfo *info) 6213 struct ethtool_drvinfo *info)
@@ -6236,14 +6229,13 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6236 6229
6237static u32 ipw2100_ethtool_get_link(struct net_device *dev) 6230static u32 ipw2100_ethtool_get_link(struct net_device *dev)
6238{ 6231{
6239 struct ipw2100_priv *priv = ieee80211_priv(dev); 6232 struct ipw2100_priv *priv = ieee80211_priv(dev);
6240 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0; 6233 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
6241} 6234}
6242 6235
6243
6244static struct ethtool_ops ipw2100_ethtool_ops = { 6236static struct ethtool_ops ipw2100_ethtool_ops = {
6245 .get_link = ipw2100_ethtool_get_link, 6237 .get_link = ipw2100_ethtool_get_link,
6246 .get_drvinfo = ipw_ethtool_get_drvinfo, 6238 .get_drvinfo = ipw_ethtool_get_drvinfo,
6247}; 6239};
6248 6240
6249static void ipw2100_hang_check(void *adapter) 6241static void ipw2100_hang_check(void *adapter)
@@ -6288,7 +6280,6 @@ static void ipw2100_hang_check(void *adapter)
6288 spin_unlock_irqrestore(&priv->low_lock, flags); 6280 spin_unlock_irqrestore(&priv->low_lock, flags);
6289} 6281}
6290 6282
6291
6292static void ipw2100_rf_kill(void *adapter) 6283static void ipw2100_rf_kill(void *adapter)
6293{ 6284{
6294 struct ipw2100_priv *priv = adapter; 6285 struct ipw2100_priv *priv = adapter;
@@ -6313,7 +6304,7 @@ static void ipw2100_rf_kill(void *adapter)
6313 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " 6304 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6314 "enabled\n"); 6305 "enabled\n");
6315 6306
6316 exit_unlock: 6307 exit_unlock:
6317 spin_unlock_irqrestore(&priv->low_lock, flags); 6308 spin_unlock_irqrestore(&priv->low_lock, flags);
6318} 6309}
6319 6310
@@ -6321,11 +6312,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6321 6312
6322/* Look into using netdev destructor to shutdown ieee80211? */ 6313/* Look into using netdev destructor to shutdown ieee80211? */
6323 6314
6324static struct net_device *ipw2100_alloc_device( 6315static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6325 struct pci_dev *pci_dev, 6316 void __iomem * base_addr,
6326 void __iomem *base_addr, 6317 unsigned long mem_start,
6327 unsigned long mem_start, 6318 unsigned long mem_len)
6328 unsigned long mem_len)
6329{ 6319{
6330 struct ipw2100_priv *priv; 6320 struct ipw2100_priv *priv;
6331 struct net_device *dev; 6321 struct net_device *dev;
@@ -6341,17 +6331,22 @@ static struct net_device *ipw2100_alloc_device(
6341 priv->ieee->hard_start_xmit = ipw2100_tx; 6331 priv->ieee->hard_start_xmit = ipw2100_tx;
6342 priv->ieee->set_security = shim__set_security; 6332 priv->ieee->set_security = shim__set_security;
6343 6333
6334 priv->ieee->perfect_rssi = -20;
6335 priv->ieee->worst_rssi = -85;
6336
6344 dev->open = ipw2100_open; 6337 dev->open = ipw2100_open;
6345 dev->stop = ipw2100_close; 6338 dev->stop = ipw2100_close;
6346 dev->init = ipw2100_net_init; 6339 dev->init = ipw2100_net_init;
6340#if WIRELESS_EXT < 18
6347 dev->do_ioctl = ipw2100_ioctl; 6341 dev->do_ioctl = ipw2100_ioctl;
6342#endif
6348 dev->get_stats = ipw2100_stats; 6343 dev->get_stats = ipw2100_stats;
6349 dev->ethtool_ops = &ipw2100_ethtool_ops; 6344 dev->ethtool_ops = &ipw2100_ethtool_ops;
6350 dev->tx_timeout = ipw2100_tx_timeout; 6345 dev->tx_timeout = ipw2100_tx_timeout;
6351 dev->wireless_handlers = &ipw2100_wx_handler_def; 6346 dev->wireless_handlers = &ipw2100_wx_handler_def;
6352 dev->get_wireless_stats = ipw2100_wx_wireless_stats; 6347 dev->get_wireless_stats = ipw2100_wx_wireless_stats;
6353 dev->set_mac_address = ipw2100_set_address; 6348 dev->set_mac_address = ipw2100_set_address;
6354 dev->watchdog_timeo = 3*HZ; 6349 dev->watchdog_timeo = 3 * HZ;
6355 dev->irq = 0; 6350 dev->irq = 0;
6356 6351
6357 dev->base_addr = (unsigned long)base_addr; 6352 dev->base_addr = (unsigned long)base_addr;
@@ -6364,22 +6359,19 @@ static struct net_device *ipw2100_alloc_device(
6364 * ends up causing problems. So, we just handle 6359 * ends up causing problems. So, we just handle
6365 * the WX extensions through the ipw2100_ioctl interface */ 6360 * the WX extensions through the ipw2100_ioctl interface */
6366 6361
6367
6368 /* memset() puts everything to 0, so we only have explicitely set 6362 /* memset() puts everything to 0, so we only have explicitely set
6369 * those values that need to be something else */ 6363 * those values that need to be something else */
6370 6364
6371 /* If power management is turned on, default to AUTO mode */ 6365 /* If power management is turned on, default to AUTO mode */
6372 priv->power_mode = IPW_POWER_AUTO; 6366 priv->power_mode = IPW_POWER_AUTO;
6373 6367
6374 6368#ifdef CONFIG_IPW2100_MONITOR
6375 6369 priv->config |= CFG_CRC_CHECK;
6376#ifdef CONFIG_IEEE80211_WPA 6370#endif
6377 priv->ieee->wpa_enabled = 0; 6371 priv->ieee->wpa_enabled = 0;
6378 priv->ieee->tkip_countermeasures = 0;
6379 priv->ieee->drop_unencrypted = 0; 6372 priv->ieee->drop_unencrypted = 0;
6380 priv->ieee->privacy_invoked = 0; 6373 priv->ieee->privacy_invoked = 0;
6381 priv->ieee->ieee802_1x = 1; 6374 priv->ieee->ieee802_1x = 1;
6382#endif /* CONFIG_IEEE80211_WPA */
6383 6375
6384 /* Set module parameters */ 6376 /* Set module parameters */
6385 switch (mode) { 6377 switch (mode) {
@@ -6401,8 +6393,7 @@ static struct net_device *ipw2100_alloc_device(
6401 priv->status |= STATUS_RF_KILL_SW; 6393 priv->status |= STATUS_RF_KILL_SW;
6402 6394
6403 if (channel != 0 && 6395 if (channel != 0 &&
6404 ((channel >= REG_MIN_CHANNEL) && 6396 ((channel >= REG_MIN_CHANNEL) && (channel <= REG_MAX_CHANNEL))) {
6405 (channel <= REG_MAX_CHANNEL))) {
6406 priv->config |= CFG_STATIC_CHANNEL; 6397 priv->config |= CFG_STATIC_CHANNEL;
6407 priv->channel = channel; 6398 priv->channel = channel;
6408 } 6399 }
@@ -6441,12 +6432,8 @@ static struct net_device *ipw2100_alloc_device(
6441 INIT_LIST_HEAD(&priv->fw_pend_list); 6432 INIT_LIST_HEAD(&priv->fw_pend_list);
6442 INIT_STAT(&priv->fw_pend_stat); 6433 INIT_STAT(&priv->fw_pend_stat);
6443 6434
6444
6445#ifdef CONFIG_SOFTWARE_SUSPEND2
6446 priv->workqueue = create_workqueue(DRV_NAME, 0);
6447#else
6448 priv->workqueue = create_workqueue(DRV_NAME); 6435 priv->workqueue = create_workqueue(DRV_NAME);
6449#endif 6436
6450 INIT_WORK(&priv->reset_work, 6437 INIT_WORK(&priv->reset_work,
6451 (void (*)(void *))ipw2100_reset_adapter, priv); 6438 (void (*)(void *))ipw2100_reset_adapter, priv);
6452 INIT_WORK(&priv->security_work, 6439 INIT_WORK(&priv->security_work,
@@ -6535,7 +6522,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6535 return err; 6522 return err;
6536 } 6523 }
6537 6524
6538 /* We disable the RETRY_TIMEOUT register (0x41) to keep 6525 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6539 * PCI Tx retries from interfering with C3 CPU state */ 6526 * PCI Tx retries from interfering with C3 CPU state */
6540 pci_read_config_dword(pci_dev, 0x40, &val); 6527 pci_read_config_dword(pci_dev, 0x40, &val);
6541 if ((val & 0x0000ff00) != 0) 6528 if ((val & 0x0000ff00) != 0)
@@ -6566,12 +6553,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6566 ipw2100_queues_initialize(priv); 6553 ipw2100_queues_initialize(priv);
6567 6554
6568 err = request_irq(pci_dev->irq, 6555 err = request_irq(pci_dev->irq,
6569 ipw2100_interrupt, SA_SHIRQ, 6556 ipw2100_interrupt, SA_SHIRQ, dev->name, priv);
6570 dev->name, priv);
6571 if (err) { 6557 if (err) {
6572 printk(KERN_WARNING DRV_NAME 6558 printk(KERN_WARNING DRV_NAME
6573 "Error calling request_irq: %d.\n", 6559 "Error calling request_irq: %d.\n", pci_dev->irq);
6574 pci_dev->irq);
6575 goto fail; 6560 goto fail;
6576 } 6561 }
6577 dev->irq = pci_dev->irq; 6562 dev->irq = pci_dev->irq;
@@ -6606,7 +6591,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6606 6591
6607 /* perform this after register_netdev so that dev->name is set */ 6592 /* perform this after register_netdev so that dev->name is set */
6608 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6593 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6609 netif_carrier_off(dev);
6610 6594
6611 /* If the RF Kill switch is disabled, go ahead and complete the 6595 /* If the RF Kill switch is disabled, go ahead and complete the
6612 * startup sequence */ 6596 * startup sequence */
@@ -6634,10 +6618,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6634 6618
6635 return 0; 6619 return 0;
6636 6620
6637 fail_unlock: 6621 fail_unlock:
6638 up(&priv->action_sem); 6622 up(&priv->action_sem);
6639 6623
6640 fail: 6624 fail:
6641 if (dev) { 6625 if (dev) {
6642 if (registered) 6626 if (registered)
6643 unregister_netdev(dev); 6627 unregister_netdev(dev);
@@ -6653,7 +6637,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6653 6637
6654 /* These are safe to call even if they weren't allocated */ 6638 /* These are safe to call even if they weren't allocated */
6655 ipw2100_queues_free(priv); 6639 ipw2100_queues_free(priv);
6656 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6640 sysfs_remove_group(&pci_dev->dev.kobj,
6641 &ipw2100_attribute_group);
6657 6642
6658 free_ieee80211(dev); 6643 free_ieee80211(dev);
6659 pci_set_drvdata(pci_dev, NULL); 6644 pci_set_drvdata(pci_dev, NULL);
@@ -6679,7 +6664,8 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6679 priv->status &= ~STATUS_INITIALIZED; 6664 priv->status &= ~STATUS_INITIALIZED;
6680 6665
6681 dev = priv->net_dev; 6666 dev = priv->net_dev;
6682 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6667 sysfs_remove_group(&pci_dev->dev.kobj,
6668 &ipw2100_attribute_group);
6683 6669
6684#ifdef CONFIG_PM 6670#ifdef CONFIG_PM
6685 if (ipw2100_firmware.version) 6671 if (ipw2100_firmware.version)
@@ -6721,19 +6707,13 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6721 IPW_DEBUG_INFO("exit\n"); 6707 IPW_DEBUG_INFO("exit\n");
6722} 6708}
6723 6709
6724
6725#ifdef CONFIG_PM 6710#ifdef CONFIG_PM
6726#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6727static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
6728#else
6729static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) 6711static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6730#endif
6731{ 6712{
6732 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); 6713 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6733 struct net_device *dev = priv->net_dev; 6714 struct net_device *dev = priv->net_dev;
6734 6715
6735 IPW_DEBUG_INFO("%s: Going into suspend...\n", 6716 IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
6736 dev->name);
6737 6717
6738 down(&priv->action_sem); 6718 down(&priv->action_sem);
6739 if (priv->status & STATUS_INITIALIZED) { 6719 if (priv->status & STATUS_INITIALIZED) {
@@ -6745,7 +6725,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6745 netif_device_detach(dev); 6725 netif_device_detach(dev);
6746 6726
6747 pci_save_state(pci_dev); 6727 pci_save_state(pci_dev);
6748 pci_disable_device (pci_dev); 6728 pci_disable_device(pci_dev);
6749 pci_set_power_state(pci_dev, PCI_D3hot); 6729 pci_set_power_state(pci_dev, PCI_D3hot);
6750 6730
6751 up(&priv->action_sem); 6731 up(&priv->action_sem);
@@ -6764,8 +6744,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6764 6744
6765 down(&priv->action_sem); 6745 down(&priv->action_sem);
6766 6746
6767 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", 6747 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
6768 dev->name);
6769 6748
6770 pci_set_power_state(pci_dev, PCI_D0); 6749 pci_set_power_state(pci_dev, PCI_D0);
6771 pci_enable_device(pci_dev); 6750 pci_enable_device(pci_dev);
@@ -6785,9 +6764,9 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6785 * the queue of needed */ 6764 * the queue of needed */
6786 netif_device_attach(dev); 6765 netif_device_attach(dev);
6787 6766
6788 /* Bring the device back up */ 6767 /* Bring the device back up */
6789 if (!(priv->status & STATUS_RF_KILL_SW)) 6768 if (!(priv->status & STATUS_RF_KILL_SW))
6790 ipw2100_up(priv, 0); 6769 ipw2100_up(priv, 0);
6791 6770
6792 up(&priv->action_sem); 6771 up(&priv->action_sem);
6793 6772
@@ -6795,56 +6774,55 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6795} 6774}
6796#endif 6775#endif
6797 6776
6798
6799#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } 6777#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
6800 6778
6801static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = { 6779static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
6802 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */ 6780 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
6803 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */ 6781 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
6804 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */ 6782 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
6805 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */ 6783 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
6806 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */ 6784 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
6807 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */ 6785 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
6808 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */ 6786 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
6809 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */ 6787 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
6810 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */ 6788 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
6811 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */ 6789 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
6812 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */ 6790 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
6813 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */ 6791 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
6814 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */ 6792 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
6815 6793
6816 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */ 6794 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
6817 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */ 6795 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
6818 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */ 6796 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
6819 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */ 6797 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
6820 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */ 6798 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
6821 6799
6822 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */ 6800 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
6823 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */ 6801 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
6824 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */ 6802 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
6825 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */ 6803 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
6826 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */ 6804 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
6827 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */ 6805 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
6828 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */ 6806 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
6829 6807
6830 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */ 6808 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
6831 6809
6832 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */ 6810 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
6833 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */ 6811 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
6834 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */ 6812 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
6835 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */ 6813 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
6836 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */ 6814 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
6837 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */ 6815 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
6838 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */ 6816 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
6839 6817
6840 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */ 6818 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
6841 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */ 6819 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
6842 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */ 6820 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
6843 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */ 6821 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
6844 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */ 6822 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
6845 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */ 6823 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
6846 6824
6847 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */ 6825 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
6848 {0,}, 6826 {0,},
6849}; 6827};
6850 6828
@@ -6861,7 +6839,6 @@ static struct pci_driver ipw2100_pci_driver = {
6861#endif 6839#endif
6862}; 6840};
6863 6841
6864
6865/** 6842/**
6866 * Initialize the ipw2100 driver/module 6843 * Initialize the ipw2100 driver/module
6867 * 6844 *
@@ -6878,10 +6855,6 @@ static int __init ipw2100_init(void)
6878 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 6855 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6879 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); 6856 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6880 6857
6881#ifdef CONFIG_IEEE80211_NOWEP
6882 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6883#endif
6884
6885 ret = pci_module_init(&ipw2100_pci_driver); 6858 ret = pci_module_init(&ipw2100_pci_driver);
6886 6859
6887#ifdef CONFIG_IPW_DEBUG 6860#ifdef CONFIG_IPW_DEBUG
@@ -6893,7 +6866,6 @@ static int __init ipw2100_init(void)
6893 return ret; 6866 return ret;
6894} 6867}
6895 6868
6896
6897/** 6869/**
6898 * Cleanup ipw2100 driver registration 6870 * Cleanup ipw2100 driver registration
6899 */ 6871 */
@@ -6949,7 +6921,6 @@ static int ipw2100_wx_get_name(struct net_device *dev,
6949 return 0; 6921 return 0;
6950} 6922}
6951 6923
6952
6953static int ipw2100_wx_set_freq(struct net_device *dev, 6924static int ipw2100_wx_set_freq(struct net_device *dev,
6954 struct iw_request_info *info, 6925 struct iw_request_info *info,
6955 union iwreq_data *wrqu, char *extra) 6926 union iwreq_data *wrqu, char *extra)
@@ -6969,8 +6940,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6969 6940
6970 /* if setting by freq convert to channel */ 6941 /* if setting by freq convert to channel */
6971 if (fwrq->e == 1) { 6942 if (fwrq->e == 1) {
6972 if ((fwrq->m >= (int) 2.412e8 && 6943 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) {
6973 fwrq->m <= (int) 2.487e8)) {
6974 int f = fwrq->m / 100000; 6944 int f = fwrq->m / 100000;
6975 int c = 0; 6945 int c = 0;
6976 6946
@@ -6984,19 +6954,19 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6984 } 6954 }
6985 } 6955 }
6986 6956
6987 if (fwrq->e > 0 || fwrq->m > 1000) 6957 if (fwrq->e > 0 || fwrq->m > 1000) {
6988 return -EOPNOTSUPP; 6958 err = -EOPNOTSUPP;
6989 else { /* Set the channel */ 6959 goto done;
6960 } else { /* Set the channel */
6990 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 6961 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6991 err = ipw2100_set_channel(priv, fwrq->m, 0); 6962 err = ipw2100_set_channel(priv, fwrq->m, 0);
6992 } 6963 }
6993 6964
6994 done: 6965 done:
6995 up(&priv->action_sem); 6966 up(&priv->action_sem);
6996 return err; 6967 return err;
6997} 6968}
6998 6969
6999
7000static int ipw2100_wx_get_freq(struct net_device *dev, 6970static int ipw2100_wx_get_freq(struct net_device *dev,
7001 struct iw_request_info *info, 6971 struct iw_request_info *info,
7002 union iwreq_data *wrqu, char *extra) 6972 union iwreq_data *wrqu, char *extra)
@@ -7045,7 +7015,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7045 case IW_MODE_MONITOR: 7015 case IW_MODE_MONITOR:
7046 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR); 7016 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7047 break; 7017 break;
7048#endif /* CONFIG_IPW2100_MONITOR */ 7018#endif /* CONFIG_IPW2100_MONITOR */
7049 case IW_MODE_ADHOC: 7019 case IW_MODE_ADHOC:
7050 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC); 7020 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
7051 break; 7021 break;
@@ -7056,9 +7026,9 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7056 break; 7026 break;
7057 } 7027 }
7058 7028
7059done: 7029 done:
7060 up(&priv->action_sem); 7030 up(&priv->action_sem);
7061 return err; 7031 return err;
7062} 7032}
7063 7033
7064static int ipw2100_wx_get_mode(struct net_device *dev, 7034static int ipw2100_wx_get_mode(struct net_device *dev,
@@ -7077,7 +7047,6 @@ static int ipw2100_wx_get_mode(struct net_device *dev,
7077 return 0; 7047 return 0;
7078} 7048}
7079 7049
7080
7081#define POWER_MODES 5 7050#define POWER_MODES 5
7082 7051
7083/* Values are in microsecond */ 7052/* Values are in microsecond */
@@ -7124,19 +7093,19 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7124 /* ~5 Mb/s real (802.11b) */ 7093 /* ~5 Mb/s real (802.11b) */
7125 range->throughput = 5 * 1000 * 1000; 7094 range->throughput = 5 * 1000 * 1000;
7126 7095
7127// range->sensitivity; /* signal level threshold range */ 7096// range->sensitivity; /* signal level threshold range */
7128 7097
7129 range->max_qual.qual = 100; 7098 range->max_qual.qual = 100;
7130 /* TODO: Find real max RSSI and stick here */ 7099 /* TODO: Find real max RSSI and stick here */
7131 range->max_qual.level = 0; 7100 range->max_qual.level = 0;
7132 range->max_qual.noise = 0; 7101 range->max_qual.noise = 0;
7133 range->max_qual.updated = 7; /* Updated all three */ 7102 range->max_qual.updated = 7; /* Updated all three */
7134 7103
7135 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ 7104 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
7136 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ 7105 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
7137 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM; 7106 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
7138 range->avg_qual.noise = 0; 7107 range->avg_qual.noise = 0;
7139 range->avg_qual.updated = 7; /* Updated all three */ 7108 range->avg_qual.updated = 7; /* Updated all three */
7140 7109
7141 range->num_bitrates = RATE_COUNT; 7110 range->num_bitrates = RATE_COUNT;
7142 7111
@@ -7150,61 +7119,62 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7150 range->max_frag = MAX_FRAG_THRESHOLD; 7119 range->max_frag = MAX_FRAG_THRESHOLD;
7151 7120
7152 range->min_pmp = period_duration[0]; /* Minimal PM period */ 7121 range->min_pmp = period_duration[0]; /* Minimal PM period */
7153 range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */ 7122 range->max_pmp = period_duration[POWER_MODES - 1]; /* Maximal PM period */
7154 range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */ 7123 range->min_pmt = timeout_duration[POWER_MODES - 1]; /* Minimal PM timeout */
7155 range->max_pmt = timeout_duration[0];/* Maximal PM timeout */ 7124 range->max_pmt = timeout_duration[0]; /* Maximal PM timeout */
7156 7125
7157 /* How to decode max/min PM period */ 7126 /* How to decode max/min PM period */
7158 range->pmp_flags = IW_POWER_PERIOD; 7127 range->pmp_flags = IW_POWER_PERIOD;
7159 /* How to decode max/min PM period */ 7128 /* How to decode max/min PM period */
7160 range->pmt_flags = IW_POWER_TIMEOUT; 7129 range->pmt_flags = IW_POWER_TIMEOUT;
7161 /* What PM options are supported */ 7130 /* What PM options are supported */
7162 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD; 7131 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
7163 7132
7164 range->encoding_size[0] = 5; 7133 range->encoding_size[0] = 5;
7165 range->encoding_size[1] = 13; /* Different token sizes */ 7134 range->encoding_size[1] = 13; /* Different token sizes */
7166 range->num_encoding_sizes = 2; /* Number of entry in the list */ 7135 range->num_encoding_sizes = 2; /* Number of entry in the list */
7167 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */ 7136 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
7168// range->encoding_login_index; /* token index for login token */ 7137// range->encoding_login_index; /* token index for login token */
7169 7138
7170 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7139 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7171 range->txpower_capa = IW_TXPOW_DBM; 7140 range->txpower_capa = IW_TXPOW_DBM;
7172 range->num_txpower = IW_MAX_TXPOWER; 7141 range->num_txpower = IW_MAX_TXPOWER;
7173 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER; 7142 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16);
7174 i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) / 7143 i < IW_MAX_TXPOWER;
7175 (IW_MAX_TXPOWER - 1)) 7144 i++, level -=
7145 ((IPW_TX_POWER_MAX_DBM -
7146 IPW_TX_POWER_MIN_DBM) * 16) / (IW_MAX_TXPOWER - 1))
7176 range->txpower[i] = level / 16; 7147 range->txpower[i] = level / 16;
7177 } else { 7148 } else {
7178 range->txpower_capa = 0; 7149 range->txpower_capa = 0;
7179 range->num_txpower = 0; 7150 range->num_txpower = 0;
7180 } 7151 }
7181 7152
7182
7183 /* Set the Wireless Extension versions */ 7153 /* Set the Wireless Extension versions */
7184 range->we_version_compiled = WIRELESS_EXT; 7154 range->we_version_compiled = WIRELESS_EXT;
7185 range->we_version_source = 16; 7155 range->we_version_source = 16;
7186 7156
7187// range->retry_capa; /* What retry options are supported */ 7157// range->retry_capa; /* What retry options are supported */
7188// range->retry_flags; /* How to decode max/min retry limit */ 7158// range->retry_flags; /* How to decode max/min retry limit */
7189// range->r_time_flags; /* How to decode max/min retry life */ 7159// range->r_time_flags; /* How to decode max/min retry life */
7190// range->min_retry; /* Minimal number of retries */ 7160// range->min_retry; /* Minimal number of retries */
7191// range->max_retry; /* Maximal number of retries */ 7161// range->max_retry; /* Maximal number of retries */
7192// range->min_r_time; /* Minimal retry lifetime */ 7162// range->min_r_time; /* Minimal retry lifetime */
7193// range->max_r_time; /* Maximal retry lifetime */ 7163// range->max_r_time; /* Maximal retry lifetime */
7194 7164
7195 range->num_channels = FREQ_COUNT; 7165 range->num_channels = FREQ_COUNT;
7196 7166
7197 val = 0; 7167 val = 0;
7198 for (i = 0; i < FREQ_COUNT; i++) { 7168 for (i = 0; i < FREQ_COUNT; i++) {
7199 // TODO: Include only legal frequencies for some countries 7169 // TODO: Include only legal frequencies for some countries
7200// if (local->channel_mask & (1 << i)) { 7170// if (local->channel_mask & (1 << i)) {
7201 range->freq[val].i = i + 1; 7171 range->freq[val].i = i + 1;
7202 range->freq[val].m = ipw2100_frequencies[i] * 100000; 7172 range->freq[val].m = ipw2100_frequencies[i] * 100000;
7203 range->freq[val].e = 1; 7173 range->freq[val].e = 1;
7204 val++; 7174 val++;
7205// } 7175// }
7206 if (val == IW_MAX_FREQUENCIES) 7176 if (val == IW_MAX_FREQUENCIES)
7207 break; 7177 break;
7208 } 7178 }
7209 range->num_frequency = val; 7179 range->num_frequency = val;
7210 7180
@@ -7259,7 +7229,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
7259 wrqu->ap_addr.sa_data[4] & 0xff, 7229 wrqu->ap_addr.sa_data[4] & 0xff,
7260 wrqu->ap_addr.sa_data[5] & 0xff); 7230 wrqu->ap_addr.sa_data[5] & 0xff);
7261 7231
7262 done: 7232 done:
7263 up(&priv->action_sem); 7233 up(&priv->action_sem);
7264 return err; 7234 return err;
7265} 7235}
@@ -7276,10 +7246,9 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
7276 7246
7277 /* If we are associated, trying to associate, or have a statically 7247 /* If we are associated, trying to associate, or have a statically
7278 * configured BSSID then return that; otherwise return ANY */ 7248 * configured BSSID then return that; otherwise return ANY */
7279 if (priv->config & CFG_STATIC_BSSID || 7249 if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) {
7280 priv->status & STATUS_ASSOCIATED) {
7281 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 7250 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7282 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 7251 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
7283 } else 7252 } else
7284 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 7253 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7285 7254
@@ -7293,7 +7262,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7293 union iwreq_data *wrqu, char *extra) 7262 union iwreq_data *wrqu, char *extra)
7294{ 7263{
7295 struct ipw2100_priv *priv = ieee80211_priv(dev); 7264 struct ipw2100_priv *priv = ieee80211_priv(dev);
7296 char *essid = ""; /* ANY */ 7265 char *essid = ""; /* ANY */
7297 int length = 0; 7266 int length = 0;
7298 int err = 0; 7267 int err = 0;
7299 7268
@@ -7333,7 +7302,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7333 7302
7334 err = ipw2100_set_essid(priv, essid, length, 0); 7303 err = ipw2100_set_essid(priv, essid, length, 0);
7335 7304
7336 done: 7305 done:
7337 up(&priv->action_sem); 7306 up(&priv->action_sem);
7338 return err; 7307 return err;
7339} 7308}
@@ -7350,17 +7319,16 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
7350 7319
7351 /* If we are associated, trying to associate, or have a statically 7320 /* If we are associated, trying to associate, or have a statically
7352 * configured ESSID then return that; otherwise return ANY */ 7321 * configured ESSID then return that; otherwise return ANY */
7353 if (priv->config & CFG_STATIC_ESSID || 7322 if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) {
7354 priv->status & STATUS_ASSOCIATED) {
7355 IPW_DEBUG_WX("Getting essid: '%s'\n", 7323 IPW_DEBUG_WX("Getting essid: '%s'\n",
7356 escape_essid(priv->essid, priv->essid_len)); 7324 escape_essid(priv->essid, priv->essid_len));
7357 memcpy(extra, priv->essid, priv->essid_len); 7325 memcpy(extra, priv->essid, priv->essid_len);
7358 wrqu->essid.length = priv->essid_len; 7326 wrqu->essid.length = priv->essid_len;
7359 wrqu->essid.flags = 1; /* active */ 7327 wrqu->essid.flags = 1; /* active */
7360 } else { 7328 } else {
7361 IPW_DEBUG_WX("Getting essid: ANY\n"); 7329 IPW_DEBUG_WX("Getting essid: ANY\n");
7362 wrqu->essid.length = 0; 7330 wrqu->essid.length = 0;
7363 wrqu->essid.flags = 0; /* active */ 7331 wrqu->essid.flags = 0; /* active */
7364 } 7332 }
7365 7333
7366 return 0; 7334 return 0;
@@ -7379,9 +7347,9 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
7379 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 7347 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7380 return -E2BIG; 7348 return -E2BIG;
7381 7349
7382 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick)); 7350 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
7383 memset(priv->nick, 0, sizeof(priv->nick)); 7351 memset(priv->nick, 0, sizeof(priv->nick));
7384 memcpy(priv->nick, extra, wrqu->data.length); 7352 memcpy(priv->nick, extra, wrqu->data.length);
7385 7353
7386 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick); 7354 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
7387 7355
@@ -7400,7 +7368,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
7400 7368
7401 wrqu->data.length = strlen(priv->nick) + 1; 7369 wrqu->data.length = strlen(priv->nick) + 1;
7402 memcpy(extra, priv->nick, wrqu->data.length); 7370 memcpy(extra, priv->nick, wrqu->data.length);
7403 wrqu->data.flags = 1; /* active */ 7371 wrqu->data.flags = 1; /* active */
7404 7372
7405 IPW_DEBUG_WX("GET Nickname -> %s \n", extra); 7373 IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
7406 7374
@@ -7442,12 +7410,11 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
7442 err = ipw2100_set_tx_rates(priv, rate, 0); 7410 err = ipw2100_set_tx_rates(priv, rate, 0);
7443 7411
7444 IPW_DEBUG_WX("SET Rate -> %04X \n", rate); 7412 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7445 done: 7413 done:
7446 up(&priv->action_sem); 7414 up(&priv->action_sem);
7447 return err; 7415 return err;
7448} 7416}
7449 7417
7450
7451static int ipw2100_wx_get_rate(struct net_device *dev, 7418static int ipw2100_wx_get_rate(struct net_device *dev,
7452 struct iw_request_info *info, 7419 struct iw_request_info *info,
7453 union iwreq_data *wrqu, char *extra) 7420 union iwreq_data *wrqu, char *extra)
@@ -7495,7 +7462,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7495 7462
7496 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 7463 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7497 7464
7498 done: 7465 done:
7499 up(&priv->action_sem); 7466 up(&priv->action_sem);
7500 return err; 7467 return err;
7501} 7468}
@@ -7520,8 +7487,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7520 if (wrqu->rts.disabled) 7487 if (wrqu->rts.disabled)
7521 value = priv->rts_threshold | RTS_DISABLED; 7488 value = priv->rts_threshold | RTS_DISABLED;
7522 else { 7489 else {
7523 if (wrqu->rts.value < 1 || 7490 if (wrqu->rts.value < 1 || wrqu->rts.value > 2304) {
7524 wrqu->rts.value > 2304) {
7525 err = -EINVAL; 7491 err = -EINVAL;
7526 goto done; 7492 goto done;
7527 } 7493 }
@@ -7531,7 +7497,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7531 err = ipw2100_set_rts_threshold(priv, value); 7497 err = ipw2100_set_rts_threshold(priv, value);
7532 7498
7533 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); 7499 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7534 done: 7500 done:
7535 up(&priv->action_sem); 7501 up(&priv->action_sem);
7536 return err; 7502 return err;
7537} 7503}
@@ -7547,7 +7513,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
7547 struct ipw2100_priv *priv = ieee80211_priv(dev); 7513 struct ipw2100_priv *priv = ieee80211_priv(dev);
7548 7514
7549 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED; 7515 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
7550 wrqu->rts.fixed = 1; /* no auto select */ 7516 wrqu->rts.fixed = 1; /* no auto select */
7551 7517
7552 /* If RTS is set to the default value, then it is disabled */ 7518 /* If RTS is set to the default value, then it is disabled */
7553 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0; 7519 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
@@ -7574,8 +7540,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7574 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM) 7540 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
7575 return -EINVAL; 7541 return -EINVAL;
7576 7542
7577 value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 / 7543 value = wrqu->txpower.value;
7578 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
7579 } 7544 }
7580 7545
7581 down(&priv->action_sem); 7546 down(&priv->action_sem);
@@ -7588,7 +7553,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7588 7553
7589 IPW_DEBUG_WX("SET TX Power -> %d \n", value); 7554 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7590 7555
7591 done: 7556 done:
7592 up(&priv->action_sem); 7557 up(&priv->action_sem);
7593 return err; 7558 return err;
7594} 7559}
@@ -7615,11 +7580,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
7615 } else { 7580 } else {
7616 wrqu->power.disabled = 0; 7581 wrqu->power.disabled = 0;
7617 wrqu->power.fixed = 1; 7582 wrqu->power.fixed = 1;
7618 wrqu->power.value = 7583 wrqu->power.value = priv->tx_power;
7619 (priv->tx_power *
7620 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
7621 (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
7622 IPW_TX_POWER_MIN_DBM;
7623 } 7584 }
7624 7585
7625 wrqu->power.flags = IW_TXPOW_DBM; 7586 wrqu->power.flags = IW_TXPOW_DBM;
@@ -7684,8 +7645,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7684 struct ipw2100_priv *priv = ieee80211_priv(dev); 7645 struct ipw2100_priv *priv = ieee80211_priv(dev);
7685 int err = 0; 7646 int err = 0;
7686 7647
7687 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 7648 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
7688 wrqu->retry.disabled)
7689 return -EINVAL; 7649 return -EINVAL;
7690 7650
7691 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) 7651 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
@@ -7700,14 +7660,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7700 if (wrqu->retry.flags & IW_RETRY_MIN) { 7660 if (wrqu->retry.flags & IW_RETRY_MIN) {
7701 err = ipw2100_set_short_retry(priv, wrqu->retry.value); 7661 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7702 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", 7662 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7703 wrqu->retry.value); 7663 wrqu->retry.value);
7704 goto done; 7664 goto done;
7705 } 7665 }
7706 7666
7707 if (wrqu->retry.flags & IW_RETRY_MAX) { 7667 if (wrqu->retry.flags & IW_RETRY_MAX) {
7708 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7668 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7709 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", 7669 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7710 wrqu->retry.value); 7670 wrqu->retry.value);
7711 goto done; 7671 goto done;
7712 } 7672 }
7713 7673
@@ -7717,7 +7677,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7717 7677
7718 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); 7678 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7719 7679
7720 done: 7680 done:
7721 up(&priv->action_sem); 7681 up(&priv->action_sem);
7722 return err; 7682 return err;
7723} 7683}
@@ -7732,20 +7692,19 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7732 7692
7733 struct ipw2100_priv *priv = ieee80211_priv(dev); 7693 struct ipw2100_priv *priv = ieee80211_priv(dev);
7734 7694
7735 wrqu->retry.disabled = 0; /* can't be disabled */ 7695 wrqu->retry.disabled = 0; /* can't be disabled */
7736 7696
7737 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 7697 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
7738 IW_RETRY_LIFETIME)
7739 return -EINVAL; 7698 return -EINVAL;
7740 7699
7741 if (wrqu->retry.flags & IW_RETRY_MAX) { 7700 if (wrqu->retry.flags & IW_RETRY_MAX) {
7742 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; 7701 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
7743 wrqu->retry.value = priv->long_retry_limit; 7702 wrqu->retry.value = priv->long_retry_limit;
7744 } else { 7703 } else {
7745 wrqu->retry.flags = 7704 wrqu->retry.flags =
7746 (priv->short_retry_limit != 7705 (priv->short_retry_limit !=
7747 priv->long_retry_limit) ? 7706 priv->long_retry_limit) ?
7748 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT; 7707 IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
7749 7708
7750 wrqu->retry.value = priv->short_retry_limit; 7709 wrqu->retry.value = priv->short_retry_limit;
7751 } 7710 }
@@ -7769,15 +7728,14 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7769 } 7728 }
7770 7729
7771 IPW_DEBUG_WX("Initiating scan...\n"); 7730 IPW_DEBUG_WX("Initiating scan...\n");
7772 if (ipw2100_set_scan_options(priv) || 7731 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
7773 ipw2100_start_scan(priv)) {
7774 IPW_DEBUG_WX("Start scan failed.\n"); 7732 IPW_DEBUG_WX("Start scan failed.\n");
7775 7733
7776 /* TODO: Mark a scan as pending so when hardware initialized 7734 /* TODO: Mark a scan as pending so when hardware initialized
7777 * a scan starts */ 7735 * a scan starts */
7778 } 7736 }
7779 7737
7780 done: 7738 done:
7781 up(&priv->action_sem); 7739 up(&priv->action_sem);
7782 return err; 7740 return err;
7783} 7741}
@@ -7794,7 +7752,6 @@ static int ipw2100_wx_get_scan(struct net_device *dev,
7794 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra); 7752 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7795} 7753}
7796 7754
7797
7798/* 7755/*
7799 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c 7756 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
7800 */ 7757 */
@@ -7823,8 +7780,8 @@ static int ipw2100_wx_get_encode(struct net_device *dev,
7823} 7780}
7824 7781
7825static int ipw2100_wx_set_power(struct net_device *dev, 7782static int ipw2100_wx_set_power(struct net_device *dev,
7826 struct iw_request_info *info, 7783 struct iw_request_info *info,
7827 union iwreq_data *wrqu, char *extra) 7784 union iwreq_data *wrqu, char *extra)
7828{ 7785{
7829 struct ipw2100_priv *priv = ieee80211_priv(dev); 7786 struct ipw2100_priv *priv = ieee80211_priv(dev);
7830 int err = 0; 7787 int err = 0;
@@ -7843,11 +7800,11 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7843 } 7800 }
7844 7801
7845 switch (wrqu->power.flags & IW_POWER_MODE) { 7802 switch (wrqu->power.flags & IW_POWER_MODE) {
7846 case IW_POWER_ON: /* If not specified */ 7803 case IW_POWER_ON: /* If not specified */
7847 case IW_POWER_MODE: /* If set all mask */ 7804 case IW_POWER_MODE: /* If set all mask */
7848 case IW_POWER_ALL_R: /* If explicitely state all */ 7805 case IW_POWER_ALL_R: /* If explicitely state all */
7849 break; 7806 break;
7850 default: /* Otherwise we don't support it */ 7807 default: /* Otherwise we don't support it */
7851 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 7808 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7852 wrqu->power.flags); 7809 wrqu->power.flags);
7853 err = -EOPNOTSUPP; 7810 err = -EOPNOTSUPP;
@@ -7859,18 +7816,17 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7859 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; 7816 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7860 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 7817 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7861 7818
7862 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", 7819 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
7863 priv->power_mode);
7864 7820
7865 done: 7821 done:
7866 up(&priv->action_sem); 7822 up(&priv->action_sem);
7867 return err; 7823 return err;
7868 7824
7869} 7825}
7870 7826
7871static int ipw2100_wx_get_power(struct net_device *dev, 7827static int ipw2100_wx_get_power(struct net_device *dev,
7872 struct iw_request_info *info, 7828 struct iw_request_info *info,
7873 union iwreq_data *wrqu, char *extra) 7829 union iwreq_data *wrqu, char *extra)
7874{ 7830{
7875 /* 7831 /*
7876 * This can be called at any time. No action lock required 7832 * This can be called at any time. No action lock required
@@ -7878,9 +7834,9 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7878 7834
7879 struct ipw2100_priv *priv = ieee80211_priv(dev); 7835 struct ipw2100_priv *priv = ieee80211_priv(dev);
7880 7836
7881 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 7837 if (!(priv->power_mode & IPW_POWER_ENABLED))
7882 wrqu->power.disabled = 1; 7838 wrqu->power.disabled = 1;
7883 } else { 7839 else {
7884 wrqu->power.disabled = 0; 7840 wrqu->power.disabled = 0;
7885 wrqu->power.flags = 0; 7841 wrqu->power.flags = 0;
7886 } 7842 }
@@ -7890,6 +7846,269 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7890 return 0; 7846 return 0;
7891} 7847}
7892 7848
7849#if WIRELESS_EXT > 17
7850/*
7851 * WE-18 WPA support
7852 */
7853
7854/* SIOCSIWGENIE */
7855static int ipw2100_wx_set_genie(struct net_device *dev,
7856 struct iw_request_info *info,
7857 union iwreq_data *wrqu, char *extra)
7858{
7859
7860 struct ipw2100_priv *priv = ieee80211_priv(dev);
7861 struct ieee80211_device *ieee = priv->ieee;
7862 u8 *buf;
7863
7864 if (!ieee->wpa_enabled)
7865 return -EOPNOTSUPP;
7866
7867 if (wrqu->data.length > MAX_WPA_IE_LEN ||
7868 (wrqu->data.length && extra == NULL))
7869 return -EINVAL;
7870
7871 if (wrqu->data.length) {
7872 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
7873 if (buf == NULL)
7874 return -ENOMEM;
7875
7876 memcpy(buf, extra, wrqu->data.length);
7877 kfree(ieee->wpa_ie);
7878 ieee->wpa_ie = buf;
7879 ieee->wpa_ie_len = wrqu->data.length;
7880 } else {
7881 kfree(ieee->wpa_ie);
7882 ieee->wpa_ie = NULL;
7883 ieee->wpa_ie_len = 0;
7884 }
7885
7886 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
7887
7888 return 0;
7889}
7890
7891/* SIOCGIWGENIE */
7892static int ipw2100_wx_get_genie(struct net_device *dev,
7893 struct iw_request_info *info,
7894 union iwreq_data *wrqu, char *extra)
7895{
7896 struct ipw2100_priv *priv = ieee80211_priv(dev);
7897 struct ieee80211_device *ieee = priv->ieee;
7898
7899 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
7900 wrqu->data.length = 0;
7901 return 0;
7902 }
7903
7904 if (wrqu->data.length < ieee->wpa_ie_len)
7905 return -E2BIG;
7906
7907 wrqu->data.length = ieee->wpa_ie_len;
7908 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
7909
7910 return 0;
7911}
7912
7913/* SIOCSIWAUTH */
7914static int ipw2100_wx_set_auth(struct net_device *dev,
7915 struct iw_request_info *info,
7916 union iwreq_data *wrqu, char *extra)
7917{
7918 struct ipw2100_priv *priv = ieee80211_priv(dev);
7919 struct ieee80211_device *ieee = priv->ieee;
7920 struct iw_param *param = &wrqu->param;
7921 struct ieee80211_crypt_data *crypt;
7922 unsigned long flags;
7923 int ret = 0;
7924
7925 switch (param->flags & IW_AUTH_INDEX) {
7926 case IW_AUTH_WPA_VERSION:
7927 case IW_AUTH_CIPHER_PAIRWISE:
7928 case IW_AUTH_CIPHER_GROUP:
7929 case IW_AUTH_KEY_MGMT:
7930 /*
7931 * ipw2200 does not use these parameters
7932 */
7933 break;
7934
7935 case IW_AUTH_TKIP_COUNTERMEASURES:
7936 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
7937 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
7938 break;
7939
7940 flags = crypt->ops->get_flags(crypt->priv);
7941
7942 if (param->value)
7943 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7944 else
7945 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7946
7947 crypt->ops->set_flags(flags, crypt->priv);
7948
7949 break;
7950
7951 case IW_AUTH_DROP_UNENCRYPTED:{
7952 /* HACK:
7953 *
7954 * wpa_supplicant calls set_wpa_enabled when the driver
7955 * is loaded and unloaded, regardless of if WPA is being
7956 * used. No other calls are made which can be used to
7957 * determine if encryption will be used or not prior to
7958 * association being expected. If encryption is not being
7959 * used, drop_unencrypted is set to false, else true -- we
7960 * can use this to determine if the CAP_PRIVACY_ON bit should
7961 * be set.
7962 */
7963 struct ieee80211_security sec = {
7964 .flags = SEC_ENABLED,
7965 .enabled = param->value,
7966 };
7967 priv->ieee->drop_unencrypted = param->value;
7968 /* We only change SEC_LEVEL for open mode. Others
7969 * are set by ipw_wpa_set_encryption.
7970 */
7971 if (!param->value) {
7972 sec.flags |= SEC_LEVEL;
7973 sec.level = SEC_LEVEL_0;
7974 } else {
7975 sec.flags |= SEC_LEVEL;
7976 sec.level = SEC_LEVEL_1;
7977 }
7978 if (priv->ieee->set_security)
7979 priv->ieee->set_security(priv->ieee->dev, &sec);
7980 break;
7981 }
7982
7983 case IW_AUTH_80211_AUTH_ALG:
7984 ret = ipw2100_wpa_set_auth_algs(priv, param->value);
7985 break;
7986
7987 case IW_AUTH_WPA_ENABLED:
7988 ret = ipw2100_wpa_enable(priv, param->value);
7989 break;
7990
7991 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
7992 ieee->ieee802_1x = param->value;
7993 break;
7994
7995 //case IW_AUTH_ROAMING_CONTROL:
7996 case IW_AUTH_PRIVACY_INVOKED:
7997 ieee->privacy_invoked = param->value;
7998 break;
7999
8000 default:
8001 return -EOPNOTSUPP;
8002 }
8003 return ret;
8004}
8005
8006/* SIOCGIWAUTH */
8007static int ipw2100_wx_get_auth(struct net_device *dev,
8008 struct iw_request_info *info,
8009 union iwreq_data *wrqu, char *extra)
8010{
8011 struct ipw2100_priv *priv = ieee80211_priv(dev);
8012 struct ieee80211_device *ieee = priv->ieee;
8013 struct ieee80211_crypt_data *crypt;
8014 struct iw_param *param = &wrqu->param;
8015 int ret = 0;
8016
8017 switch (param->flags & IW_AUTH_INDEX) {
8018 case IW_AUTH_WPA_VERSION:
8019 case IW_AUTH_CIPHER_PAIRWISE:
8020 case IW_AUTH_CIPHER_GROUP:
8021 case IW_AUTH_KEY_MGMT:
8022 /*
8023 * wpa_supplicant will control these internally
8024 */
8025 ret = -EOPNOTSUPP;
8026 break;
8027
8028 case IW_AUTH_TKIP_COUNTERMEASURES:
8029 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
8030 if (!crypt || !crypt->ops->get_flags) {
8031 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
8032 "crypt not set!\n");
8033 break;
8034 }
8035
8036 param->value = (crypt->ops->get_flags(crypt->priv) &
8037 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
8038
8039 break;
8040
8041 case IW_AUTH_DROP_UNENCRYPTED:
8042 param->value = ieee->drop_unencrypted;
8043 break;
8044
8045 case IW_AUTH_80211_AUTH_ALG:
8046 param->value = priv->ieee->sec.auth_mode;
8047 break;
8048
8049 case IW_AUTH_WPA_ENABLED:
8050 param->value = ieee->wpa_enabled;
8051 break;
8052
8053 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
8054 param->value = ieee->ieee802_1x;
8055 break;
8056
8057 case IW_AUTH_ROAMING_CONTROL:
8058 case IW_AUTH_PRIVACY_INVOKED:
8059 param->value = ieee->privacy_invoked;
8060 break;
8061
8062 default:
8063 return -EOPNOTSUPP;
8064 }
8065 return 0;
8066}
8067
8068/* SIOCSIWENCODEEXT */
8069static int ipw2100_wx_set_encodeext(struct net_device *dev,
8070 struct iw_request_info *info,
8071 union iwreq_data *wrqu, char *extra)
8072{
8073 struct ipw2100_priv *priv = ieee80211_priv(dev);
8074 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
8075}
8076
8077/* SIOCGIWENCODEEXT */
8078static int ipw2100_wx_get_encodeext(struct net_device *dev,
8079 struct iw_request_info *info,
8080 union iwreq_data *wrqu, char *extra)
8081{
8082 struct ipw2100_priv *priv = ieee80211_priv(dev);
8083 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
8084}
8085
8086/* SIOCSIWMLME */
8087static int ipw2100_wx_set_mlme(struct net_device *dev,
8088 struct iw_request_info *info,
8089 union iwreq_data *wrqu, char *extra)
8090{
8091 struct ipw2100_priv *priv = ieee80211_priv(dev);
8092 struct iw_mlme *mlme = (struct iw_mlme *)extra;
8093 u16 reason;
8094
8095 reason = cpu_to_le16(mlme->reason_code);
8096
8097 switch (mlme->cmd) {
8098 case IW_MLME_DEAUTH:
8099 // silently ignore
8100 break;
8101
8102 case IW_MLME_DISASSOC:
8103 ipw2100_disassociate_bssid(priv);
8104 break;
8105
8106 default:
8107 return -EOPNOTSUPP;
8108 }
8109 return 0;
8110}
8111#endif /* WIRELESS_EXT > 17 */
7893 8112
7894/* 8113/*
7895 * 8114 *
@@ -7923,7 +8142,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
7923 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8142 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
7924 err = ipw2100_switch_mode(priv, priv->last_mode); 8143 err = ipw2100_switch_mode(priv, priv->last_mode);
7925 } 8144 }
7926 done: 8145 done:
7927 up(&priv->action_sem); 8146 up(&priv->action_sem);
7928 return err; 8147 return err;
7929} 8148}
@@ -7958,7 +8177,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
7958 8177
7959 if (priv->power_mode != mode) 8178 if (priv->power_mode != mode)
7960 err = ipw2100_set_power_mode(priv, mode); 8179 err = ipw2100_set_power_mode(priv, mode);
7961 done: 8180 done:
7962 up(&priv->action_sem); 8181 up(&priv->action_sem);
7963 return err; 8182 return err;
7964} 8183}
@@ -7986,8 +8205,8 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
7986 "Power save level: %d (None)", level); 8205 "Power save level: %d (None)", level);
7987 break; 8206 break;
7988 case IPW_POWER_AUTO: 8207 case IPW_POWER_AUTO:
7989 snprintf(extra, MAX_POWER_STRING, 8208 snprintf(extra, MAX_POWER_STRING,
7990 "Power save level: %d (Auto)", 0); 8209 "Power save level: %d (Auto)", 0);
7991 break; 8210 break;
7992 default: 8211 default:
7993 timeout = timeout_duration[level - 1] / 1000; 8212 timeout = timeout_duration[level - 1] / 1000;
@@ -8004,7 +8223,6 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
8004 return 0; 8223 return 0;
8005} 8224}
8006 8225
8007
8008static int ipw2100_wx_set_preamble(struct net_device *dev, 8226static int ipw2100_wx_set_preamble(struct net_device *dev,
8009 struct iw_request_info *info, 8227 struct iw_request_info *info,
8010 union iwreq_data *wrqu, char *extra) 8228 union iwreq_data *wrqu, char *extra)
@@ -8029,14 +8247,14 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
8029 8247
8030 err = ipw2100_system_config(priv, 0); 8248 err = ipw2100_system_config(priv, 0);
8031 8249
8032done: 8250 done:
8033 up(&priv->action_sem); 8251 up(&priv->action_sem);
8034 return err; 8252 return err;
8035} 8253}
8036 8254
8037static int ipw2100_wx_get_preamble(struct net_device *dev, 8255static int ipw2100_wx_get_preamble(struct net_device *dev,
8038 struct iw_request_info *info, 8256 struct iw_request_info *info,
8039 union iwreq_data *wrqu, char *extra) 8257 union iwreq_data *wrqu, char *extra)
8040{ 8258{
8041 /* 8259 /*
8042 * This can be called at any time. No action lock required 8260 * This can be called at any time. No action lock required
@@ -8052,54 +8270,116 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
8052 return 0; 8270 return 0;
8053} 8271}
8054 8272
8055static iw_handler ipw2100_wx_handlers[] = 8273#ifdef CONFIG_IPW2100_MONITOR
8056{ 8274static int ipw2100_wx_set_crc_check(struct net_device *dev,
8057 NULL, /* SIOCSIWCOMMIT */ 8275 struct iw_request_info *info,
8058 ipw2100_wx_get_name, /* SIOCGIWNAME */ 8276 union iwreq_data *wrqu, char *extra)
8059 NULL, /* SIOCSIWNWID */ 8277{
8060 NULL, /* SIOCGIWNWID */ 8278 struct ipw2100_priv *priv = ieee80211_priv(dev);
8061 ipw2100_wx_set_freq, /* SIOCSIWFREQ */ 8279 int err, mode = *(int *)extra;
8062 ipw2100_wx_get_freq, /* SIOCGIWFREQ */ 8280
8063 ipw2100_wx_set_mode, /* SIOCSIWMODE */ 8281 down(&priv->action_sem);
8064 ipw2100_wx_get_mode, /* SIOCGIWMODE */ 8282 if (!(priv->status & STATUS_INITIALIZED)) {
8065 NULL, /* SIOCSIWSENS */ 8283 err = -EIO;
8066 NULL, /* SIOCGIWSENS */ 8284 goto done;
8067 NULL, /* SIOCSIWRANGE */ 8285 }
8068 ipw2100_wx_get_range, /* SIOCGIWRANGE */ 8286
8069 NULL, /* SIOCSIWPRIV */ 8287 if (mode == 1)
8070 NULL, /* SIOCGIWPRIV */ 8288 priv->config |= CFG_CRC_CHECK;
8071 NULL, /* SIOCSIWSTATS */ 8289 else if (mode == 0)
8072 NULL, /* SIOCGIWSTATS */ 8290 priv->config &= ~CFG_CRC_CHECK;
8073 NULL, /* SIOCSIWSPY */ 8291 else {
8074 NULL, /* SIOCGIWSPY */ 8292 err = -EINVAL;
8075 NULL, /* SIOCGIWTHRSPY */ 8293 goto done;
8076 NULL, /* SIOCWIWTHRSPY */ 8294 }
8077 ipw2100_wx_set_wap, /* SIOCSIWAP */ 8295 err = 0;
8078 ipw2100_wx_get_wap, /* SIOCGIWAP */ 8296
8079 NULL, /* -- hole -- */ 8297 done:
8080 NULL, /* SIOCGIWAPLIST -- deprecated */ 8298 up(&priv->action_sem);
8081 ipw2100_wx_set_scan, /* SIOCSIWSCAN */ 8299 return err;
8082 ipw2100_wx_get_scan, /* SIOCGIWSCAN */ 8300}
8083 ipw2100_wx_set_essid, /* SIOCSIWESSID */ 8301
8084 ipw2100_wx_get_essid, /* SIOCGIWESSID */ 8302static int ipw2100_wx_get_crc_check(struct net_device *dev,
8085 ipw2100_wx_set_nick, /* SIOCSIWNICKN */ 8303 struct iw_request_info *info,
8086 ipw2100_wx_get_nick, /* SIOCGIWNICKN */ 8304 union iwreq_data *wrqu, char *extra)
8087 NULL, /* -- hole -- */ 8305{
8088 NULL, /* -- hole -- */ 8306 /*
8089 ipw2100_wx_set_rate, /* SIOCSIWRATE */ 8307 * This can be called at any time. No action lock required
8090 ipw2100_wx_get_rate, /* SIOCGIWRATE */ 8308 */
8091 ipw2100_wx_set_rts, /* SIOCSIWRTS */ 8309
8092 ipw2100_wx_get_rts, /* SIOCGIWRTS */ 8310 struct ipw2100_priv *priv = ieee80211_priv(dev);
8093 ipw2100_wx_set_frag, /* SIOCSIWFRAG */ 8311
8094 ipw2100_wx_get_frag, /* SIOCGIWFRAG */ 8312 if (priv->config & CFG_CRC_CHECK)
8095 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */ 8313 snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
8096 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */ 8314 else
8097 ipw2100_wx_set_retry, /* SIOCSIWRETRY */ 8315 snprintf(wrqu->name, IFNAMSIZ, "CRC ignored (0)");
8098 ipw2100_wx_get_retry, /* SIOCGIWRETRY */ 8316
8099 ipw2100_wx_set_encode, /* SIOCSIWENCODE */ 8317 return 0;
8100 ipw2100_wx_get_encode, /* SIOCGIWENCODE */ 8318}
8101 ipw2100_wx_set_power, /* SIOCSIWPOWER */ 8319#endif /* CONFIG_IPW2100_MONITOR */
8102 ipw2100_wx_get_power, /* SIOCGIWPOWER */ 8320
8321static iw_handler ipw2100_wx_handlers[] = {
8322 NULL, /* SIOCSIWCOMMIT */
8323 ipw2100_wx_get_name, /* SIOCGIWNAME */
8324 NULL, /* SIOCSIWNWID */
8325 NULL, /* SIOCGIWNWID */
8326 ipw2100_wx_set_freq, /* SIOCSIWFREQ */
8327 ipw2100_wx_get_freq, /* SIOCGIWFREQ */
8328 ipw2100_wx_set_mode, /* SIOCSIWMODE */
8329 ipw2100_wx_get_mode, /* SIOCGIWMODE */
8330 NULL, /* SIOCSIWSENS */
8331 NULL, /* SIOCGIWSENS */
8332 NULL, /* SIOCSIWRANGE */
8333 ipw2100_wx_get_range, /* SIOCGIWRANGE */
8334 NULL, /* SIOCSIWPRIV */
8335 NULL, /* SIOCGIWPRIV */
8336 NULL, /* SIOCSIWSTATS */
8337 NULL, /* SIOCGIWSTATS */
8338 NULL, /* SIOCSIWSPY */
8339 NULL, /* SIOCGIWSPY */
8340 NULL, /* SIOCGIWTHRSPY */
8341 NULL, /* SIOCWIWTHRSPY */
8342 ipw2100_wx_set_wap, /* SIOCSIWAP */
8343 ipw2100_wx_get_wap, /* SIOCGIWAP */
8344#if WIRELESS_EXT > 17
8345 ipw2100_wx_set_mlme, /* SIOCSIWMLME */
8346#else
8347 NULL, /* -- hole -- */
8348#endif
8349 NULL, /* SIOCGIWAPLIST -- deprecated */
8350 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8351 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
8352 ipw2100_wx_set_essid, /* SIOCSIWESSID */
8353 ipw2100_wx_get_essid, /* SIOCGIWESSID */
8354 ipw2100_wx_set_nick, /* SIOCSIWNICKN */
8355 ipw2100_wx_get_nick, /* SIOCGIWNICKN */
8356 NULL, /* -- hole -- */
8357 NULL, /* -- hole -- */
8358 ipw2100_wx_set_rate, /* SIOCSIWRATE */
8359 ipw2100_wx_get_rate, /* SIOCGIWRATE */
8360 ipw2100_wx_set_rts, /* SIOCSIWRTS */
8361 ipw2100_wx_get_rts, /* SIOCGIWRTS */
8362 ipw2100_wx_set_frag, /* SIOCSIWFRAG */
8363 ipw2100_wx_get_frag, /* SIOCGIWFRAG */
8364 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
8365 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
8366 ipw2100_wx_set_retry, /* SIOCSIWRETRY */
8367 ipw2100_wx_get_retry, /* SIOCGIWRETRY */
8368 ipw2100_wx_set_encode, /* SIOCSIWENCODE */
8369 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8370 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8371 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8372#if WIRELESS_EXT > 17
8373 NULL, /* -- hole -- */
8374 NULL, /* -- hole -- */
8375 ipw2100_wx_set_genie, /* SIOCSIWGENIE */
8376 ipw2100_wx_get_genie, /* SIOCGIWGENIE */
8377 ipw2100_wx_set_auth, /* SIOCSIWAUTH */
8378 ipw2100_wx_get_auth, /* SIOCGIWAUTH */
8379 ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
8380 ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
8381 NULL, /* SIOCSIWPMKSA */
8382#endif
8103}; 8383};
8104 8384
8105#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV 8385#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
@@ -8108,60 +8388,71 @@ static iw_handler ipw2100_wx_handlers[] =
8108#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3 8388#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8109#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4 8389#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8110#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5 8390#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8391#define IPW2100_PRIV_SET_CRC_CHECK SIOCIWFIRSTPRIV+6
8392#define IPW2100_PRIV_GET_CRC_CHECK SIOCIWFIRSTPRIV+7
8111 8393
8112static const struct iw_priv_args ipw2100_private_args[] = { 8394static const struct iw_priv_args ipw2100_private_args[] = {
8113 8395
8114#ifdef CONFIG_IPW2100_MONITOR 8396#ifdef CONFIG_IPW2100_MONITOR
8115 { 8397 {
8116 IPW2100_PRIV_SET_MONITOR, 8398 IPW2100_PRIV_SET_MONITOR,
8117 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor" 8399 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
8118 },
8119 { 8400 {
8120 IPW2100_PRIV_RESET, 8401 IPW2100_PRIV_RESET,
8121 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset" 8402 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
8122 }, 8403#endif /* CONFIG_IPW2100_MONITOR */
8123#endif /* CONFIG_IPW2100_MONITOR */
8124 8404
8125 { 8405 {
8126 IPW2100_PRIV_SET_POWER, 8406 IPW2100_PRIV_SET_POWER,
8127 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power" 8407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"},
8128 },
8129 { 8408 {
8130 IPW2100_PRIV_GET_POWER, 8409 IPW2100_PRIV_GET_POWER,
8131 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power" 8410 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING,
8132 }, 8411 "get_power"},
8133 { 8412 {
8134 IPW2100_PRIV_SET_LONGPREAMBLE, 8413 IPW2100_PRIV_SET_LONGPREAMBLE,
8135 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble" 8414 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
8136 },
8137 { 8415 {
8138 IPW2100_PRIV_GET_LONGPREAMBLE, 8416 IPW2100_PRIV_GET_LONGPREAMBLE,
8139 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble" 8417 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"},
8140 }, 8418#ifdef CONFIG_IPW2100_MONITOR
8419 {
8420 IPW2100_PRIV_SET_CRC_CHECK,
8421 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_crc_check"},
8422 {
8423 IPW2100_PRIV_GET_CRC_CHECK,
8424 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_crc_check"},
8425#endif /* CONFIG_IPW2100_MONITOR */
8141}; 8426};
8142 8427
8143static iw_handler ipw2100_private_handler[] = { 8428static iw_handler ipw2100_private_handler[] = {
8144#ifdef CONFIG_IPW2100_MONITOR 8429#ifdef CONFIG_IPW2100_MONITOR
8145 ipw2100_wx_set_promisc, 8430 ipw2100_wx_set_promisc,
8146 ipw2100_wx_reset, 8431 ipw2100_wx_reset,
8147#else /* CONFIG_IPW2100_MONITOR */ 8432#else /* CONFIG_IPW2100_MONITOR */
8148 NULL, 8433 NULL,
8149 NULL, 8434 NULL,
8150#endif /* CONFIG_IPW2100_MONITOR */ 8435#endif /* CONFIG_IPW2100_MONITOR */
8151 ipw2100_wx_set_powermode, 8436 ipw2100_wx_set_powermode,
8152 ipw2100_wx_get_powermode, 8437 ipw2100_wx_get_powermode,
8153 ipw2100_wx_set_preamble, 8438 ipw2100_wx_set_preamble,
8154 ipw2100_wx_get_preamble, 8439 ipw2100_wx_get_preamble,
8440#ifdef CONFIG_IPW2100_MONITOR
8441 ipw2100_wx_set_crc_check,
8442 ipw2100_wx_get_crc_check,
8443#else /* CONFIG_IPW2100_MONITOR */
8444 NULL,
8445 NULL,
8446#endif /* CONFIG_IPW2100_MONITOR */
8155}; 8447};
8156 8448
8157static struct iw_handler_def ipw2100_wx_handler_def = 8449static struct iw_handler_def ipw2100_wx_handler_def = {
8158{
8159 .standard = ipw2100_wx_handlers, 8450 .standard = ipw2100_wx_handlers,
8160 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler), 8451 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
8161 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler), 8452 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
8162 .num_private_args = sizeof(ipw2100_private_args) / 8453 .num_private_args = sizeof(ipw2100_private_args) /
8163 sizeof(struct iw_priv_args), 8454 sizeof(struct iw_priv_args),
8164 .private = (iw_handler *)ipw2100_private_handler, 8455 .private = (iw_handler *) ipw2100_private_handler,
8165 .private_args = (struct iw_priv_args *)ipw2100_private_args, 8456 .private_args = (struct iw_priv_args *)ipw2100_private_args,
8166}; 8457};
8167 8458
@@ -8170,7 +8461,7 @@ static struct iw_handler_def ipw2100_wx_handler_def =
8170 * Called by /proc/net/wireless 8461 * Called by /proc/net/wireless
8171 * Also called by SIOCGIWSTATS 8462 * Also called by SIOCGIWSTATS
8172 */ 8463 */
8173static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev) 8464static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
8174{ 8465{
8175 enum { 8466 enum {
8176 POOR = 30, 8467 POOR = 30,
@@ -8190,7 +8481,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8190 u32 ord_len = sizeof(u32); 8481 u32 ord_len = sizeof(u32);
8191 8482
8192 if (!priv) 8483 if (!priv)
8193 return (struct iw_statistics *) NULL; 8484 return (struct iw_statistics *)NULL;
8194 8485
8195 wstats = &priv->wstats; 8486 wstats = &priv->wstats;
8196 8487
@@ -8207,7 +8498,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8207 wstats->qual.noise = 0; 8498 wstats->qual.noise = 0;
8208 wstats->qual.updated = 7; 8499 wstats->qual.updated = 7;
8209 wstats->qual.updated |= IW_QUAL_NOISE_INVALID | 8500 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
8210 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; 8501 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
8211 return wstats; 8502 return wstats;
8212 } 8503 }
8213 8504
@@ -8215,7 +8506,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8215 &missed_beacons, &ord_len)) 8506 &missed_beacons, &ord_len))
8216 goto fail_get_ordinal; 8507 goto fail_get_ordinal;
8217 8508
8218 /* If we don't have a connection the quality and level is 0*/ 8509 /* If we don't have a connection the quality and level is 0 */
8219 if (!(priv->status & STATUS_ASSOCIATED)) { 8510 if (!(priv->status & STATUS_ASSOCIATED)) {
8220 wstats->qual.qual = 0; 8511 wstats->qual.qual = 0;
8221 wstats->qual.level = 0; 8512 wstats->qual.level = 0;
@@ -8232,10 +8523,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8232 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR; 8523 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
8233 else if (rssi < 30) 8524 else if (rssi < 30)
8234 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) / 8525 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
8235 10 + GOOD; 8526 10 + GOOD;
8236 else 8527 else
8237 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) / 8528 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
8238 10 + VERY_GOOD; 8529 10 + VERY_GOOD;
8239 8530
8240 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES, 8531 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
8241 &tx_retries, &ord_len)) 8532 &tx_retries, &ord_len))
@@ -8249,25 +8540,25 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8249 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR; 8540 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
8250 else if (tx_retries > 50) 8541 else if (tx_retries > 50)
8251 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) / 8542 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
8252 15 + GOOD; 8543 15 + GOOD;
8253 else 8544 else
8254 tx_qual = (50 - tx_retries) * 8545 tx_qual = (50 - tx_retries) *
8255 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; 8546 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
8256 8547
8257 if (missed_beacons > 50) 8548 if (missed_beacons > 50)
8258 beacon_qual = (60 - missed_beacons) * POOR / 10; 8549 beacon_qual = (60 - missed_beacons) * POOR / 10;
8259 else if (missed_beacons > 40) 8550 else if (missed_beacons > 40)
8260 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) / 8551 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
8261 10 + POOR; 8552 10 + POOR;
8262 else if (missed_beacons > 32) 8553 else if (missed_beacons > 32)
8263 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) / 8554 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
8264 18 + FAIR; 8555 18 + FAIR;
8265 else if (missed_beacons > 20) 8556 else if (missed_beacons > 20)
8266 beacon_qual = (32 - missed_beacons) * 8557 beacon_qual = (32 - missed_beacons) *
8267 (VERY_GOOD - GOOD) / 20 + GOOD; 8558 (VERY_GOOD - GOOD) / 20 + GOOD;
8268 else 8559 else
8269 beacon_qual = (20 - missed_beacons) * 8560 beacon_qual = (20 - missed_beacons) *
8270 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD; 8561 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8271 8562
8272 quality = min(beacon_qual, min(tx_qual, rssi_qual)); 8563 quality = min(beacon_qual, min(tx_qual, rssi_qual));
8273 8564
@@ -8290,7 +8581,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8290 wstats->qual.updated = 7; 8581 wstats->qual.updated = 7;
8291 wstats->qual.updated |= IW_QUAL_NOISE_INVALID; 8582 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
8292 8583
8293 /* FIXME: this is percent and not a # */ 8584 /* FIXME: this is percent and not a # */
8294 wstats->miss.beacon = missed_beacons; 8585 wstats->miss.beacon = missed_beacons;
8295 8586
8296 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES, 8587 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
@@ -8300,10 +8591,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8300 8591
8301 return wstats; 8592 return wstats;
8302 8593
8303 fail_get_ordinal: 8594 fail_get_ordinal:
8304 IPW_DEBUG_WX("failed querying ordinals.\n"); 8595 IPW_DEBUG_WX("failed querying ordinals.\n");
8305 8596
8306 return (struct iw_statistics *) NULL; 8597 return (struct iw_statistics *)NULL;
8307} 8598}
8308 8599
8309static void ipw2100_wx_event_work(struct ipw2100_priv *priv) 8600static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
@@ -8326,23 +8617,17 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8326 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) || 8617 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
8327 priv->status & STATUS_RF_KILL_MASK || 8618 priv->status & STATUS_RF_KILL_MASK ||
8328 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, 8619 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
8329 &priv->bssid, &len)) { 8620 &priv->bssid, &len)) {
8330 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 8621 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
8331 } else { 8622 } else {
8332 /* We now have the BSSID, so can finish setting to the full 8623 /* We now have the BSSID, so can finish setting to the full
8333 * associated state */ 8624 * associated state */
8334 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 8625 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8335 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN); 8626 memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN);
8336 priv->status &= ~STATUS_ASSOCIATING; 8627 priv->status &= ~STATUS_ASSOCIATING;
8337 priv->status |= STATUS_ASSOCIATED; 8628 priv->status |= STATUS_ASSOCIATED;
8338 netif_carrier_on(priv->net_dev); 8629 netif_carrier_on(priv->net_dev);
8339 if (netif_queue_stopped(priv->net_dev)) { 8630 netif_wake_queue(priv->net_dev);
8340 IPW_DEBUG_INFO("Waking net queue.\n");
8341 netif_wake_queue(priv->net_dev);
8342 } else {
8343 IPW_DEBUG_INFO("Starting net queue.\n");
8344 netif_start_queue(priv->net_dev);
8345 }
8346 } 8631 }
8347 8632
8348 if (!(priv->status & STATUS_ASSOCIATED)) { 8633 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -8351,7 +8636,8 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8351 /* This is a disassociation event, so kick the firmware to 8636 /* This is a disassociation event, so kick the firmware to
8352 * look for another AP */ 8637 * look for another AP */
8353 if (priv->config & CFG_STATIC_ESSID) 8638 if (priv->config & CFG_STATIC_ESSID)
8354 ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0); 8639 ipw2100_set_essid(priv, priv->essid, priv->essid_len,
8640 0);
8355 else 8641 else
8356 ipw2100_set_essid(priv, NULL, 0, 0); 8642 ipw2100_set_essid(priv, NULL, 0, 0);
8357 up(&priv->action_sem); 8643 up(&priv->action_sem);
@@ -8374,7 +8660,6 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8374 8660
8375#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw" 8661#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
8376 8662
8377
8378/* 8663/*
8379 8664
8380BINARY FIRMWARE HEADER FORMAT 8665BINARY FIRMWARE HEADER FORMAT
@@ -8396,12 +8681,10 @@ struct ipw2100_fw_header {
8396 unsigned int uc_size; 8681 unsigned int uc_size;
8397} __attribute__ ((packed)); 8682} __attribute__ ((packed));
8398 8683
8399
8400
8401static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw) 8684static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8402{ 8685{
8403 struct ipw2100_fw_header *h = 8686 struct ipw2100_fw_header *h =
8404 (struct ipw2100_fw_header *)fw->fw_entry->data; 8687 (struct ipw2100_fw_header *)fw->fw_entry->data;
8405 8688
8406 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) { 8689 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
8407 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible " 8690 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
@@ -8420,7 +8703,6 @@ static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8420 return 0; 8703 return 0;
8421} 8704}
8422 8705
8423
8424static int ipw2100_get_firmware(struct ipw2100_priv *priv, 8706static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8425 struct ipw2100_fw *fw) 8707 struct ipw2100_fw *fw)
8426{ 8708{
@@ -8428,7 +8710,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8428 int rc; 8710 int rc;
8429 8711
8430 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n", 8712 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
8431 priv->net_dev->name); 8713 priv->net_dev->name);
8432 8714
8433 switch (priv->ieee->iw_mode) { 8715 switch (priv->ieee->iw_mode) {
8434 case IW_MODE_ADHOC: 8716 case IW_MODE_ADHOC:
@@ -8454,7 +8736,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8454 return rc; 8736 return rc;
8455 } 8737 }
8456 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data, 8738 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
8457 fw->fw_entry->size); 8739 fw->fw_entry->size);
8458 8740
8459 ipw2100_mod_firmware_load(fw); 8741 ipw2100_mod_firmware_load(fw);
8460 8742
@@ -8470,7 +8752,6 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
8470 fw->fw_entry = NULL; 8752 fw->fw_entry = NULL;
8471} 8753}
8472 8754
8473
8474static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf, 8755static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8475 size_t max) 8756 size_t max)
8476{ 8757{
@@ -8479,8 +8760,7 @@ static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8479 u32 tmp; 8760 u32 tmp;
8480 int i; 8761 int i;
8481 /* firmware version is an ascii string (max len of 14) */ 8762 /* firmware version is an ascii string (max len of 14) */
8482 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, 8763 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, ver, &len))
8483 ver, &len))
8484 return -EIO; 8764 return -EIO;
8485 tmp = max; 8765 tmp = max;
8486 if (len >= max) 8766 if (len >= max)
@@ -8497,8 +8777,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8497 u32 ver; 8777 u32 ver;
8498 u32 len = sizeof(ver); 8778 u32 len = sizeof(ver);
8499 /* microcode version is a 32 bit integer */ 8779 /* microcode version is a 32 bit integer */
8500 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, 8780 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, &ver, &len))
8501 &ver, &len))
8502 return -EIO; 8781 return -EIO;
8503 return snprintf(buf, max, "%08X", ver); 8782 return snprintf(buf, max, "%08X", ver);
8504} 8783}
@@ -8506,8 +8785,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8506/* 8785/*
8507 * On exit, the firmware will have been freed from the fw list 8786 * On exit, the firmware will have been freed from the fw list
8508 */ 8787 */
8509static int ipw2100_fw_download(struct ipw2100_priv *priv, 8788static int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
8510 struct ipw2100_fw *fw)
8511{ 8789{
8512 /* firmware is constructed of N contiguous entries, each entry is 8790 /* firmware is constructed of N contiguous entries, each entry is
8513 * structured as: 8791 * structured as:
@@ -8515,7 +8793,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8515 * offset sie desc 8793 * offset sie desc
8516 * 0 4 address to write to 8794 * 0 4 address to write to
8517 * 4 2 length of data run 8795 * 4 2 length of data run
8518 * 6 length data 8796 * 6 length data
8519 */ 8797 */
8520 unsigned int addr; 8798 unsigned int addr;
8521 unsigned short len; 8799 unsigned short len;
@@ -8524,12 +8802,12 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8524 unsigned int firmware_data_left = fw->fw.size; 8802 unsigned int firmware_data_left = fw->fw.size;
8525 8803
8526 while (firmware_data_left > 0) { 8804 while (firmware_data_left > 0) {
8527 addr = *(u32 *)(firmware_data); 8805 addr = *(u32 *) (firmware_data);
8528 firmware_data += 4; 8806 firmware_data += 4;
8529 firmware_data_left -= 4; 8807 firmware_data_left -= 4;
8530 8808
8531 len = *(u16 *)(firmware_data); 8809 len = *(u16 *) (firmware_data);
8532 firmware_data += 2; 8810 firmware_data += 2;
8533 firmware_data_left -= 2; 8811 firmware_data_left -= 2;
8534 8812
8535 if (len > 32) { 8813 if (len > 32) {
@@ -8540,7 +8818,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8540 } 8818 }
8541 8819
8542 write_nic_memory(priv->net_dev, addr, len, firmware_data); 8820 write_nic_memory(priv->net_dev, addr, len, firmware_data);
8543 firmware_data += len; 8821 firmware_data += len;
8544 firmware_data_left -= len; 8822 firmware_data_left -= len;
8545 } 8823 }
8546 8824
@@ -8654,21 +8932,19 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8654 for (i = 0; i < 30; i++) { 8932 for (i = 0; i < 30; i++) {
8655 /* Read alive response structure */ 8933 /* Read alive response structure */
8656 for (j = 0; 8934 for (j = 0;
8657 j < (sizeof(struct symbol_alive_response) >> 1); 8935 j < (sizeof(struct symbol_alive_response) >> 1); j++)
8658 j++) 8936 read_nic_word(dev, 0x210004, ((u16 *) & response) + j);
8659 read_nic_word(dev, 0x210004,
8660 ((u16 *)&response) + j);
8661 8937
8662 if ((response.cmd_id == 1) && 8938 if ((response.cmd_id == 1) && (response.ucode_valid == 0x1))
8663 (response.ucode_valid == 0x1))
8664 break; 8939 break;
8665 udelay(10); 8940 udelay(10);
8666 } 8941 }
8667 8942
8668 if (i == 30) { 8943 if (i == 30) {
8669 printk(KERN_ERR DRV_NAME ": %s: No response from Symbol - hw not alive\n", 8944 printk(KERN_ERR DRV_NAME
8945 ": %s: No response from Symbol - hw not alive\n",
8670 dev->name); 8946 dev->name);
8671 printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response)); 8947 printk_buf(IPW_DL_ERROR, (u8 *) & response, sizeof(response));
8672 return -EIO; 8948 return -EIO;
8673 } 8949 }
8674 8950
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index c9e99ce15d66..140fdf2a0a09 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -37,7 +37,6 @@
37#include <linux/socket.h> 37#include <linux/socket.h>
38#include <linux/if_arp.h> 38#include <linux/if_arp.h>
39#include <linux/wireless.h> 39#include <linux/wireless.h>
40#include <linux/version.h>
41#include <net/iw_handler.h> // new driver API 40#include <net/iw_handler.h> // new driver API
42 41
43#include <net/ieee80211.h> 42#include <net/ieee80211.h>
@@ -93,7 +92,6 @@ struct ipw2100_rx_packet;
93#define IPW_DL_IOCTL (1<<14) 92#define IPW_DL_IOCTL (1<<14)
94#define IPW_DL_RF_KILL (1<<17) 93#define IPW_DL_RF_KILL (1<<17)
95 94
96
97#define IPW_DL_MANAGE (1<<15) 95#define IPW_DL_MANAGE (1<<15)
98#define IPW_DL_FW (1<<16) 96#define IPW_DL_FW (1<<16)
99 97
@@ -156,7 +154,9 @@ extern const char *band_str[];
156 154
157struct bd_status { 155struct bd_status {
158 union { 156 union {
159 struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields; 157 struct {
158 u8 nlf:1, txType:2, intEnabled:1, reserved:4;
159 } fields;
160 u8 field; 160 u8 field;
161 } info; 161 } info;
162} __attribute__ ((packed)); 162} __attribute__ ((packed));
@@ -165,7 +165,7 @@ struct ipw2100_bd {
165 u32 host_addr; 165 u32 host_addr;
166 u32 buf_length; 166 u32 buf_length;
167 struct bd_status status; 167 struct bd_status status;
168 /* number of fragments for frame (should be set only for 168 /* number of fragments for frame (should be set only for
169 * 1st TBD) */ 169 * 1st TBD) */
170 u8 num_fragments; 170 u8 num_fragments;
171 u8 reserved[6]; 171 u8 reserved[6];
@@ -293,10 +293,10 @@ struct ipw2100_cmd_header {
293struct ipw2100_data_header { 293struct ipw2100_data_header {
294 u32 host_command_reg; 294 u32 host_command_reg;
295 u32 host_command_reg1; 295 u32 host_command_reg1;
296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver 296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC 297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key 298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV 299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
300 u8 key[16]; 300 u8 key[16];
301 u8 reserved[10]; // f/w reserved 301 u8 reserved[10]; // f/w reserved
302 u8 src_addr[ETH_ALEN]; 302 u8 src_addr[ETH_ALEN];
@@ -306,14 +306,13 @@ struct ipw2100_data_header {
306 306
307/* Host command data structure */ 307/* Host command data structure */
308struct host_command { 308struct host_command {
309 u32 host_command; // COMMAND ID 309 u32 host_command; // COMMAND ID
310 u32 host_command1; // COMMAND ID 310 u32 host_command1; // COMMAND ID
311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID) 311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
312 u32 host_command_length; // LENGTH 312 u32 host_command_length; // LENGTH
313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS 313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
314} __attribute__ ((packed)); 314} __attribute__ ((packed));
315 315
316
317typedef enum { 316typedef enum {
318 POWER_ON_RESET, 317 POWER_ON_RESET,
319 EXIT_POWER_DOWN_RESET, 318 EXIT_POWER_DOWN_RESET,
@@ -328,17 +327,16 @@ enum {
328 RX 327 RX
329}; 328};
330 329
331
332struct ipw2100_tx_packet { 330struct ipw2100_tx_packet {
333 int type; 331 int type;
334 int index; 332 int index;
335 union { 333 union {
336 struct { /* COMMAND */ 334 struct { /* COMMAND */
337 struct ipw2100_cmd_header* cmd; 335 struct ipw2100_cmd_header *cmd;
338 dma_addr_t cmd_phys; 336 dma_addr_t cmd_phys;
339 } c_struct; 337 } c_struct;
340 struct { /* DATA */ 338 struct { /* DATA */
341 struct ipw2100_data_header* data; 339 struct ipw2100_data_header *data;
342 dma_addr_t data_phys; 340 dma_addr_t data_phys;
343 struct ieee80211_txb *txb; 341 struct ieee80211_txb *txb;
344 } d_struct; 342 } d_struct;
@@ -348,7 +346,6 @@ struct ipw2100_tx_packet {
348 struct list_head list; 346 struct list_head list;
349}; 347};
350 348
351
352struct ipw2100_rx_packet { 349struct ipw2100_rx_packet {
353 struct ipw2100_rx *rxp; 350 struct ipw2100_rx *rxp;
354 dma_addr_t dma_addr; 351 dma_addr_t dma_addr;
@@ -432,13 +429,13 @@ enum {
432}; 429};
433 430
434#define STATUS_POWERED (1<<0) 431#define STATUS_POWERED (1<<0)
435#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */ 432#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
436#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */ 433#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
437#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */ 434#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
438#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */ 435#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
439#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */ 436#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
440#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */ 437#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
441#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */ 438#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
442#define STATUS_INT_ENABLED (1<<11) 439#define STATUS_INT_ENABLED (1<<11)
443#define STATUS_RF_KILL_HW (1<<12) 440#define STATUS_RF_KILL_HW (1<<12)
444#define STATUS_RF_KILL_SW (1<<13) 441#define STATUS_RF_KILL_SW (1<<13)
@@ -451,9 +448,7 @@ enum {
451#define STATUS_SCAN_COMPLETE (1<<26) 448#define STATUS_SCAN_COMPLETE (1<<26)
452#define STATUS_WX_EVENT_PENDING (1<<27) 449#define STATUS_WX_EVENT_PENDING (1<<27)
453#define STATUS_RESET_PENDING (1<<29) 450#define STATUS_RESET_PENDING (1<<29)
454#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */ 451#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
455
456
457 452
458/* Internal NIC states */ 453/* Internal NIC states */
459#define IPW_STATE_INITIALIZED (1<<0) 454#define IPW_STATE_INITIALIZED (1<<0)
@@ -469,11 +464,9 @@ enum {
469#define IPW_STATE_POWER_DOWN (1<<10) 464#define IPW_STATE_POWER_DOWN (1<<10)
470#define IPW_STATE_SCANNING (1<<11) 465#define IPW_STATE_SCANNING (1<<11)
471 466
472 467#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
473 468#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
474#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */ 469#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
475#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
476#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
477#define CFG_CUSTOM_MAC (1<<3) 470#define CFG_CUSTOM_MAC (1<<3)
478#define CFG_LONG_PREAMBLE (1<<4) 471#define CFG_LONG_PREAMBLE (1<<4)
479#define CFG_ASSOCIATE (1<<6) 472#define CFG_ASSOCIATE (1<<6)
@@ -481,14 +474,17 @@ enum {
481#define CFG_ADHOC_CREATE (1<<8) 474#define CFG_ADHOC_CREATE (1<<8)
482#define CFG_C3_DISABLED (1<<9) 475#define CFG_C3_DISABLED (1<<9)
483#define CFG_PASSIVE_SCAN (1<<10) 476#define CFG_PASSIVE_SCAN (1<<10)
477#ifdef CONFIG_IPW2100_MONITOR
478#define CFG_CRC_CHECK (1<<11)
479#endif
484 480
485#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 481#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
486#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 482#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
487 483
488struct ipw2100_priv { 484struct ipw2100_priv {
489 485
490 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */ 486 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
491 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */ 487 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
492 488
493 struct ieee80211_device *ieee; 489 struct ieee80211_device *ieee;
494 unsigned long status; 490 unsigned long status;
@@ -519,19 +515,16 @@ struct ipw2100_priv {
519 unsigned long hw_features; 515 unsigned long hw_features;
520 int hangs; 516 int hangs;
521 u32 last_rtc; 517 u32 last_rtc;
522 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */ 518 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
523 u8* snapshot[0x30]; 519 u8 *snapshot[0x30];
524 520
525 u8 mandatory_bssid_mac[ETH_ALEN]; 521 u8 mandatory_bssid_mac[ETH_ALEN];
526 u8 mac_addr[ETH_ALEN]; 522 u8 mac_addr[ETH_ALEN];
527 523
528 int power_mode; 524 int power_mode;
529 525
530 /* WEP data */
531 struct ieee80211_security sec;
532 int messages_sent; 526 int messages_sent;
533 527
534
535 int short_retry_limit; 528 int short_retry_limit;
536 int long_retry_limit; 529 int long_retry_limit;
537 530
@@ -599,7 +592,6 @@ struct ipw2100_priv {
599 wait_queue_head_t wait_command_queue; 592 wait_queue_head_t wait_command_queue;
600}; 593};
601 594
602
603/********************************************************* 595/*********************************************************
604 * Host Command -> From Driver to FW 596 * Host Command -> From Driver to FW
605 *********************************************************/ 597 *********************************************************/
@@ -646,7 +638,6 @@ struct ipw2100_priv {
646#define CARD_DISABLE_PHY_OFF 61 638#define CARD_DISABLE_PHY_OFF 61
647#define MSDU_TX_RATES 62 639#define MSDU_TX_RATES 62
648 640
649
650/* Rogue AP Detection */ 641/* Rogue AP Detection */
651#define SET_STATION_STAT_BITS 64 642#define SET_STATION_STAT_BITS 64
652#define CLEAR_STATIONS_STAT_BITS 65 643#define CLEAR_STATIONS_STAT_BITS 65
@@ -655,8 +646,6 @@ struct ipw2100_priv {
655#define DISASSOCIATION_BSSID 68 646#define DISASSOCIATION_BSSID 68
656#define SET_WPA_IE 69 647#define SET_WPA_IE 69
657 648
658
659
660/* system configuration bit mask: */ 649/* system configuration bit mask: */
661#define IPW_CFG_MONITOR 0x00004 650#define IPW_CFG_MONITOR 0x00004
662#define IPW_CFG_PREAMBLE_AUTO 0x00010 651#define IPW_CFG_PREAMBLE_AUTO 0x00010
@@ -704,7 +693,7 @@ struct ipw2100_priv {
704#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB) 693#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
705#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1 694#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
706#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2 695#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
707#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3 696#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
708#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4 697#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
709#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5 698#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
710#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16 699#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
@@ -784,9 +773,6 @@ struct ipw2100_priv {
784#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli 773#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
785#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli 774#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
786 775
787
788
789
790#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr) 776#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr)
791#define IPW_MAX_80211_PAYLOAD_SIZE 2304U 777#define IPW_MAX_80211_PAYLOAD_SIZE 2304U
792#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312 778#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
@@ -843,8 +829,8 @@ struct ipw2100_rx {
843#define IPW_TX_POWER_MIN_DBM (-12) 829#define IPW_TX_POWER_MIN_DBM (-12)
844#define IPW_TX_POWER_MAX_DBM 16 830#define IPW_TX_POWER_MAX_DBM 16
845 831
846#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan 832#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
847#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan 833#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
848 834
849#define REG_MIN_CHANNEL 0 835#define REG_MIN_CHANNEL 0
850#define REG_MAX_CHANNEL 14 836#define REG_MAX_CHANNEL 14
@@ -856,7 +842,6 @@ struct ipw2100_rx {
856#define DIVERSITY_ANTENNA_A 1 // Use antenna A 842#define DIVERSITY_ANTENNA_A 1 // Use antenna A
857#define DIVERSITY_ANTENNA_B 2 // Use antenna B 843#define DIVERSITY_ANTENNA_B 2 // Use antenna B
858 844
859
860#define HOST_COMMAND_WAIT 0 845#define HOST_COMMAND_WAIT 0
861#define HOST_COMMAND_NO_WAIT 1 846#define HOST_COMMAND_NO_WAIT 1
862 847
@@ -873,10 +858,9 @@ struct ipw2100_rx {
873#define TYPE_ASSOCIATION_REQUEST 0x0013 858#define TYPE_ASSOCIATION_REQUEST 0x0013
874#define TYPE_REASSOCIATION_REQUEST 0x0014 859#define TYPE_REASSOCIATION_REQUEST 0x0014
875 860
876 861#define HW_FEATURE_RFKILL 0x0001
877#define HW_FEATURE_RFKILL (0x0001) 862#define RF_KILLSWITCH_OFF 1
878#define RF_KILLSWITCH_OFF (1) 863#define RF_KILLSWITCH_ON 0
879#define RF_KILLSWITCH_ON (0)
880 864
881#define IPW_COMMAND_POOL_SIZE 40 865#define IPW_COMMAND_POOL_SIZE 40
882 866
@@ -895,7 +879,7 @@ struct ipw2100_rx {
895// Fixed size data: Ordinal Table 1 879// Fixed size data: Ordinal Table 1
896typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW 880typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
897// Transmit statistics 881// Transmit statistics
898 IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU) 882 IPW_ORD_STAT_TX_HOST_REQUESTS = 1, // # of requested Host Tx's (MSDU)
899 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU) 883 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
900 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU) 884 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
901 885
@@ -905,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
905 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB 889 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
906 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB 890 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
907 891
908 IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB 892 IPW_ORD_STAT_TX_NODIR_DATA1 = 13, // # of successful Non_Directed Tx's (MSDU) @ 1MB
909 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB 893 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
910 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB 894 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
911 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB 895 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
912 896
913 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's 897 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
914 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS 898 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
915 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS 899 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
916 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK 900 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
917 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's 901 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
918 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's 902 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
919 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's 903 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
920 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's 904 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
921 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted 905 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
922 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted 906 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
923 IPW_ORD_STAT_TX_BEACON, // # of tx beacon 907 IPW_ORD_STAT_TX_BEACON, // # of tx beacon
924 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM 908 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
925 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX 909 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
926 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx 910 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
927 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX 911 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
928 912
929 IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes 913 IPW_ORD_STAT_TX_TOTAL_BYTES = 41, // Total successful Tx data bytes
930 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries 914 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
931 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS 915 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
932 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS 916 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
933 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS 917 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
934 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS 918 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
935 919
936 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures 920 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
937 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time 921 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
938 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed 922 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP, // # of times max tries in a hop failed
939 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup 923 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
940 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted 924 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
941 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed 925 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
942 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames 926 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
943 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent 927 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
944 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks 928 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
945 929
946 // Receive statistics 930 // Receive statistics
@@ -952,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
952 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB 936 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
953 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB 937 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
954 938
955 IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets 939 IPW_ORD_STAT_RX_NODIR_DATA = 71, // # of nondirected packets
956 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB 940 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
957 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB 941 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
958 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB 942 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
@@ -977,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
977 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx 961 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
978 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx 962 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
979 963
980 IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received 964 IPW_ORD_STAT_RX_TOTAL_BYTES = 101, // Total rx data bytes received
981 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error 965 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
982 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB 966 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
983 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB 967 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
984 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB 968 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
985 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB 969 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
986 970
987 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB 971 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
988 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB 972 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
989 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB 973 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
990 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB 974 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
991 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets 975 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
992 976
993 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db 977 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
994 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db 978 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
@@ -1006,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
1006 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption 990 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
1007 991
1008// PSP Statistics 992// PSP Statistics
1009 IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended 993 IPW_ORD_STAT_PSP_SUSPENSION = 137, // # of times adapter suspended
1010 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout 994 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
1011 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts 995 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
1012 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt 996 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT, // # of timeouts waiting for last broadcast/muticast pkt
1013 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received 997 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
1014 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received 998 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
1015 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID 999 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
1016 1000
1017// Association and roaming 1001// Association and roaming
1018 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association 1002 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
1019 IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons 1003 IPW_ORD_STAT_PERCENT_MISSED_BCNS, // current calculation of % missed beacons
1020 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries 1004 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
1021 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated 1005 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
1022 // AP table entry. set to 0 if not associated 1006 // AP table entry. set to 0 if not associated
@@ -1151,7 +1135,7 @@ struct ipw2100_fw_chunk {
1151}; 1135};
1152 1136
1153struct ipw2100_fw_chunk_set { 1137struct ipw2100_fw_chunk_set {
1154 const void *data; 1138 const void *data;
1155 unsigned long size; 1139 unsigned long size;
1156}; 1140};
1157 1141
@@ -1164,4 +1148,4 @@ struct ipw2100_fw {
1164 1148
1165#define MAX_FW_VERSION_LEN 14 1149#define MAX_FW_VERSION_LEN 14
1166 1150
1167#endif /* _IPW2100_H */ 1151#endif /* _IPW2100_H */
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3db0c32afe82..b0d195d1721a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 802.11 status code portion of this file from ethereal-0.10.6: 5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB 6 Copyright 2000, Axis Communications AB
@@ -31,30 +31,103 @@
31******************************************************************************/ 31******************************************************************************/
32 32
33#include "ipw2200.h" 33#include "ipw2200.h"
34#include <linux/version.h>
34 35
35#define IPW2200_VERSION "1.0.0" 36#define IPW2200_VERSION "git-1.0.8"
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 37#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 38#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION 39#define DRV_VERSION IPW2200_VERSION
39 40
41#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
42
40MODULE_DESCRIPTION(DRV_DESCRIPTION); 43MODULE_DESCRIPTION(DRV_DESCRIPTION);
41MODULE_VERSION(DRV_VERSION); 44MODULE_VERSION(DRV_VERSION);
42MODULE_AUTHOR(DRV_COPYRIGHT); 45MODULE_AUTHOR(DRV_COPYRIGHT);
43MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
44 47
48static int cmdlog = 0;
45static int debug = 0; 49static int debug = 0;
46static int channel = 0; 50static int channel = 0;
47static char *ifname;
48static int mode = 0; 51static int mode = 0;
49 52
50static u32 ipw_debug_level; 53static u32 ipw_debug_level;
51static int associate = 1; 54static int associate = 1;
52static int auto_create = 1; 55static int auto_create = 1;
56static int led = 0;
53static int disable = 0; 57static int disable = 0;
58static int hwcrypto = 1;
54static const char ipw_modes[] = { 59static const char ipw_modes[] = {
55 'a', 'b', 'g', '?' 60 'a', 'b', 'g', '?'
56}; 61};
57 62
63#ifdef CONFIG_IPW_QOS
64static int qos_enable = 0;
65static int qos_burst_enable = 0;
66static int qos_no_ack_mask = 0;
67static int burst_duration_CCK = 0;
68static int burst_duration_OFDM = 0;
69
70static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
71 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
72 QOS_TX3_CW_MIN_OFDM},
73 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
74 QOS_TX3_CW_MAX_OFDM},
75 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
76 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
77 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
78 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
79};
80
81static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
82 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
83 QOS_TX3_CW_MIN_CCK},
84 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
85 QOS_TX3_CW_MAX_CCK},
86 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
87 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
88 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
89 QOS_TX3_TXOP_LIMIT_CCK}
90};
91
92static struct ieee80211_qos_parameters def_parameters_OFDM = {
93 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
94 DEF_TX3_CW_MIN_OFDM},
95 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
96 DEF_TX3_CW_MAX_OFDM},
97 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
98 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
99 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
100 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
101};
102
103static struct ieee80211_qos_parameters def_parameters_CCK = {
104 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
105 DEF_TX3_CW_MIN_CCK},
106 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
107 DEF_TX3_CW_MAX_CCK},
108 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
109 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
110 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
111 DEF_TX3_TXOP_LIMIT_CCK}
112};
113
114static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
115
116static int from_priority_to_tx_queue[] = {
117 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
118 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
119};
120
121static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
122
123static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
124 *qos_param);
125static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
126 *qos_param);
127#endif /* CONFIG_IPW_QOS */
128
129static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
130static void ipw_remove_current_network(struct ipw_priv *priv);
58static void ipw_rx(struct ipw_priv *priv); 131static void ipw_rx(struct ipw_priv *priv);
59static int ipw_queue_tx_reclaim(struct ipw_priv *priv, 132static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
60 struct clx2_tx_queue *txq, int qindex); 133 struct clx2_tx_queue *txq, int qindex);
@@ -68,42 +141,24 @@ static void ipw_tx_queue_free(struct ipw_priv *);
68static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *); 141static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
69static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *); 142static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
70static void ipw_rx_queue_replenish(void *); 143static void ipw_rx_queue_replenish(void *);
71
72static int ipw_up(struct ipw_priv *); 144static int ipw_up(struct ipw_priv *);
145static void ipw_bg_up(void *);
73static void ipw_down(struct ipw_priv *); 146static void ipw_down(struct ipw_priv *);
147static void ipw_bg_down(void *);
74static int ipw_config(struct ipw_priv *); 148static int ipw_config(struct ipw_priv *);
75static int init_supported_rates(struct ipw_priv *priv, 149static int init_supported_rates(struct ipw_priv *priv,
76 struct ipw_supported_rates *prates); 150 struct ipw_supported_rates *prates);
151static void ipw_set_hwcrypto_keys(struct ipw_priv *);
152static void ipw_send_wep_keys(struct ipw_priv *, int);
77 153
78static u8 band_b_active_channel[MAX_B_CHANNELS] = { 154static int ipw_is_valid_channel(struct ieee80211_device *, u8);
79 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 155static int ipw_channel_to_index(struct ieee80211_device *, u8);
80}; 156static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
81static u8 band_a_active_channel[MAX_A_CHANNELS] = { 157static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
82 36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0 158static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
83};
84 159
85static int is_valid_channel(int mode_mask, int channel) 160static int snprint_line(char *buf, size_t count,
86{ 161 const u8 * data, u32 len, u32 ofs)
87 int i;
88
89 if (!channel)
90 return 0;
91
92 if (mode_mask & IEEE_A)
93 for (i = 0; i < MAX_A_CHANNELS; i++)
94 if (band_a_active_channel[i] == channel)
95 return IEEE_A;
96
97 if (mode_mask & (IEEE_B | IEEE_G))
98 for (i = 0; i < MAX_B_CHANNELS; i++)
99 if (band_b_active_channel[i] == channel)
100 return mode_mask & (IEEE_B | IEEE_G);
101
102 return 0;
103}
104
105static char *snprint_line(char *buf, size_t count,
106 const u8 * data, u32 len, u32 ofs)
107{ 162{
108 int out, i, j, l; 163 int out, i, j, l;
109 char c; 164 char c;
@@ -134,7 +189,7 @@ static char *snprint_line(char *buf, size_t count,
134 out += snprintf(buf + out, count - out, " "); 189 out += snprintf(buf + out, count - out, " ");
135 } 190 }
136 191
137 return buf; 192 return out;
138} 193}
139 194
140static void printk_buf(int level, const u8 * data, u32 len) 195static void printk_buf(int level, const u8 * data, u32 len)
@@ -145,14 +200,33 @@ static void printk_buf(int level, const u8 * data, u32 len)
145 return; 200 return;
146 201
147 while (len) { 202 while (len) {
148 printk(KERN_DEBUG "%s\n", 203 snprint_line(line, sizeof(line), &data[ofs],
149 snprint_line(line, sizeof(line), &data[ofs], 204 min(len, 16U), ofs);
150 min(len, 16U), ofs)); 205 printk(KERN_DEBUG "%s\n", line);
151 ofs += 16; 206 ofs += 16;
152 len -= min(len, 16U); 207 len -= min(len, 16U);
153 } 208 }
154} 209}
155 210
211static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
212{
213 size_t out = size;
214 u32 ofs = 0;
215 int total = 0;
216
217 while (size && len) {
218 out = snprint_line(output, size, &data[ofs],
219 min_t(size_t, len, 16U), ofs);
220
221 ofs += 16;
222 output += out;
223 size -= out;
224 len -= min_t(size_t, len, 16U);
225 total += out;
226 }
227 return total;
228}
229
156static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg); 230static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
157#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b) 231#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
158 232
@@ -226,38 +300,42 @@ static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
226#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) 300#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
227 301
228static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); 302static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
229#define ipw_read_indirect(a, b, c, d) \ 303static inline void __ipw_read_indirect(const char *f, int l,
230 IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 304 struct ipw_priv *a, u32 b, u8 * c, int d)
231 _ipw_read_indirect(a, b, c, d) 305{
306 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
307 d);
308 _ipw_read_indirect(a, b, c, d);
309}
310
311#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
232 312
233static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, 313static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
234 int num); 314 int num);
235#define ipw_write_indirect(a, b, c, d) \ 315#define ipw_write_indirect(a, b, c, d) \
236 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 316 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
237 _ipw_write_indirect(a, b, c, d) 317 _ipw_write_indirect(a, b, c, d)
238 318
239/* indirect write s */ 319/* indirect write s */
240static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) 320static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
241{ 321{
242 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); 322 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
243 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 323 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
244 _ipw_write32(priv, CX2_INDIRECT_DATA, value); 324 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
245} 325}
246 326
247static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) 327static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
248{ 328{
249 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 329 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
250 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 330 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
251 _ipw_write8(priv, CX2_INDIRECT_DATA, value); 331 _ipw_write8(priv, IPW_INDIRECT_DATA, value);
252 IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
253 (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value);
254} 332}
255 333
256static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) 334static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
257{ 335{
258 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 336 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
259 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 337 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
260 _ipw_write16(priv, CX2_INDIRECT_DATA, value); 338 _ipw_write16(priv, IPW_INDIRECT_DATA, value);
261} 339}
262 340
263/* indirect read s */ 341/* indirect read s */
@@ -265,9 +343,9 @@ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
265static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) 343static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
266{ 344{
267 u32 word; 345 u32 word;
268 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 346 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
269 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); 347 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
270 word = _ipw_read32(priv, CX2_INDIRECT_DATA); 348 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
271 return (word >> ((reg & 0x3) * 8)) & 0xff; 349 return (word >> ((reg & 0x3) * 8)) & 0xff;
272} 350}
273 351
@@ -277,8 +355,8 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
277 355
278 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg); 356 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
279 357
280 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 358 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
281 value = _ipw_read32(priv, CX2_INDIRECT_DATA); 359 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
282 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value); 360 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
283 return value; 361 return value;
284} 362}
@@ -287,67 +365,69 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
287static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 365static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
288 int num) 366 int num)
289{ 367{
290 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 368 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
291 u32 dif_len = addr - aligned_addr; 369 u32 dif_len = addr - aligned_addr;
292 u32 aligned_len;
293 u32 i; 370 u32 i;
294 371
295 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 372 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
296 373
374 if (num <= 0) {
375 return;
376 }
377
297 /* Read the first nibble byte by byte */ 378 /* Read the first nibble byte by byte */
298 if (unlikely(dif_len)) { 379 if (unlikely(dif_len)) {
380 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
299 /* Start reading at aligned_addr + dif_len */ 381 /* Start reading at aligned_addr + dif_len */
300 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 382 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
301 for (i = dif_len; i < 4; i++, buf++) 383 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
302 *buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
303 num -= dif_len;
304 aligned_addr += 4; 384 aligned_addr += 4;
305 } 385 }
306 386
307 /* Read DWs through autoinc register */ 387 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
308 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 388 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
309 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 389 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
310 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
311 *(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA);
312 390
313 /* Copy the last nibble */ 391 /* Copy the last nibble */
314 dif_len = num - aligned_len; 392 if (unlikely(num)) {
315 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 393 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
316 for (i = 0; i < dif_len; i++, buf++) 394 for (i = 0; num > 0; i++, num--)
317 *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); 395 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
396 }
318} 397}
319 398
320static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 399static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
321 int num) 400 int num)
322{ 401{
323 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 402 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
324 u32 dif_len = addr - aligned_addr; 403 u32 dif_len = addr - aligned_addr;
325 u32 aligned_len;
326 u32 i; 404 u32 i;
327 405
328 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 406 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
329 407
408 if (num <= 0) {
409 return;
410 }
411
330 /* Write the first nibble byte by byte */ 412 /* Write the first nibble byte by byte */
331 if (unlikely(dif_len)) { 413 if (unlikely(dif_len)) {
332 /* Start writing at aligned_addr + dif_len */ 414 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
333 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 415 /* Start reading at aligned_addr + dif_len */
334 for (i = dif_len; i < 4; i++, buf++) 416 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
335 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 417 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
336 num -= dif_len;
337 aligned_addr += 4; 418 aligned_addr += 4;
338 } 419 }
339 420
340 /* Write DWs through autoinc register */ 421 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
341 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 422 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
342 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 423 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
343 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
344 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
345 424
346 /* Copy the last nibble */ 425 /* Copy the last nibble */
347 dif_len = num - aligned_len; 426 if (unlikely(num)) {
348 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 427 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
349 for (i = 0; i < dif_len; i++, buf++) 428 for (i = 0; num > 0; i++, num--, buf++)
350 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 429 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
430 }
351} 431}
352 432
353static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, 433static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
@@ -371,7 +451,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv)
371 if (priv->status & STATUS_INT_ENABLED) 451 if (priv->status & STATUS_INT_ENABLED)
372 return; 452 return;
373 priv->status |= STATUS_INT_ENABLED; 453 priv->status |= STATUS_INT_ENABLED;
374 ipw_write32(priv, CX2_INTA_MASK_R, CX2_INTA_MASK_ALL); 454 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
375} 455}
376 456
377static inline void ipw_disable_interrupts(struct ipw_priv *priv) 457static inline void ipw_disable_interrupts(struct ipw_priv *priv)
@@ -379,9 +459,10 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
379 if (!(priv->status & STATUS_INT_ENABLED)) 459 if (!(priv->status & STATUS_INT_ENABLED))
380 return; 460 return;
381 priv->status &= ~STATUS_INT_ENABLED; 461 priv->status &= ~STATUS_INT_ENABLED;
382 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 462 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
383} 463}
384 464
465#ifdef CONFIG_IPW_DEBUG
385static char *ipw_error_desc(u32 val) 466static char *ipw_error_desc(u32 val)
386{ 467{
387 switch (val) { 468 switch (val) {
@@ -394,81 +475,65 @@ static char *ipw_error_desc(u32 val)
394 case IPW_FW_ERROR_MEMORY_OVERFLOW: 475 case IPW_FW_ERROR_MEMORY_OVERFLOW:
395 return "MEMORY_OVERFLOW"; 476 return "MEMORY_OVERFLOW";
396 case IPW_FW_ERROR_BAD_PARAM: 477 case IPW_FW_ERROR_BAD_PARAM:
397 return "ERROR_BAD_PARAM"; 478 return "BAD_PARAM";
398 case IPW_FW_ERROR_BAD_CHECKSUM: 479 case IPW_FW_ERROR_BAD_CHECKSUM:
399 return "ERROR_BAD_CHECKSUM"; 480 return "BAD_CHECKSUM";
400 case IPW_FW_ERROR_NMI_INTERRUPT: 481 case IPW_FW_ERROR_NMI_INTERRUPT:
401 return "ERROR_NMI_INTERRUPT"; 482 return "NMI_INTERRUPT";
402 case IPW_FW_ERROR_BAD_DATABASE: 483 case IPW_FW_ERROR_BAD_DATABASE:
403 return "ERROR_BAD_DATABASE"; 484 return "BAD_DATABASE";
404 case IPW_FW_ERROR_ALLOC_FAIL: 485 case IPW_FW_ERROR_ALLOC_FAIL:
405 return "ERROR_ALLOC_FAIL"; 486 return "ALLOC_FAIL";
406 case IPW_FW_ERROR_DMA_UNDERRUN: 487 case IPW_FW_ERROR_DMA_UNDERRUN:
407 return "ERROR_DMA_UNDERRUN"; 488 return "DMA_UNDERRUN";
408 case IPW_FW_ERROR_DMA_STATUS: 489 case IPW_FW_ERROR_DMA_STATUS:
409 return "ERROR_DMA_STATUS"; 490 return "DMA_STATUS";
410 case IPW_FW_ERROR_DINOSTATUS_ERROR: 491 case IPW_FW_ERROR_DINO_ERROR:
411 return "ERROR_DINOSTATUS_ERROR"; 492 return "DINO_ERROR";
412 case IPW_FW_ERROR_EEPROMSTATUS_ERROR: 493 case IPW_FW_ERROR_EEPROM_ERROR:
413 return "ERROR_EEPROMSTATUS_ERROR"; 494 return "EEPROM_ERROR";
414 case IPW_FW_ERROR_SYSASSERT: 495 case IPW_FW_ERROR_SYSASSERT:
415 return "ERROR_SYSASSERT"; 496 return "SYSASSERT";
416 case IPW_FW_ERROR_FATAL_ERROR: 497 case IPW_FW_ERROR_FATAL_ERROR:
417 return "ERROR_FATALSTATUS_ERROR"; 498 return "FATAL_ERROR";
418 default: 499 default:
419 return "UNKNOWNSTATUS_ERROR"; 500 return "UNKNOWN_ERROR";
420 } 501 }
421} 502}
422 503
423static void ipw_dump_nic_error_log(struct ipw_priv *priv) 504static void ipw_dump_error_log(struct ipw_priv *priv,
505 struct ipw_fw_error *error)
424{ 506{
425 u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base; 507 u32 i;
426
427 base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
428 count = ipw_read_reg32(priv, base);
429 508
430 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { 509 if (!error) {
431 IPW_ERROR("Start IPW Error Log Dump:\n"); 510 IPW_ERROR("Error allocating and capturing error log. "
432 IPW_ERROR("Status: 0x%08X, Config: %08X\n", 511 "Nothing to dump.\n");
433 priv->status, priv->config); 512 return;
434 } 513 }
435 514
436 for (i = ERROR_START_OFFSET; 515 IPW_ERROR("Start IPW Error Log Dump:\n");
437 i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) { 516 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
438 desc = ipw_read_reg32(priv, base + i); 517 error->status, error->config);
439 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
440 blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
441 blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
442 ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
443 ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
444 idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
445 518
519 for (i = 0; i < error->elem_len; i++)
446 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 520 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
447 ipw_error_desc(desc), time, blink1, blink2, 521 ipw_error_desc(error->elem[i].desc),
448 ilink1, ilink2, idata); 522 error->elem[i].time,
449 } 523 error->elem[i].blink1,
524 error->elem[i].blink2,
525 error->elem[i].link1,
526 error->elem[i].link2, error->elem[i].data);
527 for (i = 0; i < error->log_len; i++)
528 IPW_ERROR("%i\t0x%08x\t%i\n",
529 error->log[i].time,
530 error->log[i].data, error->log[i].event);
450} 531}
532#endif
451 533
452static void ipw_dump_nic_event_log(struct ipw_priv *priv) 534static inline int ipw_is_init(struct ipw_priv *priv)
453{ 535{
454 u32 ev, time, data, i, count, base; 536 return (priv->status & STATUS_INIT) ? 1 : 0;
455
456 base = ipw_read32(priv, IPW_EVENT_LOG);
457 count = ipw_read_reg32(priv, base);
458
459 if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
460 IPW_ERROR("Start IPW Event Log Dump:\n");
461
462 for (i = EVENT_START_OFFSET;
463 i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
464 ev = ipw_read_reg32(priv, base + i);
465 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
466 data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
467
468#ifdef CONFIG_IPW_DEBUG
469 IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
470#endif
471 }
472} 537}
473 538
474static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len) 539static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
@@ -636,6 +701,340 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
636 701
637} 702}
638 703
704u32 ipw_register_toggle(u32 reg)
705{
706 reg &= ~IPW_START_STANDBY;
707 if (reg & IPW_GATE_ODMA)
708 reg &= ~IPW_GATE_ODMA;
709 if (reg & IPW_GATE_IDMA)
710 reg &= ~IPW_GATE_IDMA;
711 if (reg & IPW_GATE_ADMA)
712 reg &= ~IPW_GATE_ADMA;
713 return reg;
714}
715
716/*
717 * LED behavior:
718 * - On radio ON, turn on any LEDs that require to be on during start
719 * - On initialization, start unassociated blink
720 * - On association, disable unassociated blink
721 * - On disassociation, start unassociated blink
722 * - On radio OFF, turn off any LEDs started during radio on
723 *
724 */
725#define LD_TIME_LINK_ON 300
726#define LD_TIME_LINK_OFF 2700
727#define LD_TIME_ACT_ON 250
728
729void ipw_led_link_on(struct ipw_priv *priv)
730{
731 unsigned long flags;
732 u32 led;
733
734 /* If configured to not use LEDs, or nic_type is 1,
735 * then we don't toggle a LINK led */
736 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
737 return;
738
739 spin_lock_irqsave(&priv->lock, flags);
740
741 if (!(priv->status & STATUS_RF_KILL_MASK) &&
742 !(priv->status & STATUS_LED_LINK_ON)) {
743 IPW_DEBUG_LED("Link LED On\n");
744 led = ipw_read_reg32(priv, IPW_EVENT_REG);
745 led |= priv->led_association_on;
746
747 led = ipw_register_toggle(led);
748
749 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
750 ipw_write_reg32(priv, IPW_EVENT_REG, led);
751
752 priv->status |= STATUS_LED_LINK_ON;
753
754 /* If we aren't associated, schedule turning the LED off */
755 if (!(priv->status & STATUS_ASSOCIATED))
756 queue_delayed_work(priv->workqueue,
757 &priv->led_link_off,
758 LD_TIME_LINK_ON);
759 }
760
761 spin_unlock_irqrestore(&priv->lock, flags);
762}
763
764static void ipw_bg_led_link_on(void *data)
765{
766 struct ipw_priv *priv = data;
767 down(&priv->sem);
768 ipw_led_link_on(data);
769 up(&priv->sem);
770}
771
772void ipw_led_link_off(struct ipw_priv *priv)
773{
774 unsigned long flags;
775 u32 led;
776
777 /* If configured not to use LEDs, or nic type is 1,
778 * then we don't goggle the LINK led. */
779 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
780 return;
781
782 spin_lock_irqsave(&priv->lock, flags);
783
784 if (priv->status & STATUS_LED_LINK_ON) {
785 led = ipw_read_reg32(priv, IPW_EVENT_REG);
786 led &= priv->led_association_off;
787 led = ipw_register_toggle(led);
788
789 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
790 ipw_write_reg32(priv, IPW_EVENT_REG, led);
791
792 IPW_DEBUG_LED("Link LED Off\n");
793
794 priv->status &= ~STATUS_LED_LINK_ON;
795
796 /* If we aren't associated and the radio is on, schedule
797 * turning the LED on (blink while unassociated) */
798 if (!(priv->status & STATUS_RF_KILL_MASK) &&
799 !(priv->status & STATUS_ASSOCIATED))
800 queue_delayed_work(priv->workqueue, &priv->led_link_on,
801 LD_TIME_LINK_OFF);
802
803 }
804
805 spin_unlock_irqrestore(&priv->lock, flags);
806}
807
808static void ipw_bg_led_link_off(void *data)
809{
810 struct ipw_priv *priv = data;
811 down(&priv->sem);
812 ipw_led_link_off(data);
813 up(&priv->sem);
814}
815
816static inline void __ipw_led_activity_on(struct ipw_priv *priv)
817{
818 u32 led;
819
820 if (priv->config & CFG_NO_LED)
821 return;
822
823 if (priv->status & STATUS_RF_KILL_MASK)
824 return;
825
826 if (!(priv->status & STATUS_LED_ACT_ON)) {
827 led = ipw_read_reg32(priv, IPW_EVENT_REG);
828 led |= priv->led_activity_on;
829
830 led = ipw_register_toggle(led);
831
832 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
833 ipw_write_reg32(priv, IPW_EVENT_REG, led);
834
835 IPW_DEBUG_LED("Activity LED On\n");
836
837 priv->status |= STATUS_LED_ACT_ON;
838
839 cancel_delayed_work(&priv->led_act_off);
840 queue_delayed_work(priv->workqueue, &priv->led_act_off,
841 LD_TIME_ACT_ON);
842 } else {
843 /* Reschedule LED off for full time period */
844 cancel_delayed_work(&priv->led_act_off);
845 queue_delayed_work(priv->workqueue, &priv->led_act_off,
846 LD_TIME_ACT_ON);
847 }
848}
849
850void ipw_led_activity_on(struct ipw_priv *priv)
851{
852 unsigned long flags;
853 spin_lock_irqsave(&priv->lock, flags);
854 __ipw_led_activity_on(priv);
855 spin_unlock_irqrestore(&priv->lock, flags);
856}
857
858void ipw_led_activity_off(struct ipw_priv *priv)
859{
860 unsigned long flags;
861 u32 led;
862
863 if (priv->config & CFG_NO_LED)
864 return;
865
866 spin_lock_irqsave(&priv->lock, flags);
867
868 if (priv->status & STATUS_LED_ACT_ON) {
869 led = ipw_read_reg32(priv, IPW_EVENT_REG);
870 led &= priv->led_activity_off;
871
872 led = ipw_register_toggle(led);
873
874 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
875 ipw_write_reg32(priv, IPW_EVENT_REG, led);
876
877 IPW_DEBUG_LED("Activity LED Off\n");
878
879 priv->status &= ~STATUS_LED_ACT_ON;
880 }
881
882 spin_unlock_irqrestore(&priv->lock, flags);
883}
884
885static void ipw_bg_led_activity_off(void *data)
886{
887 struct ipw_priv *priv = data;
888 down(&priv->sem);
889 ipw_led_activity_off(data);
890 up(&priv->sem);
891}
892
893void ipw_led_band_on(struct ipw_priv *priv)
894{
895 unsigned long flags;
896 u32 led;
897
898 /* Only nic type 1 supports mode LEDs */
899 if (priv->config & CFG_NO_LED ||
900 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
901 return;
902
903 spin_lock_irqsave(&priv->lock, flags);
904
905 led = ipw_read_reg32(priv, IPW_EVENT_REG);
906 if (priv->assoc_network->mode == IEEE_A) {
907 led |= priv->led_ofdm_on;
908 led &= priv->led_association_off;
909 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
910 } else if (priv->assoc_network->mode == IEEE_G) {
911 led |= priv->led_ofdm_on;
912 led |= priv->led_association_on;
913 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
914 } else {
915 led &= priv->led_ofdm_off;
916 led |= priv->led_association_on;
917 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
918 }
919
920 led = ipw_register_toggle(led);
921
922 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
923 ipw_write_reg32(priv, IPW_EVENT_REG, led);
924
925 spin_unlock_irqrestore(&priv->lock, flags);
926}
927
928void ipw_led_band_off(struct ipw_priv *priv)
929{
930 unsigned long flags;
931 u32 led;
932
933 /* Only nic type 1 supports mode LEDs */
934 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
935 return;
936
937 spin_lock_irqsave(&priv->lock, flags);
938
939 led = ipw_read_reg32(priv, IPW_EVENT_REG);
940 led &= priv->led_ofdm_off;
941 led &= priv->led_association_off;
942
943 led = ipw_register_toggle(led);
944
945 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
946 ipw_write_reg32(priv, IPW_EVENT_REG, led);
947
948 spin_unlock_irqrestore(&priv->lock, flags);
949}
950
951void ipw_led_radio_on(struct ipw_priv *priv)
952{
953 ipw_led_link_on(priv);
954}
955
956void ipw_led_radio_off(struct ipw_priv *priv)
957{
958 ipw_led_activity_off(priv);
959 ipw_led_link_off(priv);
960}
961
962void ipw_led_link_up(struct ipw_priv *priv)
963{
964 /* Set the Link Led on for all nic types */
965 ipw_led_link_on(priv);
966}
967
968void ipw_led_link_down(struct ipw_priv *priv)
969{
970 ipw_led_activity_off(priv);
971 ipw_led_link_off(priv);
972
973 if (priv->status & STATUS_RF_KILL_MASK)
974 ipw_led_radio_off(priv);
975}
976
977void ipw_led_init(struct ipw_priv *priv)
978{
979 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
980
981 /* Set the default PINs for the link and activity leds */
982 priv->led_activity_on = IPW_ACTIVITY_LED;
983 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
984
985 priv->led_association_on = IPW_ASSOCIATED_LED;
986 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
987
988 /* Set the default PINs for the OFDM leds */
989 priv->led_ofdm_on = IPW_OFDM_LED;
990 priv->led_ofdm_off = ~(IPW_OFDM_LED);
991
992 switch (priv->nic_type) {
993 case EEPROM_NIC_TYPE_1:
994 /* In this NIC type, the LEDs are reversed.... */
995 priv->led_activity_on = IPW_ASSOCIATED_LED;
996 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
997 priv->led_association_on = IPW_ACTIVITY_LED;
998 priv->led_association_off = ~(IPW_ACTIVITY_LED);
999
1000 if (!(priv->config & CFG_NO_LED))
1001 ipw_led_band_on(priv);
1002
1003 /* And we don't blink link LEDs for this nic, so
1004 * just return here */
1005 return;
1006
1007 case EEPROM_NIC_TYPE_3:
1008 case EEPROM_NIC_TYPE_2:
1009 case EEPROM_NIC_TYPE_4:
1010 case EEPROM_NIC_TYPE_0:
1011 break;
1012
1013 default:
1014 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1015 priv->nic_type);
1016 priv->nic_type = EEPROM_NIC_TYPE_0;
1017 break;
1018 }
1019
1020 if (!(priv->config & CFG_NO_LED)) {
1021 if (priv->status & STATUS_ASSOCIATED)
1022 ipw_led_link_on(priv);
1023 else
1024 ipw_led_link_off(priv);
1025 }
1026}
1027
1028void ipw_led_shutdown(struct ipw_priv *priv)
1029{
1030 ipw_led_activity_off(priv);
1031 ipw_led_link_off(priv);
1032 ipw_led_band_off(priv);
1033 cancel_delayed_work(&priv->led_link_on);
1034 cancel_delayed_work(&priv->led_link_off);
1035 cancel_delayed_work(&priv->led_act_off);
1036}
1037
639/* 1038/*
640 * The following adds a new attribute to the sysfs representation 1039 * The following adds a new attribute to the sysfs representation
641 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) 1040 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
@@ -647,8 +1046,9 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
647{ 1046{
648 return sprintf(buf, "0x%08X\n", ipw_debug_level); 1047 return sprintf(buf, "0x%08X\n", ipw_debug_level);
649} 1048}
650static ssize_t store_debug_level(struct device_driver *d, 1049
651 const char *buf, size_t count) 1050static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1051 size_t count)
652{ 1052{
653 char *p = (char *)buf; 1053 char *p = (char *)buf;
654 u32 val; 1054 u32 val;
@@ -672,75 +1072,263 @@ static ssize_t store_debug_level(struct device_driver *d,
672static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 1072static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
673 show_debug_level, store_debug_level); 1073 show_debug_level, store_debug_level);
674 1074
675static ssize_t show_status(struct device *d, 1075static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
676 struct device_attribute *attr, char *buf)
677{ 1076{
678 struct ipw_priv *p = d->driver_data; 1077 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
679 return sprintf(buf, "0x%08x\n", (int)p->status);
680} 1078}
681 1079
682static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 1080static void ipw_capture_event_log(struct ipw_priv *priv,
1081 u32 log_len, struct ipw_event *log)
1082{
1083 u32 base;
683 1084
684static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 1085 if (log_len) {
685 char *buf) 1086 base = ipw_read32(priv, IPW_EVENT_LOG);
1087 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
1088 (u8 *) log, sizeof(*log) * log_len);
1089 }
1090}
1091
1092static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
686{ 1093{
687 struct ipw_priv *p = d->driver_data; 1094 struct ipw_fw_error *error;
688 return sprintf(buf, "0x%08x\n", (int)p->config); 1095 u32 log_len = ipw_get_event_log_len(priv);
1096 u32 base = ipw_read32(priv, IPW_ERROR_LOG);
1097 u32 elem_len = ipw_read_reg32(priv, base);
1098
1099 error = kmalloc(sizeof(*error) +
1100 sizeof(*error->elem) * elem_len +
1101 sizeof(*error->log) * log_len, GFP_ATOMIC);
1102 if (!error) {
1103 IPW_ERROR("Memory allocation for firmware error log "
1104 "failed.\n");
1105 return NULL;
1106 }
1107 error->jiffies = jiffies;
1108 error->status = priv->status;
1109 error->config = priv->config;
1110 error->elem_len = elem_len;
1111 error->log_len = log_len;
1112 error->elem = (struct ipw_error_elem *)error->payload;
1113 error->log = (struct ipw_event *)(error->elem +
1114 (sizeof(*error->elem) * elem_len));
1115
1116 ipw_capture_event_log(priv, log_len, error->log);
1117
1118 if (elem_len)
1119 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
1120 sizeof(*error->elem) * elem_len);
1121
1122 return error;
689} 1123}
690 1124
691static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 1125static void ipw_free_error_log(struct ipw_fw_error *error)
1126{
1127 if (error)
1128 kfree(error);
1129}
692 1130
693static ssize_t show_nic_type(struct device *d, 1131static ssize_t show_event_log(struct device *d,
694 struct device_attribute *attr, char *buf) 1132 struct device_attribute *attr, char *buf)
695{ 1133{
696 struct ipw_priv *p = d->driver_data; 1134 struct ipw_priv *priv = dev_get_drvdata(d);
697 u8 type = p->eeprom[EEPROM_NIC_TYPE]; 1135 u32 log_len = ipw_get_event_log_len(priv);
1136 struct ipw_event log[log_len];
1137 u32 len = 0, i;
1138
1139 ipw_capture_event_log(priv, log_len, log);
1140
1141 len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1142 for (i = 0; i < log_len; i++)
1143 len += snprintf(buf + len, PAGE_SIZE - len,
1144 "\n%08X%08X%08X",
1145 log[i].time, log[i].event, log[i].data);
1146 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1147 return len;
1148}
698 1149
699 switch (type) { 1150static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
700 case EEPROM_NIC_TYPE_STANDARD: 1151
701 return sprintf(buf, "STANDARD\n"); 1152static ssize_t show_error(struct device *d,
702 case EEPROM_NIC_TYPE_DELL: 1153 struct device_attribute *attr, char *buf)
703 return sprintf(buf, "DELL\n"); 1154{
704 case EEPROM_NIC_TYPE_FUJITSU: 1155 struct ipw_priv *priv = dev_get_drvdata(d);
705 return sprintf(buf, "FUJITSU\n"); 1156 u32 len = 0, i;
706 case EEPROM_NIC_TYPE_IBM: 1157 if (!priv->error)
707 return sprintf(buf, "IBM\n"); 1158 return 0;
708 case EEPROM_NIC_TYPE_HP: 1159 len += snprintf(buf + len, PAGE_SIZE - len,
709 return sprintf(buf, "HP\n"); 1160 "%08lX%08X%08X%08X",
1161 priv->error->jiffies,
1162 priv->error->status,
1163 priv->error->config, priv->error->elem_len);
1164 for (i = 0; i < priv->error->elem_len; i++)
1165 len += snprintf(buf + len, PAGE_SIZE - len,
1166 "\n%08X%08X%08X%08X%08X%08X%08X",
1167 priv->error->elem[i].time,
1168 priv->error->elem[i].desc,
1169 priv->error->elem[i].blink1,
1170 priv->error->elem[i].blink2,
1171 priv->error->elem[i].link1,
1172 priv->error->elem[i].link2,
1173 priv->error->elem[i].data);
1174
1175 len += snprintf(buf + len, PAGE_SIZE - len,
1176 "\n%08X", priv->error->log_len);
1177 for (i = 0; i < priv->error->log_len; i++)
1178 len += snprintf(buf + len, PAGE_SIZE - len,
1179 "\n%08X%08X%08X",
1180 priv->error->log[i].time,
1181 priv->error->log[i].event,
1182 priv->error->log[i].data);
1183 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1184 return len;
1185}
1186
1187static ssize_t clear_error(struct device *d,
1188 struct device_attribute *attr,
1189 const char *buf, size_t count)
1190{
1191 struct ipw_priv *priv = dev_get_drvdata(d);
1192 if (priv->error) {
1193 ipw_free_error_log(priv->error);
1194 priv->error = NULL;
710 } 1195 }
1196 return count;
1197}
1198
1199static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
711 1200
712 return sprintf(buf, "UNKNOWN\n"); 1201static ssize_t show_cmd_log(struct device *d,
1202 struct device_attribute *attr, char *buf)
1203{
1204 struct ipw_priv *priv = dev_get_drvdata(d);
1205 u32 len = 0, i;
1206 if (!priv->cmdlog)
1207 return 0;
1208 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
1209 (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
1210 i = (i + 1) % priv->cmdlog_len) {
1211 len +=
1212 snprintf(buf + len, PAGE_SIZE - len,
1213 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
1214 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
1215 priv->cmdlog[i].cmd.len);
1216 len +=
1217 snprintk_buf(buf + len, PAGE_SIZE - len,
1218 (u8 *) priv->cmdlog[i].cmd.param,
1219 priv->cmdlog[i].cmd.len);
1220 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1221 }
1222 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1223 return len;
713} 1224}
714 1225
715static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); 1226static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
716 1227
717static ssize_t dump_error_log(struct device *d, 1228static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
718 struct device_attribute *attr, const char *buf, 1229 char *buf)
719 size_t count)
720{ 1230{
721 char *p = (char *)buf; 1231 struct ipw_priv *priv = dev_get_drvdata(d);
1232 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1233}
722 1234
723 if (p[0] == '1') 1235static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
724 ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data); 1236 const char *buf, size_t count)
1237{
1238 struct ipw_priv *priv = dev_get_drvdata(d);
1239#ifdef CONFIG_IPW_DEBUG
1240 struct net_device *dev = priv->net_dev;
1241#endif
1242 char buffer[] = "00000000";
1243 unsigned long len =
1244 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1245 unsigned long val;
1246 char *p = buffer;
725 1247
726 return strnlen(buf, count); 1248 IPW_DEBUG_INFO("enter\n");
1249
1250 strncpy(buffer, buf, len);
1251 buffer[len] = 0;
1252
1253 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1254 p++;
1255 if (p[0] == 'x' || p[0] == 'X')
1256 p++;
1257 val = simple_strtoul(p, &p, 16);
1258 } else
1259 val = simple_strtoul(p, &p, 10);
1260 if (p == buffer) {
1261 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1262 } else {
1263 priv->ieee->scan_age = val;
1264 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1265 }
1266
1267 IPW_DEBUG_INFO("exit\n");
1268 return len;
727} 1269}
728 1270
729static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); 1271static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
730 1272
731static ssize_t dump_event_log(struct device *d, 1273static ssize_t show_led(struct device *d, struct device_attribute *attr,
732 struct device_attribute *attr, const char *buf, 1274 char *buf)
733 size_t count)
734{ 1275{
735 char *p = (char *)buf; 1276 struct ipw_priv *priv = dev_get_drvdata(d);
1277 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1278}
736 1279
737 if (p[0] == '1') 1280static ssize_t store_led(struct device *d, struct device_attribute *attr,
738 ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data); 1281 const char *buf, size_t count)
1282{
1283 struct ipw_priv *priv = dev_get_drvdata(d);
739 1284
740 return strnlen(buf, count); 1285 IPW_DEBUG_INFO("enter\n");
1286
1287 if (count == 0)
1288 return 0;
1289
1290 if (*buf == 0) {
1291 IPW_DEBUG_LED("Disabling LED control.\n");
1292 priv->config |= CFG_NO_LED;
1293 ipw_led_shutdown(priv);
1294 } else {
1295 IPW_DEBUG_LED("Enabling LED control.\n");
1296 priv->config &= ~CFG_NO_LED;
1297 ipw_led_init(priv);
1298 }
1299
1300 IPW_DEBUG_INFO("exit\n");
1301 return count;
1302}
1303
1304static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1305
1306static ssize_t show_status(struct device *d,
1307 struct device_attribute *attr, char *buf)
1308{
1309 struct ipw_priv *p = d->driver_data;
1310 return sprintf(buf, "0x%08x\n", (int)p->status);
741} 1311}
742 1312
743static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); 1313static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1314
1315static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1316 char *buf)
1317{
1318 struct ipw_priv *p = d->driver_data;
1319 return sprintf(buf, "0x%08x\n", (int)p->config);
1320}
1321
1322static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1323
1324static ssize_t show_nic_type(struct device *d,
1325 struct device_attribute *attr, char *buf)
1326{
1327 struct ipw_priv *priv = d->driver_data;
1328 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
1329}
1330
1331static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
744 1332
745static ssize_t show_ucode_version(struct device *d, 1333static ssize_t show_ucode_version(struct device *d,
746 struct device_attribute *attr, char *buf) 1334 struct device_attribute *attr, char *buf)
@@ -798,7 +1386,7 @@ static ssize_t show_command_event_reg(struct device *d,
798 u32 reg = 0; 1386 u32 reg = 0;
799 struct ipw_priv *p = d->driver_data; 1387 struct ipw_priv *p = d->driver_data;
800 1388
801 reg = ipw_read_reg32(p, CX2_INTERNAL_CMD_EVENT); 1389 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
802 return sprintf(buf, "0x%08x\n", reg); 1390 return sprintf(buf, "0x%08x\n", reg);
803} 1391}
804static ssize_t store_command_event_reg(struct device *d, 1392static ssize_t store_command_event_reg(struct device *d,
@@ -809,7 +1397,7 @@ static ssize_t store_command_event_reg(struct device *d,
809 struct ipw_priv *p = d->driver_data; 1397 struct ipw_priv *p = d->driver_data;
810 1398
811 sscanf(buf, "%x", &reg); 1399 sscanf(buf, "%x", &reg);
812 ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg); 1400 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
813 return strnlen(buf, count); 1401 return strnlen(buf, count);
814} 1402}
815 1403
@@ -845,6 +1433,7 @@ static ssize_t show_indirect_dword(struct device *d,
845{ 1433{
846 u32 reg = 0; 1434 u32 reg = 0;
847 struct ipw_priv *priv = d->driver_data; 1435 struct ipw_priv *priv = d->driver_data;
1436
848 if (priv->status & STATUS_INDIRECT_DWORD) 1437 if (priv->status & STATUS_INDIRECT_DWORD)
849 reg = ipw_read_reg32(priv, priv->indirect_dword); 1438 reg = ipw_read_reg32(priv, priv->indirect_dword);
850 else 1439 else
@@ -871,6 +1460,7 @@ static ssize_t show_indirect_byte(struct device *d,
871{ 1460{
872 u8 reg = 0; 1461 u8 reg = 0;
873 struct ipw_priv *priv = d->driver_data; 1462 struct ipw_priv *priv = d->driver_data;
1463
874 if (priv->status & STATUS_INDIRECT_BYTE) 1464 if (priv->status & STATUS_INDIRECT_BYTE)
875 reg = ipw_read_reg8(priv, priv->indirect_byte); 1465 reg = ipw_read_reg8(priv, priv->indirect_byte);
876 else 1466 else
@@ -945,7 +1535,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
945static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) 1535static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
946{ 1536{
947 if ((disable_radio ? 1 : 0) == 1537 if ((disable_radio ? 1 : 0) ==
948 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 1538 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
949 return 0; 1539 return 0;
950 1540
951 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 1541 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
@@ -954,10 +1544,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
954 if (disable_radio) { 1544 if (disable_radio) {
955 priv->status |= STATUS_RF_KILL_SW; 1545 priv->status |= STATUS_RF_KILL_SW;
956 1546
957 if (priv->workqueue) { 1547 if (priv->workqueue)
958 cancel_delayed_work(&priv->request_scan); 1548 cancel_delayed_work(&priv->request_scan);
959 }
960 wake_up_interruptible(&priv->wait_command_queue);
961 queue_work(priv->workqueue, &priv->down); 1549 queue_work(priv->workqueue, &priv->down);
962 } else { 1550 } else {
963 priv->status &= ~STATUS_RF_KILL_SW; 1551 priv->status &= ~STATUS_RF_KILL_SW;
@@ -987,6 +1575,93 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
987 1575
988static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); 1576static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
989 1577
1578static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1579 char *buf)
1580{
1581 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1582 int pos = 0, len = 0;
1583 if (priv->config & CFG_SPEED_SCAN) {
1584 while (priv->speed_scan[pos] != 0)
1585 len += sprintf(&buf[len], "%d ",
1586 priv->speed_scan[pos++]);
1587 return len + sprintf(&buf[len], "\n");
1588 }
1589
1590 return sprintf(buf, "0\n");
1591}
1592
1593static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1594 const char *buf, size_t count)
1595{
1596 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1597 int channel, pos = 0;
1598 const char *p = buf;
1599
1600 /* list of space separated channels to scan, optionally ending with 0 */
1601 while ((channel = simple_strtol(p, NULL, 0))) {
1602 if (pos == MAX_SPEED_SCAN - 1) {
1603 priv->speed_scan[pos] = 0;
1604 break;
1605 }
1606
1607 if (ipw_is_valid_channel(priv->ieee, channel))
1608 priv->speed_scan[pos++] = channel;
1609 else
1610 IPW_WARNING("Skipping invalid channel request: %d\n",
1611 channel);
1612 p = strchr(p, ' ');
1613 if (!p)
1614 break;
1615 while (*p == ' ' || *p == '\t')
1616 p++;
1617 }
1618
1619 if (pos == 0)
1620 priv->config &= ~CFG_SPEED_SCAN;
1621 else {
1622 priv->speed_scan_pos = 0;
1623 priv->config |= CFG_SPEED_SCAN;
1624 }
1625
1626 return count;
1627}
1628
1629static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1630 store_speed_scan);
1631
1632static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1633 char *buf)
1634{
1635 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1636 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1637}
1638
1639static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1640 const char *buf, size_t count)
1641{
1642 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1643 if (buf[0] == '1')
1644 priv->config |= CFG_NET_STATS;
1645 else
1646 priv->config &= ~CFG_NET_STATS;
1647
1648 return count;
1649}
1650
1651static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1652 show_net_stats, store_net_stats);
1653
1654static void notify_wx_assoc_event(struct ipw_priv *priv)
1655{
1656 union iwreq_data wrqu;
1657 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1658 if (priv->status & STATUS_ASSOCIATED)
1659 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1660 else
1661 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1662 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1663}
1664
990static void ipw_irq_tasklet(struct ipw_priv *priv) 1665static void ipw_irq_tasklet(struct ipw_priv *priv)
991{ 1666{
992 u32 inta, inta_mask, handled = 0; 1667 u32 inta, inta_mask, handled = 0;
@@ -995,102 +1670,135 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
995 1670
996 spin_lock_irqsave(&priv->lock, flags); 1671 spin_lock_irqsave(&priv->lock, flags);
997 1672
998 inta = ipw_read32(priv, CX2_INTA_RW); 1673 inta = ipw_read32(priv, IPW_INTA_RW);
999 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 1674 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
1000 inta &= (CX2_INTA_MASK_ALL & inta_mask); 1675 inta &= (IPW_INTA_MASK_ALL & inta_mask);
1001 1676
1002 /* Add any cached INTA values that need to be handled */ 1677 /* Add any cached INTA values that need to be handled */
1003 inta |= priv->isr_inta; 1678 inta |= priv->isr_inta;
1004 1679
1005 /* handle all the justifications for the interrupt */ 1680 /* handle all the justifications for the interrupt */
1006 if (inta & CX2_INTA_BIT_RX_TRANSFER) { 1681 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
1007 ipw_rx(priv); 1682 ipw_rx(priv);
1008 handled |= CX2_INTA_BIT_RX_TRANSFER; 1683 handled |= IPW_INTA_BIT_RX_TRANSFER;
1009 } 1684 }
1010 1685
1011 if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) { 1686 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
1012 IPW_DEBUG_HC("Command completed.\n"); 1687 IPW_DEBUG_HC("Command completed.\n");
1013 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1); 1688 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
1014 priv->status &= ~STATUS_HCMD_ACTIVE; 1689 priv->status &= ~STATUS_HCMD_ACTIVE;
1015 wake_up_interruptible(&priv->wait_command_queue); 1690 wake_up_interruptible(&priv->wait_command_queue);
1016 handled |= CX2_INTA_BIT_TX_CMD_QUEUE; 1691 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
1017 } 1692 }
1018 1693
1019 if (inta & CX2_INTA_BIT_TX_QUEUE_1) { 1694 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
1020 IPW_DEBUG_TX("TX_QUEUE_1\n"); 1695 IPW_DEBUG_TX("TX_QUEUE_1\n");
1021 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0); 1696 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
1022 handled |= CX2_INTA_BIT_TX_QUEUE_1; 1697 handled |= IPW_INTA_BIT_TX_QUEUE_1;
1023 } 1698 }
1024 1699
1025 if (inta & CX2_INTA_BIT_TX_QUEUE_2) { 1700 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
1026 IPW_DEBUG_TX("TX_QUEUE_2\n"); 1701 IPW_DEBUG_TX("TX_QUEUE_2\n");
1027 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1); 1702 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
1028 handled |= CX2_INTA_BIT_TX_QUEUE_2; 1703 handled |= IPW_INTA_BIT_TX_QUEUE_2;
1029 } 1704 }
1030 1705
1031 if (inta & CX2_INTA_BIT_TX_QUEUE_3) { 1706 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
1032 IPW_DEBUG_TX("TX_QUEUE_3\n"); 1707 IPW_DEBUG_TX("TX_QUEUE_3\n");
1033 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2); 1708 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
1034 handled |= CX2_INTA_BIT_TX_QUEUE_3; 1709 handled |= IPW_INTA_BIT_TX_QUEUE_3;
1035 } 1710 }
1036 1711
1037 if (inta & CX2_INTA_BIT_TX_QUEUE_4) { 1712 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
1038 IPW_DEBUG_TX("TX_QUEUE_4\n"); 1713 IPW_DEBUG_TX("TX_QUEUE_4\n");
1039 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3); 1714 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
1040 handled |= CX2_INTA_BIT_TX_QUEUE_4; 1715 handled |= IPW_INTA_BIT_TX_QUEUE_4;
1041 } 1716 }
1042 1717
1043 if (inta & CX2_INTA_BIT_STATUS_CHANGE) { 1718 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
1044 IPW_WARNING("STATUS_CHANGE\n"); 1719 IPW_WARNING("STATUS_CHANGE\n");
1045 handled |= CX2_INTA_BIT_STATUS_CHANGE; 1720 handled |= IPW_INTA_BIT_STATUS_CHANGE;
1046 } 1721 }
1047 1722
1048 if (inta & CX2_INTA_BIT_BEACON_PERIOD_EXPIRED) { 1723 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
1049 IPW_WARNING("TX_PERIOD_EXPIRED\n"); 1724 IPW_WARNING("TX_PERIOD_EXPIRED\n");
1050 handled |= CX2_INTA_BIT_BEACON_PERIOD_EXPIRED; 1725 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
1051 } 1726 }
1052 1727
1053 if (inta & CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) { 1728 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
1054 IPW_WARNING("HOST_CMD_DONE\n"); 1729 IPW_WARNING("HOST_CMD_DONE\n");
1055 handled |= CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE; 1730 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
1056 } 1731 }
1057 1732
1058 if (inta & CX2_INTA_BIT_FW_INITIALIZATION_DONE) { 1733 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
1059 IPW_WARNING("FW_INITIALIZATION_DONE\n"); 1734 IPW_WARNING("FW_INITIALIZATION_DONE\n");
1060 handled |= CX2_INTA_BIT_FW_INITIALIZATION_DONE; 1735 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
1061 } 1736 }
1062 1737
1063 if (inta & CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) { 1738 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
1064 IPW_WARNING("PHY_OFF_DONE\n"); 1739 IPW_WARNING("PHY_OFF_DONE\n");
1065 handled |= CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE; 1740 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
1066 } 1741 }
1067 1742
1068 if (inta & CX2_INTA_BIT_RF_KILL_DONE) { 1743 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
1069 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); 1744 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1070 priv->status |= STATUS_RF_KILL_HW; 1745 priv->status |= STATUS_RF_KILL_HW;
1071 wake_up_interruptible(&priv->wait_command_queue); 1746 wake_up_interruptible(&priv->wait_command_queue);
1072 netif_carrier_off(priv->net_dev); 1747 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1073 netif_stop_queue(priv->net_dev);
1074 cancel_delayed_work(&priv->request_scan); 1748 cancel_delayed_work(&priv->request_scan);
1749 schedule_work(&priv->link_down);
1075 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); 1750 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1076 handled |= CX2_INTA_BIT_RF_KILL_DONE; 1751 handled |= IPW_INTA_BIT_RF_KILL_DONE;
1077 } 1752 }
1078 1753
1079 if (inta & CX2_INTA_BIT_FATAL_ERROR) { 1754 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
1080 IPW_ERROR("Firmware error detected. Restarting.\n"); 1755 IPW_ERROR("Firmware error detected. Restarting.\n");
1756 if (priv->error) {
1757 IPW_ERROR("Sysfs 'error' log already exists.\n");
1081#ifdef CONFIG_IPW_DEBUG 1758#ifdef CONFIG_IPW_DEBUG
1082 if (ipw_debug_level & IPW_DL_FW_ERRORS) { 1759 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1083 ipw_dump_nic_error_log(priv); 1760 struct ipw_fw_error *error =
1084 ipw_dump_nic_event_log(priv); 1761 ipw_alloc_error_log(priv);
1085 } 1762 ipw_dump_error_log(priv, error);
1763 if (error)
1764 ipw_free_error_log(error);
1765 }
1086#endif 1766#endif
1767 } else {
1768 priv->error = ipw_alloc_error_log(priv);
1769 if (priv->error)
1770 IPW_ERROR("Sysfs 'error' log captured.\n");
1771 else
1772 IPW_ERROR("Error allocating sysfs 'error' "
1773 "log.\n");
1774#ifdef CONFIG_IPW_DEBUG
1775 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1776 ipw_dump_error_log(priv, priv->error);
1777#endif
1778 }
1779
1780 /* XXX: If hardware encryption is for WPA/WPA2,
1781 * we have to notify the supplicant. */
1782 if (priv->ieee->sec.encrypt) {
1783 priv->status &= ~STATUS_ASSOCIATED;
1784 notify_wx_assoc_event(priv);
1785 }
1786
1787 /* Keep the restart process from trying to send host
1788 * commands by clearing the INIT status bit */
1789 priv->status &= ~STATUS_INIT;
1790
1791 /* Cancel currently queued command. */
1792 priv->status &= ~STATUS_HCMD_ACTIVE;
1793 wake_up_interruptible(&priv->wait_command_queue);
1794
1087 queue_work(priv->workqueue, &priv->adapter_restart); 1795 queue_work(priv->workqueue, &priv->adapter_restart);
1088 handled |= CX2_INTA_BIT_FATAL_ERROR; 1796 handled |= IPW_INTA_BIT_FATAL_ERROR;
1089 } 1797 }
1090 1798
1091 if (inta & CX2_INTA_BIT_PARITY_ERROR) { 1799 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
1092 IPW_ERROR("Parity error\n"); 1800 IPW_ERROR("Parity error\n");
1093 handled |= CX2_INTA_BIT_PARITY_ERROR; 1801 handled |= IPW_INTA_BIT_PARITY_ERROR;
1094 } 1802 }
1095 1803
1096 if (handled != inta) { 1804 if (handled != inta) {
@@ -1103,7 +1811,6 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1103 spin_unlock_irqrestore(&priv->lock, flags); 1811 spin_unlock_irqrestore(&priv->lock, flags);
1104} 1812}
1105 1813
1106#ifdef CONFIG_IPW_DEBUG
1107#define IPW_CMD(x) case IPW_CMD_ ## x : return #x 1814#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1108static char *get_cmd_string(u8 cmd) 1815static char *get_cmd_string(u8 cmd)
1109{ 1816{
@@ -1162,44 +1869,78 @@ static char *get_cmd_string(u8 cmd)
1162 return "UNKNOWN"; 1869 return "UNKNOWN";
1163 } 1870 }
1164} 1871}
1165#endif /* CONFIG_IPW_DEBUG */
1166 1872
1167#define HOST_COMPLETE_TIMEOUT HZ 1873#define HOST_COMPLETE_TIMEOUT HZ
1168static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) 1874static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1169{ 1875{
1170 int rc = 0; 1876 int rc = 0;
1877 unsigned long flags;
1171 1878
1879 spin_lock_irqsave(&priv->lock, flags);
1172 if (priv->status & STATUS_HCMD_ACTIVE) { 1880 if (priv->status & STATUS_HCMD_ACTIVE) {
1173 IPW_ERROR("Already sending a command\n"); 1881 IPW_ERROR("Failed to send %s: Already sending a command.\n",
1174 return -1; 1882 get_cmd_string(cmd->cmd));
1883 spin_unlock_irqrestore(&priv->lock, flags);
1884 return -EAGAIN;
1175 } 1885 }
1176 1886
1177 priv->status |= STATUS_HCMD_ACTIVE; 1887 priv->status |= STATUS_HCMD_ACTIVE;
1178 1888
1179 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 1889 if (priv->cmdlog) {
1180 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len); 1890 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
1891 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
1892 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
1893 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
1894 cmd->len);
1895 priv->cmdlog[priv->cmdlog_pos].retcode = -1;
1896 }
1897
1898 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
1899 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
1900 priv->status);
1181 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); 1901 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
1182 1902
1183 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); 1903 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
1184 if (rc) 1904 if (rc) {
1185 return rc; 1905 priv->status &= ~STATUS_HCMD_ACTIVE;
1906 IPW_ERROR("Failed to send %s: Reason %d\n",
1907 get_cmd_string(cmd->cmd), rc);
1908 spin_unlock_irqrestore(&priv->lock, flags);
1909 goto exit;
1910 }
1911 spin_unlock_irqrestore(&priv->lock, flags);
1186 1912
1187 rc = wait_event_interruptible_timeout(priv->wait_command_queue, 1913 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1188 !(priv-> 1914 !(priv->
1189 status & STATUS_HCMD_ACTIVE), 1915 status & STATUS_HCMD_ACTIVE),
1190 HOST_COMPLETE_TIMEOUT); 1916 HOST_COMPLETE_TIMEOUT);
1191 if (rc == 0) { 1917 if (rc == 0) {
1192 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 1918 spin_lock_irqsave(&priv->lock, flags);
1193 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 1919 if (priv->status & STATUS_HCMD_ACTIVE) {
1194 priv->status &= ~STATUS_HCMD_ACTIVE; 1920 IPW_ERROR("Failed to send %s: Command timed out.\n",
1195 return -EIO; 1921 get_cmd_string(cmd->cmd));
1196 } 1922 priv->status &= ~STATUS_HCMD_ACTIVE;
1197 if (priv->status & STATUS_RF_KILL_MASK) { 1923 spin_unlock_irqrestore(&priv->lock, flags);
1198 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n"); 1924 rc = -EIO;
1199 return -EIO; 1925 goto exit;
1926 }
1927 spin_unlock_irqrestore(&priv->lock, flags);
1928 } else
1929 rc = 0;
1930
1931 if (priv->status & STATUS_RF_KILL_HW) {
1932 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
1933 get_cmd_string(cmd->cmd));
1934 rc = -EIO;
1935 goto exit;
1200 } 1936 }
1201 1937
1202 return 0; 1938 exit:
1939 if (priv->cmdlog) {
1940 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
1941 priv->cmdlog_pos %= priv->cmdlog_len;
1942 }
1943 return rc;
1203} 1944}
1204 1945
1205static int ipw_send_host_complete(struct ipw_priv *priv) 1946static int ipw_send_host_complete(struct ipw_priv *priv)
@@ -1214,12 +1955,7 @@ static int ipw_send_host_complete(struct ipw_priv *priv)
1214 return -1; 1955 return -1;
1215 } 1956 }
1216 1957
1217 if (ipw_send_cmd(priv, &cmd)) { 1958 return ipw_send_cmd(priv, &cmd);
1218 IPW_ERROR("failed to send HOST_COMPLETE command\n");
1219 return -1;
1220 }
1221
1222 return 0;
1223} 1959}
1224 1960
1225static int ipw_send_system_config(struct ipw_priv *priv, 1961static int ipw_send_system_config(struct ipw_priv *priv,
@@ -1235,13 +1971,8 @@ static int ipw_send_system_config(struct ipw_priv *priv,
1235 return -1; 1971 return -1;
1236 } 1972 }
1237 1973
1238 memcpy(&cmd.param, config, sizeof(*config)); 1974 memcpy(cmd.param, config, sizeof(*config));
1239 if (ipw_send_cmd(priv, &cmd)) { 1975 return ipw_send_cmd(priv, &cmd);
1240 IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
1241 return -1;
1242 }
1243
1244 return 0;
1245} 1976}
1246 1977
1247static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) 1978static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -1256,13 +1987,8 @@ static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
1256 return -1; 1987 return -1;
1257 } 1988 }
1258 1989
1259 memcpy(&cmd.param, ssid, cmd.len); 1990 memcpy(cmd.param, ssid, cmd.len);
1260 if (ipw_send_cmd(priv, &cmd)) { 1991 return ipw_send_cmd(priv, &cmd);
1261 IPW_ERROR("failed to send SSID command\n");
1262 return -1;
1263 }
1264
1265 return 0;
1266} 1992}
1267 1993
1268static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) 1994static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
@@ -1280,16 +2006,15 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
1280 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", 2006 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
1281 priv->net_dev->name, MAC_ARG(mac)); 2007 priv->net_dev->name, MAC_ARG(mac));
1282 2008
1283 memcpy(&cmd.param, mac, ETH_ALEN); 2009 memcpy(cmd.param, mac, ETH_ALEN);
1284 2010 return ipw_send_cmd(priv, &cmd);
1285 if (ipw_send_cmd(priv, &cmd)) {
1286 IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
1287 return -1;
1288 }
1289
1290 return 0;
1291} 2011}
1292 2012
2013/*
2014 * NOTE: This must be executed from our workqueue as it results in udelay
2015 * being called which may corrupt the keyboard if executed on default
2016 * workqueue
2017 */
1293static void ipw_adapter_restart(void *adapter) 2018static void ipw_adapter_restart(void *adapter)
1294{ 2019{
1295 struct ipw_priv *priv = adapter; 2020 struct ipw_priv *priv = adapter;
@@ -1298,12 +2023,25 @@ static void ipw_adapter_restart(void *adapter)
1298 return; 2023 return;
1299 2024
1300 ipw_down(priv); 2025 ipw_down(priv);
2026
2027 if (priv->assoc_network &&
2028 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
2029 ipw_remove_current_network(priv);
2030
1301 if (ipw_up(priv)) { 2031 if (ipw_up(priv)) {
1302 IPW_ERROR("Failed to up device\n"); 2032 IPW_ERROR("Failed to up device\n");
1303 return; 2033 return;
1304 } 2034 }
1305} 2035}
1306 2036
2037static void ipw_bg_adapter_restart(void *data)
2038{
2039 struct ipw_priv *priv = data;
2040 down(&priv->sem);
2041 ipw_adapter_restart(data);
2042 up(&priv->sem);
2043}
2044
1307#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) 2045#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
1308 2046
1309static void ipw_scan_check(void *data) 2047static void ipw_scan_check(void *data)
@@ -1313,10 +2051,18 @@ static void ipw_scan_check(void *data)
1313 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 2051 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
1314 "adapter (%dms).\n", 2052 "adapter (%dms).\n",
1315 IPW_SCAN_CHECK_WATCHDOG / 100); 2053 IPW_SCAN_CHECK_WATCHDOG / 100);
1316 ipw_adapter_restart(priv); 2054 queue_work(priv->workqueue, &priv->adapter_restart);
1317 } 2055 }
1318} 2056}
1319 2057
2058static void ipw_bg_scan_check(void *data)
2059{
2060 struct ipw_priv *priv = data;
2061 down(&priv->sem);
2062 ipw_scan_check(data);
2063 up(&priv->sem);
2064}
2065
1320static int ipw_send_scan_request_ext(struct ipw_priv *priv, 2066static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1321 struct ipw_scan_request_ext *request) 2067 struct ipw_scan_request_ext *request)
1322{ 2068{
@@ -1325,20 +2071,8 @@ static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1325 .len = sizeof(*request) 2071 .len = sizeof(*request)
1326 }; 2072 };
1327 2073
1328 if (!priv || !request) { 2074 memcpy(cmd.param, request, sizeof(*request));
1329 IPW_ERROR("Invalid args\n"); 2075 return ipw_send_cmd(priv, &cmd);
1330 return -1;
1331 }
1332
1333 memcpy(&cmd.param, request, sizeof(*request));
1334 if (ipw_send_cmd(priv, &cmd)) {
1335 IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
1336 return -1;
1337 }
1338
1339 queue_delayed_work(priv->workqueue, &priv->scan_check,
1340 IPW_SCAN_CHECK_WATCHDOG);
1341 return 0;
1342} 2076}
1343 2077
1344static int ipw_send_scan_abort(struct ipw_priv *priv) 2078static int ipw_send_scan_abort(struct ipw_priv *priv)
@@ -1353,12 +2087,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv)
1353 return -1; 2087 return -1;
1354 } 2088 }
1355 2089
1356 if (ipw_send_cmd(priv, &cmd)) { 2090 return ipw_send_cmd(priv, &cmd);
1357 IPW_ERROR("failed to send SCAN_ABORT command\n");
1358 return -1;
1359 }
1360
1361 return 0;
1362} 2091}
1363 2092
1364static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) 2093static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
@@ -1370,12 +2099,7 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
1370 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) 2099 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
1371 &cmd.param; 2100 &cmd.param;
1372 calib->beacon_rssi_raw = sens; 2101 calib->beacon_rssi_raw = sens;
1373 if (ipw_send_cmd(priv, &cmd)) { 2102 return ipw_send_cmd(priv, &cmd);
1374 IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
1375 return -1;
1376 }
1377
1378 return 0;
1379} 2103}
1380 2104
1381static int ipw_send_associate(struct ipw_priv *priv, 2105static int ipw_send_associate(struct ipw_priv *priv,
@@ -1386,18 +2110,26 @@ static int ipw_send_associate(struct ipw_priv *priv,
1386 .len = sizeof(*associate) 2110 .len = sizeof(*associate)
1387 }; 2111 };
1388 2112
2113 struct ipw_associate tmp_associate;
2114 memcpy(&tmp_associate, associate, sizeof(*associate));
2115 tmp_associate.policy_support =
2116 cpu_to_le16(tmp_associate.policy_support);
2117 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
2118 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
2119 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
2120 tmp_associate.listen_interval =
2121 cpu_to_le16(tmp_associate.listen_interval);
2122 tmp_associate.beacon_interval =
2123 cpu_to_le16(tmp_associate.beacon_interval);
2124 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
2125
1389 if (!priv || !associate) { 2126 if (!priv || !associate) {
1390 IPW_ERROR("Invalid args\n"); 2127 IPW_ERROR("Invalid args\n");
1391 return -1; 2128 return -1;
1392 } 2129 }
1393 2130
1394 memcpy(&cmd.param, associate, sizeof(*associate)); 2131 memcpy(cmd.param, &tmp_associate, sizeof(*associate));
1395 if (ipw_send_cmd(priv, &cmd)) { 2132 return ipw_send_cmd(priv, &cmd);
1396 IPW_ERROR("failed to send ASSOCIATE command\n");
1397 return -1;
1398 }
1399
1400 return 0;
1401} 2133}
1402 2134
1403static int ipw_send_supported_rates(struct ipw_priv *priv, 2135static int ipw_send_supported_rates(struct ipw_priv *priv,
@@ -1413,13 +2145,8 @@ static int ipw_send_supported_rates(struct ipw_priv *priv,
1413 return -1; 2145 return -1;
1414 } 2146 }
1415 2147
1416 memcpy(&cmd.param, rates, sizeof(*rates)); 2148 memcpy(cmd.param, rates, sizeof(*rates));
1417 if (ipw_send_cmd(priv, &cmd)) { 2149 return ipw_send_cmd(priv, &cmd);
1418 IPW_ERROR("failed to send SUPPORTED_RATES command\n");
1419 return -1;
1420 }
1421
1422 return 0;
1423} 2150}
1424 2151
1425static int ipw_set_random_seed(struct ipw_priv *priv) 2152static int ipw_set_random_seed(struct ipw_priv *priv)
@@ -1436,15 +2163,9 @@ static int ipw_set_random_seed(struct ipw_priv *priv)
1436 2163
1437 get_random_bytes(&cmd.param, sizeof(u32)); 2164 get_random_bytes(&cmd.param, sizeof(u32));
1438 2165
1439 if (ipw_send_cmd(priv, &cmd)) { 2166 return ipw_send_cmd(priv, &cmd);
1440 IPW_ERROR("failed to send SEED_NUMBER command\n");
1441 return -1;
1442 }
1443
1444 return 0;
1445} 2167}
1446 2168
1447#if 0
1448static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) 2169static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1449{ 2170{
1450 struct host_cmd cmd = { 2171 struct host_cmd cmd = {
@@ -1459,14 +2180,8 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1459 2180
1460 *((u32 *) & cmd.param) = phy_off; 2181 *((u32 *) & cmd.param) = phy_off;
1461 2182
1462 if (ipw_send_cmd(priv, &cmd)) { 2183 return ipw_send_cmd(priv, &cmd);
1463 IPW_ERROR("failed to send CARD_DISABLE command\n");
1464 return -1;
1465 }
1466
1467 return 0;
1468} 2184}
1469#endif
1470 2185
1471static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) 2186static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1472{ 2187{
@@ -1480,12 +2195,51 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1480 return -1; 2195 return -1;
1481 } 2196 }
1482 2197
1483 memcpy(&cmd.param, power, sizeof(*power)); 2198 memcpy(cmd.param, power, sizeof(*power));
1484 if (ipw_send_cmd(priv, &cmd)) { 2199 return ipw_send_cmd(priv, &cmd);
1485 IPW_ERROR("failed to send TX_POWER command\n"); 2200}
1486 return -1; 2201
2202static int ipw_set_tx_power(struct ipw_priv *priv)
2203{
2204 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
2205 struct ipw_tx_power tx_power;
2206 s8 max_power;
2207 int i;
2208
2209 memset(&tx_power, 0, sizeof(tx_power));
2210
2211 /* configure device for 'G' band */
2212 tx_power.ieee_mode = IPW_G_MODE;
2213 tx_power.num_channels = geo->bg_channels;
2214 for (i = 0; i < geo->bg_channels; i++) {
2215 max_power = geo->bg[i].max_power;
2216 tx_power.channels_tx_power[i].channel_number =
2217 geo->bg[i].channel;
2218 tx_power.channels_tx_power[i].tx_power = max_power ?
2219 min(max_power, priv->tx_power) : priv->tx_power;
1487 } 2220 }
2221 if (ipw_send_tx_power(priv, &tx_power))
2222 return -EIO;
2223
2224 /* configure device to also handle 'B' band */
2225 tx_power.ieee_mode = IPW_B_MODE;
2226 if (ipw_send_tx_power(priv, &tx_power))
2227 return -EIO;
1488 2228
2229 /* configure device to also handle 'A' band */
2230 if (priv->ieee->abg_true) {
2231 tx_power.ieee_mode = IPW_A_MODE;
2232 tx_power.num_channels = geo->a_channels;
2233 for (i = 0; i < tx_power.num_channels; i++) {
2234 max_power = geo->a[i].max_power;
2235 tx_power.channels_tx_power[i].channel_number =
2236 geo->a[i].channel;
2237 tx_power.channels_tx_power[i].tx_power = max_power ?
2238 min(max_power, priv->tx_power) : priv->tx_power;
2239 }
2240 if (ipw_send_tx_power(priv, &tx_power))
2241 return -EIO;
2242 }
1489 return 0; 2243 return 0;
1490} 2244}
1491 2245
@@ -1504,13 +2258,8 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
1504 return -1; 2258 return -1;
1505 } 2259 }
1506 2260
1507 memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold)); 2261 memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
1508 if (ipw_send_cmd(priv, &cmd)) { 2262 return ipw_send_cmd(priv, &cmd);
1509 IPW_ERROR("failed to send RTS_THRESHOLD command\n");
1510 return -1;
1511 }
1512
1513 return 0;
1514} 2263}
1515 2264
1516static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) 2265static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -1528,13 +2277,8 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
1528 return -1; 2277 return -1;
1529 } 2278 }
1530 2279
1531 memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold)); 2280 memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
1532 if (ipw_send_cmd(priv, &cmd)) { 2281 return ipw_send_cmd(priv, &cmd);
1533 IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
1534 return -1;
1535 }
1536
1537 return 0;
1538} 2282}
1539 2283
1540static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) 2284static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
@@ -1564,12 +2308,27 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
1564 break; 2308 break;
1565 } 2309 }
1566 2310
1567 if (ipw_send_cmd(priv, &cmd)) { 2311 return ipw_send_cmd(priv, &cmd);
1568 IPW_ERROR("failed to send POWER_MODE command\n"); 2312}
2313
2314static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2315{
2316 struct ipw_retry_limit retry_limit = {
2317 .short_retry_limit = slimit,
2318 .long_retry_limit = llimit
2319 };
2320 struct host_cmd cmd = {
2321 .cmd = IPW_CMD_RETRY_LIMIT,
2322 .len = sizeof(retry_limit)
2323 };
2324
2325 if (!priv) {
2326 IPW_ERROR("Invalid args\n");
1569 return -1; 2327 return -1;
1570 } 2328 }
1571 2329
1572 return 0; 2330 memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
2331 return ipw_send_cmd(priv, &cmd);
1573} 2332}
1574 2333
1575/* 2334/*
@@ -1671,8 +2430,7 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
1671/* data's copy of the eeprom data */ 2430/* data's copy of the eeprom data */
1672static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) 2431static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
1673{ 2432{
1674 u8 *ee = (u8 *) priv->eeprom; 2433 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
1675 memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
1676} 2434}
1677 2435
1678/* 2436/*
@@ -1692,7 +2450,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1692 2450
1693 /* read entire contents of eeprom into private buffer */ 2451 /* read entire contents of eeprom into private buffer */
1694 for (i = 0; i < 128; i++) 2452 for (i = 0; i < 128; i++)
1695 eeprom[i] = eeprom_read_u16(priv, (u8) i); 2453 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
1696 2454
1697 /* 2455 /*
1698 If the data looks correct, then copy it to our private 2456 If the data looks correct, then copy it to our private
@@ -1703,7 +2461,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1703 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); 2461 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
1704 2462
1705 /* write the eeprom data to sram */ 2463 /* write the eeprom data to sram */
1706 for (i = 0; i < CX2_EEPROM_IMAGE_SIZE; i++) 2464 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
1707 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]); 2465 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
1708 2466
1709 /* Do not load eeprom data on fatal error or suspend */ 2467 /* Do not load eeprom data on fatal error or suspend */
@@ -1723,14 +2481,14 @@ static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
1723 count >>= 2; 2481 count >>= 2;
1724 if (!count) 2482 if (!count)
1725 return; 2483 return;
1726 _ipw_write32(priv, CX2_AUTOINC_ADDR, start); 2484 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
1727 while (count--) 2485 while (count--)
1728 _ipw_write32(priv, CX2_AUTOINC_DATA, 0); 2486 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
1729} 2487}
1730 2488
1731static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv) 2489static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
1732{ 2490{
1733 ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL, 2491 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
1734 CB_NUMBER_OF_ELEMENTS_SMALL * 2492 CB_NUMBER_OF_ELEMENTS_SMALL *
1735 sizeof(struct command_block)); 2493 sizeof(struct command_block));
1736} 2494}
@@ -1744,7 +2502,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
1744 ipw_fw_dma_reset_command_blocks(priv); 2502 ipw_fw_dma_reset_command_blocks(priv);
1745 2503
1746 /* Write CB base address */ 2504 /* Write CB base address */
1747 ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL); 2505 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
1748 2506
1749 IPW_DEBUG_FW("<< : \n"); 2507 IPW_DEBUG_FW("<< : \n");
1750 return 0; 2508 return 0;
@@ -1758,7 +2516,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
1758 2516
1759 //set the Stop and Abort bit 2517 //set the Stop and Abort bit
1760 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; 2518 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
1761 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2519 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1762 priv->sram_desc.last_cb_index = 0; 2520 priv->sram_desc.last_cb_index = 0;
1763 2521
1764 IPW_DEBUG_FW("<< \n"); 2522 IPW_DEBUG_FW("<< \n");
@@ -1768,7 +2526,7 @@ static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
1768 struct command_block *cb) 2526 struct command_block *cb)
1769{ 2527{
1770 u32 address = 2528 u32 address =
1771 CX2_SHARED_SRAM_DMA_CONTROL + 2529 IPW_SHARED_SRAM_DMA_CONTROL +
1772 (sizeof(struct command_block) * index); 2530 (sizeof(struct command_block) * index);
1773 IPW_DEBUG_FW(">> :\n"); 2531 IPW_DEBUG_FW(">> :\n");
1774 2532
@@ -1792,13 +2550,13 @@ static int ipw_fw_dma_kick(struct ipw_priv *priv)
1792 &priv->sram_desc.cb_list[index]); 2550 &priv->sram_desc.cb_list[index]);
1793 2551
1794 /* Enable the DMA in the CSR register */ 2552 /* Enable the DMA in the CSR register */
1795 ipw_clear_bit(priv, CX2_RESET_REG, 2553 ipw_clear_bit(priv, IPW_RESET_REG,
1796 CX2_RESET_REG_MASTER_DISABLED | 2554 IPW_RESET_REG_MASTER_DISABLED |
1797 CX2_RESET_REG_STOP_MASTER); 2555 IPW_RESET_REG_STOP_MASTER);
1798 2556
1799 /* Set the Start bit. */ 2557 /* Set the Start bit. */
1800 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START; 2558 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
1801 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2559 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1802 2560
1803 IPW_DEBUG_FW("<< :\n"); 2561 IPW_DEBUG_FW("<< :\n");
1804 return 0; 2562 return 0;
@@ -1811,12 +2569,12 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
1811 u32 cb_fields_address = 0; 2569 u32 cb_fields_address = 0;
1812 2570
1813 IPW_DEBUG_FW(">> :\n"); 2571 IPW_DEBUG_FW(">> :\n");
1814 address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2572 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1815 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address); 2573 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
1816 2574
1817 /* Read the DMA Controlor register */ 2575 /* Read the DMA Controlor register */
1818 register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL); 2576 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
1819 IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n", register_value); 2577 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
1820 2578
1821 /* Print the CB values */ 2579 /* Print the CB values */
1822 cb_fields_address = address; 2580 cb_fields_address = address;
@@ -1845,9 +2603,9 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
1845 u32 current_cb_index = 0; 2603 u32 current_cb_index = 0;
1846 2604
1847 IPW_DEBUG_FW("<< :\n"); 2605 IPW_DEBUG_FW("<< :\n");
1848 current_cb_address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2606 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1849 2607
1850 current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL) / 2608 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
1851 sizeof(struct command_block); 2609 sizeof(struct command_block);
1852 2610
1853 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", 2611 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
@@ -1976,8 +2734,8 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
1976 ipw_fw_dma_abort(priv); 2734 ipw_fw_dma_abort(priv);
1977 2735
1978 /*Disable the DMA in the CSR register */ 2736 /*Disable the DMA in the CSR register */
1979 ipw_set_bit(priv, CX2_RESET_REG, 2737 ipw_set_bit(priv, IPW_RESET_REG,
1980 CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); 2738 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
1981 2739
1982 IPW_DEBUG_FW("<< dmaWaitSync \n"); 2740 IPW_DEBUG_FW("<< dmaWaitSync \n");
1983 return 0; 2741 return 0;
@@ -1987,6 +2745,9 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1987{ 2745{
1988 struct list_head *element, *safe; 2746 struct list_head *element, *safe;
1989 struct ieee80211_network *network = NULL; 2747 struct ieee80211_network *network = NULL;
2748 unsigned long flags;
2749
2750 spin_lock_irqsave(&priv->ieee->lock, flags);
1990 list_for_each_safe(element, safe, &priv->ieee->network_list) { 2751 list_for_each_safe(element, safe, &priv->ieee->network_list) {
1991 network = list_entry(element, struct ieee80211_network, list); 2752 network = list_entry(element, struct ieee80211_network, list);
1992 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 2753 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
@@ -1995,6 +2756,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1995 &priv->ieee->network_free_list); 2756 &priv->ieee->network_free_list);
1996 } 2757 }
1997 } 2758 }
2759 spin_unlock_irqrestore(&priv->ieee->lock, flags);
1998} 2760}
1999 2761
2000/** 2762/**
@@ -2037,10 +2799,10 @@ static int ipw_stop_master(struct ipw_priv *priv)
2037 2799
2038 IPW_DEBUG_TRACE(">> \n"); 2800 IPW_DEBUG_TRACE(">> \n");
2039 /* stop master. typical delay - 0 */ 2801 /* stop master. typical delay - 0 */
2040 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 2802 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2041 2803
2042 rc = ipw_poll_bit(priv, CX2_RESET_REG, 2804 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2043 CX2_RESET_REG_MASTER_DISABLED, 100); 2805 IPW_RESET_REG_MASTER_DISABLED, 100);
2044 if (rc < 0) { 2806 if (rc < 0) {
2045 IPW_ERROR("stop master failed in 10ms\n"); 2807 IPW_ERROR("stop master failed in 10ms\n");
2046 return -1; 2808 return -1;
@@ -2056,7 +2818,7 @@ static void ipw_arc_release(struct ipw_priv *priv)
2056 IPW_DEBUG_TRACE(">> \n"); 2818 IPW_DEBUG_TRACE(">> \n");
2057 mdelay(5); 2819 mdelay(5);
2058 2820
2059 ipw_clear_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 2821 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2060 2822
2061 /* no one knows timing, for safety add some delay */ 2823 /* no one knows timing, for safety add some delay */
2062 mdelay(5); 2824 mdelay(5);
@@ -2073,13 +2835,12 @@ struct fw_chunk {
2073}; 2835};
2074 2836
2075#define IPW_FW_MAJOR_VERSION 2 2837#define IPW_FW_MAJOR_VERSION 2
2076#define IPW_FW_MINOR_VERSION 2 2838#define IPW_FW_MINOR_VERSION 4
2077 2839
2078#define IPW_FW_MINOR(x) ((x & 0xff) >> 8) 2840#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2079#define IPW_FW_MAJOR(x) (x & 0xff) 2841#define IPW_FW_MAJOR(x) (x & 0xff)
2080 2842
2081#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \ 2843#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
2082 IPW_FW_MAJOR_VERSION)
2083 2844
2084#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \ 2845#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2085"." __stringify(IPW_FW_MINOR_VERSION) "-" 2846"." __stringify(IPW_FW_MINOR_VERSION) "-"
@@ -2107,8 +2868,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2107 2868
2108// spin_lock_irqsave(&priv->lock, flags); 2869// spin_lock_irqsave(&priv->lock, flags);
2109 2870
2110 for (addr = CX2_SHARED_LOWER_BOUND; 2871 for (addr = IPW_SHARED_LOWER_BOUND;
2111 addr < CX2_REGISTER_DOMAIN1_END; addr += 4) { 2872 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
2112 ipw_write32(priv, addr, 0); 2873 ipw_write32(priv, addr, 0);
2113 } 2874 }
2114 2875
@@ -2117,16 +2878,16 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2117 /* destroy DMA queues */ 2878 /* destroy DMA queues */
2118 /* reset sequence */ 2879 /* reset sequence */
2119 2880
2120 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_ON); 2881 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
2121 ipw_arc_release(priv); 2882 ipw_arc_release(priv);
2122 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF); 2883 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
2123 mdelay(1); 2884 mdelay(1);
2124 2885
2125 /* reset PHY */ 2886 /* reset PHY */
2126 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN); 2887 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
2127 mdelay(1); 2888 mdelay(1);
2128 2889
2129 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0); 2890 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
2130 mdelay(1); 2891 mdelay(1);
2131 2892
2132 /* enable ucode store */ 2893 /* enable ucode store */
@@ -2144,18 +2905,19 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2144 */ 2905 */
2145 /* load new ipw uCode */ 2906 /* load new ipw uCode */
2146 for (i = 0; i < len / 2; i++) 2907 for (i = 0; i < len / 2; i++)
2147 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); 2908 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
2909 cpu_to_le16(image[i]));
2148 2910
2149 /* enable DINO */ 2911 /* enable DINO */
2150 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2912 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2151 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM); 2913 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
2152 2914
2153 /* this is where the igx / win driver deveates from the VAP driver. */ 2915 /* this is where the igx / win driver deveates from the VAP driver. */
2154 2916
2155 /* wait for alive response */ 2917 /* wait for alive response */
2156 for (i = 0; i < 100; i++) { 2918 for (i = 0; i < 100; i++) {
2157 /* poll for incoming data */ 2919 /* poll for incoming data */
2158 cr = ipw_read_reg8(priv, CX2_BASEBAND_CONTROL_STATUS); 2920 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
2159 if (cr & DINO_RXFIFO_DATA) 2921 if (cr & DINO_RXFIFO_DATA)
2160 break; 2922 break;
2161 mdelay(1); 2923 mdelay(1);
@@ -2167,7 +2929,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2167 2929
2168 for (i = 0; i < ARRAY_SIZE(response_buffer); i++) 2930 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
2169 response_buffer[i] = 2931 response_buffer[i] =
2170 ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ); 2932 le32_to_cpu(ipw_read_reg32(priv,
2933 IPW_BASEBAND_RX_FIFO_READ));
2171 memcpy(&priv->dino_alive, response_buffer, 2934 memcpy(&priv->dino_alive, response_buffer,
2172 sizeof(priv->dino_alive)); 2935 sizeof(priv->dino_alive));
2173 if (priv->dino_alive.alive_command == 1 2936 if (priv->dino_alive.alive_command == 1
@@ -2196,7 +2959,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2196 2959
2197 /* disable DINO, otherwise for some reason 2960 /* disable DINO, otherwise for some reason
2198 firmware have problem getting alive resp. */ 2961 firmware have problem getting alive resp. */
2199 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2962 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2200 2963
2201// spin_unlock_irqrestore(&priv->lock, flags); 2964// spin_unlock_irqrestore(&priv->lock, flags);
2202 2965
@@ -2236,13 +2999,14 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
2236 * offeset*/ 2999 * offeset*/
2237 /* Dma loading */ 3000 /* Dma loading */
2238 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset, 3001 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
2239 chunk->address, chunk->length); 3002 le32_to_cpu(chunk->address),
3003 le32_to_cpu(chunk->length));
2240 if (rc) { 3004 if (rc) {
2241 IPW_DEBUG_INFO("dmaAddBuffer Failed\n"); 3005 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2242 goto out; 3006 goto out;
2243 } 3007 }
2244 3008
2245 offset += chunk->length; 3009 offset += le32_to_cpu(chunk->length);
2246 } while (offset < len); 3010 } while (offset < len);
2247 3011
2248 /* Run the DMA and wait for the answer */ 3012 /* Run the DMA and wait for the answer */
@@ -2268,16 +3032,16 @@ static int ipw_stop_nic(struct ipw_priv *priv)
2268 int rc = 0; 3032 int rc = 0;
2269 3033
2270 /* stop */ 3034 /* stop */
2271 ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 3035 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2272 3036
2273 rc = ipw_poll_bit(priv, CX2_RESET_REG, 3037 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2274 CX2_RESET_REG_MASTER_DISABLED, 500); 3038 IPW_RESET_REG_MASTER_DISABLED, 500);
2275 if (rc < 0) { 3039 if (rc < 0) {
2276 IPW_ERROR("wait for reg master disabled failed\n"); 3040 IPW_ERROR("wait for reg master disabled failed\n");
2277 return rc; 3041 return rc;
2278 } 3042 }
2279 3043
2280 ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 3044 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2281 3045
2282 return rc; 3046 return rc;
2283} 3047}
@@ -2287,14 +3051,14 @@ static void ipw_start_nic(struct ipw_priv *priv)
2287 IPW_DEBUG_TRACE(">>\n"); 3051 IPW_DEBUG_TRACE(">>\n");
2288 3052
2289 /* prvHwStartNic release ARC */ 3053 /* prvHwStartNic release ARC */
2290 ipw_clear_bit(priv, CX2_RESET_REG, 3054 ipw_clear_bit(priv, IPW_RESET_REG,
2291 CX2_RESET_REG_MASTER_DISABLED | 3055 IPW_RESET_REG_MASTER_DISABLED |
2292 CX2_RESET_REG_STOP_MASTER | 3056 IPW_RESET_REG_STOP_MASTER |
2293 CBD_RESET_REG_PRINCETON_RESET); 3057 CBD_RESET_REG_PRINCETON_RESET);
2294 3058
2295 /* enable power management */ 3059 /* enable power management */
2296 ipw_set_bit(priv, CX2_GP_CNTRL_RW, 3060 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
2297 CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY); 3061 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
2298 3062
2299 IPW_DEBUG_TRACE("<<\n"); 3063 IPW_DEBUG_TRACE("<<\n");
2300} 3064}
@@ -2307,25 +3071,25 @@ static int ipw_init_nic(struct ipw_priv *priv)
2307 /* reset */ 3071 /* reset */
2308 /*prvHwInitNic */ 3072 /*prvHwInitNic */
2309 /* set "initialization complete" bit to move adapter to D0 state */ 3073 /* set "initialization complete" bit to move adapter to D0 state */
2310 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3074 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2311 3075
2312 /* low-level PLL activation */ 3076 /* low-level PLL activation */
2313 ipw_write32(priv, CX2_READ_INT_REGISTER, 3077 ipw_write32(priv, IPW_READ_INT_REGISTER,
2314 CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER); 3078 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
2315 3079
2316 /* wait for clock stabilization */ 3080 /* wait for clock stabilization */
2317 rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, 3081 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
2318 CX2_GP_CNTRL_BIT_CLOCK_READY, 250); 3082 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
2319 if (rc < 0) 3083 if (rc < 0)
2320 IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); 3084 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
2321 3085
2322 /* assert SW reset */ 3086 /* assert SW reset */
2323 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_SW_RESET); 3087 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
2324 3088
2325 udelay(10); 3089 udelay(10);
2326 3090
2327 /* set "initialization complete" bit to move adapter to D0 state */ 3091 /* set "initialization complete" bit to move adapter to D0 state */
2328 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3092 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2329 3093
2330 IPW_DEBUG_TRACE(">>\n"); 3094 IPW_DEBUG_TRACE(">>\n");
2331 return 0; 3095 return 0;
@@ -2337,14 +3101,19 @@ static int ipw_init_nic(struct ipw_priv *priv)
2337static int ipw_reset_nic(struct ipw_priv *priv) 3101static int ipw_reset_nic(struct ipw_priv *priv)
2338{ 3102{
2339 int rc = 0; 3103 int rc = 0;
3104 unsigned long flags;
2340 3105
2341 IPW_DEBUG_TRACE(">>\n"); 3106 IPW_DEBUG_TRACE(">>\n");
2342 3107
2343 rc = ipw_init_nic(priv); 3108 rc = ipw_init_nic(priv);
2344 3109
3110 spin_lock_irqsave(&priv->lock, flags);
2345 /* Clear the 'host command active' bit... */ 3111 /* Clear the 'host command active' bit... */
2346 priv->status &= ~STATUS_HCMD_ACTIVE; 3112 priv->status &= ~STATUS_HCMD_ACTIVE;
2347 wake_up_interruptible(&priv->wait_command_queue); 3113 wake_up_interruptible(&priv->wait_command_queue);
3114 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3115 wake_up_interruptible(&priv->wait_state);
3116 spin_unlock_irqrestore(&priv->lock, flags);
2348 3117
2349 IPW_DEBUG_TRACE("<<\n"); 3118 IPW_DEBUG_TRACE("<<\n");
2350 return rc; 3119 return rc;
@@ -2364,22 +3133,23 @@ static int ipw_get_fw(struct ipw_priv *priv,
2364 } 3133 }
2365 3134
2366 header = (struct fw_header *)(*fw)->data; 3135 header = (struct fw_header *)(*fw)->data;
2367 if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) { 3136 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
2368 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", 3137 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2369 name, 3138 name,
2370 IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION); 3139 IPW_FW_MAJOR(le32_to_cpu(header->version)),
3140 IPW_FW_MAJOR_VERSION);
2371 return -EINVAL; 3141 return -EINVAL;
2372 } 3142 }
2373 3143
2374 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", 3144 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
2375 name, 3145 name,
2376 IPW_FW_MAJOR(header->version), 3146 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2377 IPW_FW_MINOR(header->version), 3147 IPW_FW_MINOR(le32_to_cpu(header->version)),
2378 (*fw)->size - sizeof(struct fw_header)); 3148 (*fw)->size - sizeof(struct fw_header));
2379 return 0; 3149 return 0;
2380} 3150}
2381 3151
2382#define CX2_RX_BUF_SIZE (3000) 3152#define IPW_RX_BUF_SIZE (3000)
2383 3153
2384static inline void ipw_rx_queue_reset(struct ipw_priv *priv, 3154static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2385 struct ipw_rx_queue *rxq) 3155 struct ipw_rx_queue *rxq)
@@ -2398,8 +3168,9 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2398 * to an SKB, so we need to unmap and free potential storage */ 3168 * to an SKB, so we need to unmap and free potential storage */
2399 if (rxq->pool[i].skb != NULL) { 3169 if (rxq->pool[i].skb != NULL) {
2400 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 3170 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
2401 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 3171 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
2402 dev_kfree_skb(rxq->pool[i].skb); 3172 dev_kfree_skb(rxq->pool[i].skb);
3173 rxq->pool[i].skb = NULL;
2403 } 3174 }
2404 list_add_tail(&rxq->pool[i].list, &rxq->rx_used); 3175 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
2405 } 3176 }
@@ -2417,6 +3188,19 @@ static int fw_loaded = 0;
2417static const struct firmware *bootfw = NULL; 3188static const struct firmware *bootfw = NULL;
2418static const struct firmware *firmware = NULL; 3189static const struct firmware *firmware = NULL;
2419static const struct firmware *ucode = NULL; 3190static const struct firmware *ucode = NULL;
3191
3192static void free_firmware(void)
3193{
3194 if (fw_loaded) {
3195 release_firmware(bootfw);
3196 release_firmware(ucode);
3197 release_firmware(firmware);
3198 bootfw = ucode = firmware = NULL;
3199 fw_loaded = 0;
3200 }
3201}
3202#else
3203#define free_firmware() do {} while (0)
2420#endif 3204#endif
2421 3205
2422static int ipw_load(struct ipw_priv *priv) 3206static int ipw_load(struct ipw_priv *priv)
@@ -2445,10 +3229,10 @@ static int ipw_load(struct ipw_priv *priv)
2445 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); 3229 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
2446 break; 3230 break;
2447 3231
2448#ifdef CONFIG_IPW_PROMISC 3232#ifdef CONFIG_IPW2200_MONITOR
2449 case IW_MODE_MONITOR: 3233 case IW_MODE_MONITOR:
2450 rc = ipw_get_fw(priv, &ucode, 3234 rc = ipw_get_fw(priv, &ucode,
2451 IPW_FW_NAME("ibss_ucode")); 3235 IPW_FW_NAME("sniffer_ucode"));
2452 if (rc) 3236 if (rc)
2453 goto error; 3237 goto error;
2454 3238
@@ -2487,11 +3271,11 @@ static int ipw_load(struct ipw_priv *priv)
2487 3271
2488 retry: 3272 retry:
2489 /* Ensure interrupts are disabled */ 3273 /* Ensure interrupts are disabled */
2490 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3274 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
2491 priv->status &= ~STATUS_INT_ENABLED; 3275 priv->status &= ~STATUS_INT_ENABLED;
2492 3276
2493 /* ack pending interrupts */ 3277 /* ack pending interrupts */
2494 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3278 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2495 3279
2496 ipw_stop_nic(priv); 3280 ipw_stop_nic(priv);
2497 3281
@@ -2501,14 +3285,14 @@ static int ipw_load(struct ipw_priv *priv)
2501 goto error; 3285 goto error;
2502 } 3286 }
2503 3287
2504 ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND, 3288 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
2505 CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND); 3289 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
2506 3290
2507 /* DMA the initial boot firmware into the device */ 3291 /* DMA the initial boot firmware into the device */
2508 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), 3292 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
2509 bootfw->size - sizeof(struct fw_header)); 3293 bootfw->size - sizeof(struct fw_header));
2510 if (rc < 0) { 3294 if (rc < 0) {
2511 IPW_ERROR("Unable to load boot firmware\n"); 3295 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
2512 goto error; 3296 goto error;
2513 } 3297 }
2514 3298
@@ -2516,8 +3300,8 @@ static int ipw_load(struct ipw_priv *priv)
2516 ipw_start_nic(priv); 3300 ipw_start_nic(priv);
2517 3301
2518 /* wait for the device to finish it's initial startup sequence */ 3302 /* wait for the device to finish it's initial startup sequence */
2519 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3303 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2520 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3304 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2521 if (rc < 0) { 3305 if (rc < 0) {
2522 IPW_ERROR("device failed to boot initial fw image\n"); 3306 IPW_ERROR("device failed to boot initial fw image\n");
2523 goto error; 3307 goto error;
@@ -2525,13 +3309,13 @@ static int ipw_load(struct ipw_priv *priv)
2525 IPW_DEBUG_INFO("initial device response after %dms\n", rc); 3309 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
2526 3310
2527 /* ack fw init done interrupt */ 3311 /* ack fw init done interrupt */
2528 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3312 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2529 3313
2530 /* DMA the ucode into the device */ 3314 /* DMA the ucode into the device */
2531 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), 3315 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
2532 ucode->size - sizeof(struct fw_header)); 3316 ucode->size - sizeof(struct fw_header));
2533 if (rc < 0) { 3317 if (rc < 0) {
2534 IPW_ERROR("Unable to load ucode\n"); 3318 IPW_ERROR("Unable to load ucode: %d\n", rc);
2535 goto error; 3319 goto error;
2536 } 3320 }
2537 3321
@@ -2543,7 +3327,7 @@ static int ipw_load(struct ipw_priv *priv)
2543 sizeof(struct fw_header), 3327 sizeof(struct fw_header),
2544 firmware->size - sizeof(struct fw_header)); 3328 firmware->size - sizeof(struct fw_header));
2545 if (rc < 0) { 3329 if (rc < 0) {
2546 IPW_ERROR("Unable to load firmware\n"); 3330 IPW_ERROR("Unable to load firmware: %d\n", rc);
2547 goto error; 3331 goto error;
2548 } 3332 }
2549 3333
@@ -2556,12 +3340,14 @@ static int ipw_load(struct ipw_priv *priv)
2556 } 3340 }
2557 3341
2558 /* Ensure interrupts are disabled */ 3342 /* Ensure interrupts are disabled */
2559 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3343 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3344 /* ack pending interrupts */
3345 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2560 3346
2561 /* kick start the device */ 3347 /* kick start the device */
2562 ipw_start_nic(priv); 3348 ipw_start_nic(priv);
2563 3349
2564 if (ipw_read32(priv, CX2_INTA_RW) & CX2_INTA_BIT_PARITY_ERROR) { 3350 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
2565 if (retries > 0) { 3351 if (retries > 0) {
2566 IPW_WARNING("Parity error. Retrying init.\n"); 3352 IPW_WARNING("Parity error. Retrying init.\n");
2567 retries--; 3353 retries--;
@@ -2574,8 +3360,8 @@ static int ipw_load(struct ipw_priv *priv)
2574 } 3360 }
2575 3361
2576 /* wait for the device */ 3362 /* wait for the device */
2577 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3363 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2578 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3364 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2579 if (rc < 0) { 3365 if (rc < 0) {
2580 IPW_ERROR("device failed to start after 500ms\n"); 3366 IPW_ERROR("device failed to start after 500ms\n");
2581 goto error; 3367 goto error;
@@ -2583,7 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
2583 IPW_DEBUG_INFO("device response after %dms\n", rc); 3369 IPW_DEBUG_INFO("device response after %dms\n", rc);
2584 3370
2585 /* ack fw init done interrupt */ 3371 /* ack fw init done interrupt */
2586 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3372 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2587 3373
2588 /* read eeprom data and initialize the eeprom region of sram */ 3374 /* read eeprom data and initialize the eeprom region of sram */
2589 priv->eeprom_delay = 1; 3375 priv->eeprom_delay = 1;
@@ -2595,10 +3381,10 @@ static int ipw_load(struct ipw_priv *priv)
2595 /* Ensure our queue has valid packets */ 3381 /* Ensure our queue has valid packets */
2596 ipw_rx_queue_replenish(priv); 3382 ipw_rx_queue_replenish(priv);
2597 3383
2598 ipw_write32(priv, CX2_RX_READ_INDEX, priv->rxq->read); 3384 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
2599 3385
2600 /* ack pending interrupts */ 3386 /* ack pending interrupts */
2601 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3387 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2602 3388
2603#ifndef CONFIG_PM 3389#ifndef CONFIG_PM
2604 release_firmware(bootfw); 3390 release_firmware(bootfw);
@@ -2755,16 +3541,18 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
2755 return; 3541 return;
2756 3542
2757 /* sanity check */ 3543 /* sanity check */
2758 if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) { 3544 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
2759 IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks); 3545 IPW_ERROR("Too many chunks: %i\n",
3546 le32_to_cpu(bd->u.data.num_chunks));
2760 /** @todo issue fatal error, it is quite serious situation */ 3547 /** @todo issue fatal error, it is quite serious situation */
2761 return; 3548 return;
2762 } 3549 }
2763 3550
2764 /* unmap chunks if any */ 3551 /* unmap chunks if any */
2765 for (i = 0; i < bd->u.data.num_chunks; i++) { 3552 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
2766 pci_unmap_single(dev, bd->u.data.chunk_ptr[i], 3553 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
2767 bd->u.data.chunk_len[i], PCI_DMA_TODEVICE); 3554 le16_to_cpu(bd->u.data.chunk_len[i]),
3555 PCI_DMA_TODEVICE);
2768 if (txq->txb[txq->q.last_used]) { 3556 if (txq->txb[txq->q.last_used]) {
2769 ieee80211_txb_free(txq->txb[txq->q.last_used]); 3557 ieee80211_txb_free(txq->txb[txq->q.last_used]);
2770 txq->txb[txq->q.last_used] = NULL; 3558 txq->txb[txq->q.last_used] = NULL;
@@ -2821,21 +3609,6 @@ static void ipw_tx_queue_free(struct ipw_priv *priv)
2821 ipw_queue_tx_free(priv, &priv->txq[3]); 3609 ipw_queue_tx_free(priv, &priv->txq[3]);
2822} 3610}
2823 3611
2824static void inline __maybe_wake_tx(struct ipw_priv *priv)
2825{
2826 if (netif_running(priv->net_dev)) {
2827 switch (priv->port_type) {
2828 case DCR_TYPE_MU_BSS:
2829 case DCR_TYPE_MU_IBSS:
2830 if (!(priv->status & STATUS_ASSOCIATED)) {
2831 return;
2832 }
2833 }
2834 netif_wake_queue(priv->net_dev);
2835 }
2836
2837}
2838
2839static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid) 3612static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
2840{ 3613{
2841 /* First 3 bytes are manufacturer */ 3614 /* First 3 bytes are manufacturer */
@@ -2898,7 +3671,13 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2898{ 3671{
2899 int err; 3672 int err;
2900 3673
2901 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) { 3674 if (priv->status & STATUS_ASSOCIATING) {
3675 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
3676 queue_work(priv->workqueue, &priv->disassociate);
3677 return;
3678 }
3679
3680 if (!(priv->status & STATUS_ASSOCIATED)) {
2902 IPW_DEBUG_ASSOC("Disassociating while not associated.\n"); 3681 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
2903 return; 3682 return;
2904 } 3683 }
@@ -2915,6 +3694,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2915 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET; 3694 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
2916 else 3695 else
2917 priv->assoc_request.assoc_type = HC_DISASSOCIATE; 3696 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3697
2918 err = ipw_send_associate(priv, &priv->assoc_request); 3698 err = ipw_send_associate(priv, &priv->assoc_request);
2919 if (err) { 3699 if (err) {
2920 IPW_DEBUG_HC("Attempt to send [dis]associate command " 3700 IPW_DEBUG_HC("Attempt to send [dis]associate command "
@@ -2924,20 +3704,27 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2924 3704
2925} 3705}
2926 3706
2927static void ipw_disassociate(void *data) 3707static int ipw_disassociate(void *data)
2928{ 3708{
3709 struct ipw_priv *priv = data;
3710 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3711 return 0;
2929 ipw_send_disassociate(data, 0); 3712 ipw_send_disassociate(data, 0);
3713 return 1;
2930} 3714}
2931 3715
2932static void notify_wx_assoc_event(struct ipw_priv *priv) 3716static void ipw_bg_disassociate(void *data)
2933{ 3717{
2934 union iwreq_data wrqu; 3718 struct ipw_priv *priv = data;
2935 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3719 down(&priv->sem);
2936 if (priv->status & STATUS_ASSOCIATED) 3720 ipw_disassociate(data);
2937 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 3721 up(&priv->sem);
2938 else 3722}
2939 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 3723
2940 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); 3724static void ipw_system_config(void *data)
3725{
3726 struct ipw_priv *priv = data;
3727 ipw_send_system_config(priv, &priv->sys_config);
2941} 3728}
2942 3729
2943struct ipw_status_code { 3730struct ipw_status_code {
@@ -2997,7 +3784,7 @@ static const char *ipw_get_status_code(u16 status)
2997{ 3784{
2998 int i; 3785 int i;
2999 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++) 3786 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
3000 if (ipw_status_codes[i].status == status) 3787 if (ipw_status_codes[i].status == (status & 0xff))
3001 return ipw_status_codes[i].reason; 3788 return ipw_status_codes[i].reason;
3002 return "Unknown status value."; 3789 return "Unknown status value.";
3003} 3790}
@@ -3076,18 +3863,30 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3076 while (i && !(mask & i)) 3863 while (i && !(mask & i))
3077 i >>= 1; 3864 i >>= 1;
3078 switch (i) { 3865 switch (i) {
3079 case IEEE80211_CCK_RATE_1MB_MASK: return 1000000; 3866 case IEEE80211_CCK_RATE_1MB_MASK:
3080 case IEEE80211_CCK_RATE_2MB_MASK: return 2000000; 3867 return 1000000;
3081 case IEEE80211_CCK_RATE_5MB_MASK: return 5500000; 3868 case IEEE80211_CCK_RATE_2MB_MASK:
3082 case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000; 3869 return 2000000;
3083 case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000; 3870 case IEEE80211_CCK_RATE_5MB_MASK:
3084 case IEEE80211_CCK_RATE_11MB_MASK: return 11000000; 3871 return 5500000;
3085 case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000; 3872 case IEEE80211_OFDM_RATE_6MB_MASK:
3086 case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000; 3873 return 6000000;
3087 case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000; 3874 case IEEE80211_OFDM_RATE_9MB_MASK:
3088 case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000; 3875 return 9000000;
3089 case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000; 3876 case IEEE80211_CCK_RATE_11MB_MASK:
3090 case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; 3877 return 11000000;
3878 case IEEE80211_OFDM_RATE_12MB_MASK:
3879 return 12000000;
3880 case IEEE80211_OFDM_RATE_18MB_MASK:
3881 return 18000000;
3882 case IEEE80211_OFDM_RATE_24MB_MASK:
3883 return 24000000;
3884 case IEEE80211_OFDM_RATE_36MB_MASK:
3885 return 36000000;
3886 case IEEE80211_OFDM_RATE_48MB_MASK:
3887 return 48000000;
3888 case IEEE80211_OFDM_RATE_54MB_MASK:
3889 return 54000000;
3091 } 3890 }
3092 3891
3093 if (priv->ieee->mode == IEEE_B) 3892 if (priv->ieee->mode == IEEE_B)
@@ -3115,25 +3914,35 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv)
3115 return ipw_get_max_rate(priv); 3914 return ipw_get_max_rate(priv);
3116 3915
3117 switch (rate) { 3916 switch (rate) {
3118 case IPW_TX_RATE_1MB: return 1000000; 3917 case IPW_TX_RATE_1MB:
3119 case IPW_TX_RATE_2MB: return 2000000; 3918 return 1000000;
3120 case IPW_TX_RATE_5MB: return 5500000; 3919 case IPW_TX_RATE_2MB:
3121 case IPW_TX_RATE_6MB: return 6000000; 3920 return 2000000;
3122 case IPW_TX_RATE_9MB: return 9000000; 3921 case IPW_TX_RATE_5MB:
3123 case IPW_TX_RATE_11MB: return 11000000; 3922 return 5500000;
3124 case IPW_TX_RATE_12MB: return 12000000; 3923 case IPW_TX_RATE_6MB:
3125 case IPW_TX_RATE_18MB: return 18000000; 3924 return 6000000;
3126 case IPW_TX_RATE_24MB: return 24000000; 3925 case IPW_TX_RATE_9MB:
3127 case IPW_TX_RATE_36MB: return 36000000; 3926 return 9000000;
3128 case IPW_TX_RATE_48MB: return 48000000; 3927 case IPW_TX_RATE_11MB:
3129 case IPW_TX_RATE_54MB: return 54000000; 3928 return 11000000;
3929 case IPW_TX_RATE_12MB:
3930 return 12000000;
3931 case IPW_TX_RATE_18MB:
3932 return 18000000;
3933 case IPW_TX_RATE_24MB:
3934 return 24000000;
3935 case IPW_TX_RATE_36MB:
3936 return 36000000;
3937 case IPW_TX_RATE_48MB:
3938 return 48000000;
3939 case IPW_TX_RATE_54MB:
3940 return 54000000;
3130 } 3941 }
3131 3942
3132 return 0; 3943 return 0;
3133} 3944}
3134 3945
3135#define PERFECT_RSSI (-50)
3136#define WORST_RSSI (-85)
3137#define IPW_STATS_INTERVAL (2 * HZ) 3946#define IPW_STATS_INTERVAL (2 * HZ)
3138static void ipw_gather_stats(struct ipw_priv *priv) 3947static void ipw_gather_stats(struct ipw_priv *priv)
3139{ 3948{
@@ -3145,6 +3954,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3145 s16 rssi; 3954 s16 rssi;
3146 u32 beacon_quality, signal_quality, tx_quality, rx_quality, 3955 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
3147 rate_quality; 3956 rate_quality;
3957 u32 max_rate;
3148 3958
3149 if (!(priv->status & STATUS_ASSOCIATED)) { 3959 if (!(priv->status & STATUS_ASSOCIATED)) {
3150 priv->quality = 0; 3960 priv->quality = 0;
@@ -3201,7 +4011,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3201 beacon_quality, missed_beacons_percent); 4011 beacon_quality, missed_beacons_percent);
3202 4012
3203 priv->last_rate = ipw_get_current_rate(priv); 4013 priv->last_rate = ipw_get_current_rate(priv);
3204 rate_quality = priv->last_rate * 40 / priv->last_rate + 60; 4014 max_rate = ipw_get_max_rate(priv);
4015 rate_quality = priv->last_rate * 40 / max_rate + 60;
3205 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", 4016 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3206 rate_quality, priv->last_rate / 1000000); 4017 rate_quality, priv->last_rate / 1000000);
3207 4018
@@ -3222,13 +4033,20 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3222 tx_quality, tx_failures_delta, tx_packets_delta); 4033 tx_quality, tx_failures_delta, tx_packets_delta);
3223 4034
3224 rssi = average_value(&priv->average_rssi); 4035 rssi = average_value(&priv->average_rssi);
3225 if (rssi > PERFECT_RSSI) 4036 signal_quality =
4037 (100 *
4038 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4039 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4040 (priv->ieee->perfect_rssi - rssi) *
4041 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4042 62 * (priv->ieee->perfect_rssi - rssi))) /
4043 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4044 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4045 if (signal_quality > 100)
3226 signal_quality = 100; 4046 signal_quality = 100;
3227 else if (rssi < WORST_RSSI) 4047 else if (signal_quality < 1)
3228 signal_quality = 0; 4048 signal_quality = 0;
3229 else 4049
3230 signal_quality = (rssi - WORST_RSSI) * 100 /
3231 (PERFECT_RSSI - WORST_RSSI);
3232 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", 4050 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3233 signal_quality, rssi); 4051 signal_quality, rssi);
3234 4052
@@ -3257,6 +4075,85 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3257 IPW_STATS_INTERVAL); 4075 IPW_STATS_INTERVAL);
3258} 4076}
3259 4077
4078static void ipw_bg_gather_stats(void *data)
4079{
4080 struct ipw_priv *priv = data;
4081 down(&priv->sem);
4082 ipw_gather_stats(data);
4083 up(&priv->sem);
4084}
4085
4086/* Missed beacon behavior:
4087 * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
4088 * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
4089 * Above disassociate threshold, give up and stop scanning.
4090 * Roaming is disabled if disassociate_threshold <= roaming_threshold */
4091static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
4092 int missed_count)
4093{
4094 priv->notif_missed_beacons = missed_count;
4095
4096 if (missed_count > priv->disassociate_threshold &&
4097 priv->status & STATUS_ASSOCIATED) {
4098 /* If associated and we've hit the missed
4099 * beacon threshold, disassociate, turn
4100 * off roaming, and abort any active scans */
4101 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4102 IPW_DL_STATE | IPW_DL_ASSOC,
4103 "Missed beacon: %d - disassociate\n", missed_count);
4104 priv->status &= ~STATUS_ROAMING;
4105 if (priv->status & STATUS_SCANNING) {
4106 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4107 IPW_DL_STATE,
4108 "Aborting scan with missed beacon.\n");
4109 queue_work(priv->workqueue, &priv->abort_scan);
4110 }
4111
4112 queue_work(priv->workqueue, &priv->disassociate);
4113 return;
4114 }
4115
4116 if (priv->status & STATUS_ROAMING) {
4117 /* If we are currently roaming, then just
4118 * print a debug statement... */
4119 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4120 "Missed beacon: %d - roam in progress\n",
4121 missed_count);
4122 return;
4123 }
4124
4125 if (missed_count > priv->roaming_threshold &&
4126 missed_count <= priv->disassociate_threshold) {
4127 /* If we are not already roaming, set the ROAM
4128 * bit in the status and kick off a scan.
4129 * This can happen several times before we reach
4130 * disassociate_threshold. */
4131 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4132 "Missed beacon: %d - initiate "
4133 "roaming\n", missed_count);
4134 if (!(priv->status & STATUS_ROAMING)) {
4135 priv->status |= STATUS_ROAMING;
4136 if (!(priv->status & STATUS_SCANNING))
4137 queue_work(priv->workqueue,
4138 &priv->request_scan);
4139 }
4140 return;
4141 }
4142
4143 if (priv->status & STATUS_SCANNING) {
4144 /* Stop scan to keep fw from getting
4145 * stuck (only if we aren't roaming --
4146 * otherwise we'll never scan more than 2 or 3
4147 * channels..) */
4148 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4149 "Aborting scan with missed beacon.\n");
4150 queue_work(priv->workqueue, &priv->abort_scan);
4151 }
4152
4153 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4154
4155}
4156
3260/** 4157/**
3261 * Handle host notification packet. 4158 * Handle host notification packet.
3262 * Called from interrupt routine 4159 * Called from interrupt routine
@@ -3264,6 +4161,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3264static inline void ipw_rx_notification(struct ipw_priv *priv, 4161static inline void ipw_rx_notification(struct ipw_priv *priv,
3265 struct ipw_rx_notification *notif) 4162 struct ipw_rx_notification *notif)
3266{ 4163{
4164 notif->size = le16_to_cpu(notif->size);
4165
3267 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); 4166 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
3268 4167
3269 switch (notif->subtype) { 4168 switch (notif->subtype) {
@@ -3307,30 +4206,44 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3307 4206
3308 priv->status &= ~STATUS_ASSOCIATING; 4207 priv->status &= ~STATUS_ASSOCIATING;
3309 priv->status |= STATUS_ASSOCIATED; 4208 priv->status |= STATUS_ASSOCIATED;
3310 4209 queue_work(priv->workqueue,
3311 netif_carrier_on(priv->net_dev); 4210 &priv->system_config);
3312 if (netif_queue_stopped(priv->net_dev)) { 4211
3313 IPW_DEBUG_NOTIF 4212#ifdef CONFIG_IPW_QOS
3314 ("waking queue\n"); 4213#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
3315 netif_wake_queue(priv->net_dev); 4214 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
3316 } else { 4215 if ((priv->status & STATUS_AUTH) &&
3317 IPW_DEBUG_NOTIF 4216 (IPW_GET_PACKET_STYPE(&notif->u.raw)
3318 ("starting queue\n"); 4217 == IEEE80211_STYPE_ASSOC_RESP)) {
3319 netif_start_queue(priv-> 4218 if ((sizeof
3320 net_dev); 4219 (struct
4220 ieee80211_assoc_response)
4221 <= notif->size)
4222 && (notif->size <= 2314)) {
4223 struct
4224 ieee80211_rx_stats
4225 stats = {
4226 .len =
4227 notif->
4228 size - 1,
4229 };
4230
4231 IPW_DEBUG_QOS
4232 ("QoS Associate "
4233 "size %d\n",
4234 notif->size);
4235 ieee80211_rx_mgt(priv->
4236 ieee,
4237 (struct
4238 ieee80211_hdr_4addr
4239 *)
4240 &notif->u.raw, &stats);
4241 }
3321 } 4242 }
4243#endif
3322 4244
3323 ipw_reset_stats(priv); 4245 schedule_work(&priv->link_up);
3324 /* Ensure the rate is updated immediately */
3325 priv->last_rate =
3326 ipw_get_current_rate(priv);
3327 schedule_work(&priv->gather_stats);
3328 notify_wx_assoc_event(priv);
3329 4246
3330/* queue_delayed_work(priv->workqueue,
3331 &priv->request_scan,
3332 SCAN_ASSOCIATED_INTERVAL);
3333*/
3334 break; 4247 break;
3335 } 4248 }
3336 4249
@@ -3363,12 +4276,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3363 STATUS_AUTH | 4276 STATUS_AUTH |
3364 STATUS_ASSOCIATED); 4277 STATUS_ASSOCIATED);
3365 4278
3366 netif_carrier_off(priv-> 4279 schedule_work(&priv->link_down);
3367 net_dev);
3368 netif_stop_queue(priv->net_dev);
3369 queue_work(priv->workqueue,
3370 &priv->request_scan);
3371 notify_wx_assoc_event(priv);
3372 break; 4280 break;
3373 } 4281 }
3374 4282
@@ -3383,6 +4291,24 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3383 } 4291 }
3384 4292
3385 case CMAS_INIT:{ 4293 case CMAS_INIT:{
4294 if (priv->status & STATUS_AUTH) {
4295 struct
4296 ieee80211_assoc_response
4297 *resp;
4298 resp =
4299 (struct
4300 ieee80211_assoc_response
4301 *)&notif->u.raw;
4302 IPW_DEBUG(IPW_DL_NOTIF |
4303 IPW_DL_STATE |
4304 IPW_DL_ASSOC,
4305 "association failed (0x%04X): %s\n",
4306 ntohs(resp->status),
4307 ipw_get_status_code
4308 (ntohs
4309 (resp->status)));
4310 }
4311
3386 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4312 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3387 IPW_DL_ASSOC, 4313 IPW_DL_ASSOC,
3388 "disassociated: '%s' " MAC_FMT 4314 "disassociated: '%s' " MAC_FMT
@@ -3395,35 +4321,21 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3395 ~(STATUS_DISASSOCIATING | 4321 ~(STATUS_DISASSOCIATING |
3396 STATUS_ASSOCIATING | 4322 STATUS_ASSOCIATING |
3397 STATUS_ASSOCIATED | STATUS_AUTH); 4323 STATUS_ASSOCIATED | STATUS_AUTH);
4324 if (priv->assoc_network
4325 && (priv->assoc_network->
4326 capability &
4327 WLAN_CAPABILITY_IBSS))
4328 ipw_remove_current_network
4329 (priv);
3398 4330
3399 netif_stop_queue(priv->net_dev); 4331 schedule_work(&priv->link_down);
3400 if (!(priv->status & STATUS_ROAMING)) {
3401 netif_carrier_off(priv->
3402 net_dev);
3403 notify_wx_assoc_event(priv);
3404
3405 /* Cancel any queued work ... */
3406 cancel_delayed_work(&priv->
3407 request_scan);
3408 cancel_delayed_work(&priv->
3409 adhoc_check);
3410
3411 /* Queue up another scan... */
3412 queue_work(priv->workqueue,
3413 &priv->request_scan);
3414
3415 cancel_delayed_work(&priv->
3416 gather_stats);
3417 } else {
3418 priv->status |= STATUS_ROAMING;
3419 queue_work(priv->workqueue,
3420 &priv->request_scan);
3421 }
3422 4332
3423 ipw_reset_stats(priv);
3424 break; 4333 break;
3425 } 4334 }
3426 4335
4336 case CMAS_RX_ASSOC_RESP:
4337 break;
4338
3427 default: 4339 default:
3428 IPW_ERROR("assoc: unknown (%d)\n", 4340 IPW_ERROR("assoc: unknown (%d)\n",
3429 assoc->state); 4341 assoc->state);
@@ -3466,11 +4378,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3466 STATUS_AUTH | 4378 STATUS_AUTH |
3467 STATUS_ASSOCIATED); 4379 STATUS_ASSOCIATED);
3468 4380
3469 netif_carrier_off(priv->net_dev); 4381 schedule_work(&priv->link_down);
3470 netif_stop_queue(priv->net_dev);
3471 queue_work(priv->workqueue,
3472 &priv->request_scan);
3473 notify_wx_assoc_event(priv);
3474 break; 4382 break;
3475 4383
3476 case CMAS_TX_AUTH_SEQ_1: 4384 case CMAS_TX_AUTH_SEQ_1:
@@ -3512,6 +4420,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3512 case CMAS_RX_ASSOC_RESP: 4420 case CMAS_RX_ASSOC_RESP:
3513 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4421 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3514 IPW_DL_ASSOC, "RX_ASSOC_RESP\n"); 4422 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
4423
3515 break; 4424 break;
3516 case CMAS_ASSOCIATED: 4425 case CMAS_ASSOCIATED:
3517 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4426 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
@@ -3556,43 +4465,67 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3556 priv->status &= 4465 priv->status &=
3557 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING); 4466 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3558 4467
4468 wake_up_interruptible(&priv->wait_state);
3559 cancel_delayed_work(&priv->scan_check); 4469 cancel_delayed_work(&priv->scan_check);
3560 4470
4471 if (priv->status & STATUS_EXIT_PENDING)
4472 break;
4473
4474 priv->ieee->scans++;
4475
4476#ifdef CONFIG_IPW2200_MONITOR
4477 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4478 priv->status |= STATUS_SCAN_FORCED;
4479 queue_work(priv->workqueue,
4480 &priv->request_scan);
4481 break;
4482 }
4483 priv->status &= ~STATUS_SCAN_FORCED;
4484#endif /* CONFIG_IPW2200_MONITOR */
4485
3561 if (!(priv->status & (STATUS_ASSOCIATED | 4486 if (!(priv->status & (STATUS_ASSOCIATED |
3562 STATUS_ASSOCIATING | 4487 STATUS_ASSOCIATING |
3563 STATUS_ROAMING | 4488 STATUS_ROAMING |
3564 STATUS_DISASSOCIATING))) 4489 STATUS_DISASSOCIATING)))
3565 queue_work(priv->workqueue, &priv->associate); 4490 queue_work(priv->workqueue, &priv->associate);
3566 else if (priv->status & STATUS_ROAMING) { 4491 else if (priv->status & STATUS_ROAMING) {
3567 /* If a scan completed and we are in roam mode, then 4492 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
3568 * the scan that completed was the one requested as a 4493 /* If a scan completed and we are in roam mode, then
3569 * result of entering roam... so, schedule the 4494 * the scan that completed was the one requested as a
3570 * roam work */ 4495 * result of entering roam... so, schedule the
3571 queue_work(priv->workqueue, &priv->roam); 4496 * roam work */
4497 queue_work(priv->workqueue,
4498 &priv->roam);
4499 else
4500 /* Don't schedule if we aborted the scan */
4501 priv->status &= ~STATUS_ROAMING;
3572 } else if (priv->status & STATUS_SCAN_PENDING) 4502 } else if (priv->status & STATUS_SCAN_PENDING)
3573 queue_work(priv->workqueue, 4503 queue_work(priv->workqueue,
3574 &priv->request_scan); 4504 &priv->request_scan);
3575 4505 else if (priv->config & CFG_BACKGROUND_SCAN
3576 priv->ieee->scans++; 4506 && priv->status & STATUS_ASSOCIATED)
4507 queue_delayed_work(priv->workqueue,
4508 &priv->request_scan, HZ);
3577 break; 4509 break;
3578 } 4510 }
3579 4511
3580 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{ 4512 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
3581 struct notif_frag_length *x = &notif->u.frag_len; 4513 struct notif_frag_length *x = &notif->u.frag_len;
3582 4514
3583 if (notif->size == sizeof(*x)) { 4515 if (notif->size == sizeof(*x))
3584 IPW_ERROR("Frag length: %d\n", x->frag_length); 4516 IPW_ERROR("Frag length: %d\n",
3585 } else { 4517 le16_to_cpu(x->frag_length));
4518 else
3586 IPW_ERROR("Frag length of wrong size %d " 4519 IPW_ERROR("Frag length of wrong size %d "
3587 "(should be %zd)\n", 4520 "(should be %zd)\n",
3588 notif->size, sizeof(*x)); 4521 notif->size, sizeof(*x));
3589 }
3590 break; 4522 break;
3591 } 4523 }
3592 4524
3593 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{ 4525 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
3594 struct notif_link_deterioration *x = 4526 struct notif_link_deterioration *x =
3595 &notif->u.link_deterioration; 4527 &notif->u.link_deterioration;
4528
3596 if (notif->size == sizeof(*x)) { 4529 if (notif->size == sizeof(*x)) {
3597 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4530 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3598 "link deterioration: '%s' " MAC_FMT 4531 "link deterioration: '%s' " MAC_FMT
@@ -3612,11 +4545,9 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3612 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{ 4545 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
3613 IPW_ERROR("Dino config\n"); 4546 IPW_ERROR("Dino config\n");
3614 if (priv->hcmd 4547 if (priv->hcmd
3615 && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) { 4548 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
3616 /* TODO: Do anything special? */
3617 } else {
3618 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n"); 4549 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
3619 } 4550
3620 break; 4551 break;
3621 } 4552 }
3622 4553
@@ -3629,36 +4560,11 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3629 break; 4560 break;
3630 } 4561 }
3631 4562
3632 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) { 4563 if (le32_to_cpu(x->state) ==
3633 if (priv->status & STATUS_SCANNING) { 4564 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
3634 /* Stop scan to keep fw from getting 4565 ipw_handle_missed_beacon(priv,
3635 * stuck... */ 4566 le32_to_cpu(x->
3636 queue_work(priv->workqueue, 4567 number));
3637 &priv->abort_scan);
3638 }
3639
3640 if (x->number > priv->missed_beacon_threshold &&
3641 priv->status & STATUS_ASSOCIATED) {
3642 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3643 IPW_DL_STATE,
3644 "Missed beacon: %d - disassociate\n",
3645 x->number);
3646 queue_work(priv->workqueue,
3647 &priv->disassociate);
3648 } else if (x->number > priv->roaming_threshold) {
3649 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3650 "Missed beacon: %d - initiate "
3651 "roaming\n", x->number);
3652 queue_work(priv->workqueue,
3653 &priv->roam);
3654 } else {
3655 IPW_DEBUG_NOTIF("Missed beacon: %d\n",
3656 x->number);
3657 }
3658
3659 priv->notif_missed_beacons = x->number;
3660
3661 }
3662 4568
3663 break; 4569 break;
3664 } 4570 }
@@ -3697,7 +4603,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3697 case HOST_NOTIFICATION_NOISE_STATS:{ 4603 case HOST_NOTIFICATION_NOISE_STATS:{
3698 if (notif->size == sizeof(u32)) { 4604 if (notif->size == sizeof(u32)) {
3699 priv->last_noise = 4605 priv->last_noise =
3700 (u8) (notif->u.noise.value & 0xff); 4606 (u8) (le32_to_cpu(notif->u.noise.value) &
4607 0xff);
3701 average_add(&priv->average_noise, 4608 average_add(&priv->average_noise,
3702 priv->last_noise); 4609 priv->last_noise);
3703 break; 4610 break;
@@ -3730,43 +4637,43 @@ static int ipw_queue_reset(struct ipw_priv *priv)
3730 ipw_tx_queue_free(priv); 4637 ipw_tx_queue_free(priv);
3731 /* Tx CMD queue */ 4638 /* Tx CMD queue */
3732 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd, 4639 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
3733 CX2_TX_CMD_QUEUE_READ_INDEX, 4640 IPW_TX_CMD_QUEUE_READ_INDEX,
3734 CX2_TX_CMD_QUEUE_WRITE_INDEX, 4641 IPW_TX_CMD_QUEUE_WRITE_INDEX,
3735 CX2_TX_CMD_QUEUE_BD_BASE, 4642 IPW_TX_CMD_QUEUE_BD_BASE,
3736 CX2_TX_CMD_QUEUE_BD_SIZE); 4643 IPW_TX_CMD_QUEUE_BD_SIZE);
3737 if (rc) { 4644 if (rc) {
3738 IPW_ERROR("Tx Cmd queue init failed\n"); 4645 IPW_ERROR("Tx Cmd queue init failed\n");
3739 goto error; 4646 goto error;
3740 } 4647 }
3741 /* Tx queue(s) */ 4648 /* Tx queue(s) */
3742 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx, 4649 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
3743 CX2_TX_QUEUE_0_READ_INDEX, 4650 IPW_TX_QUEUE_0_READ_INDEX,
3744 CX2_TX_QUEUE_0_WRITE_INDEX, 4651 IPW_TX_QUEUE_0_WRITE_INDEX,
3745 CX2_TX_QUEUE_0_BD_BASE, CX2_TX_QUEUE_0_BD_SIZE); 4652 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
3746 if (rc) { 4653 if (rc) {
3747 IPW_ERROR("Tx 0 queue init failed\n"); 4654 IPW_ERROR("Tx 0 queue init failed\n");
3748 goto error; 4655 goto error;
3749 } 4656 }
3750 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx, 4657 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
3751 CX2_TX_QUEUE_1_READ_INDEX, 4658 IPW_TX_QUEUE_1_READ_INDEX,
3752 CX2_TX_QUEUE_1_WRITE_INDEX, 4659 IPW_TX_QUEUE_1_WRITE_INDEX,
3753 CX2_TX_QUEUE_1_BD_BASE, CX2_TX_QUEUE_1_BD_SIZE); 4660 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
3754 if (rc) { 4661 if (rc) {
3755 IPW_ERROR("Tx 1 queue init failed\n"); 4662 IPW_ERROR("Tx 1 queue init failed\n");
3756 goto error; 4663 goto error;
3757 } 4664 }
3758 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx, 4665 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
3759 CX2_TX_QUEUE_2_READ_INDEX, 4666 IPW_TX_QUEUE_2_READ_INDEX,
3760 CX2_TX_QUEUE_2_WRITE_INDEX, 4667 IPW_TX_QUEUE_2_WRITE_INDEX,
3761 CX2_TX_QUEUE_2_BD_BASE, CX2_TX_QUEUE_2_BD_SIZE); 4668 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
3762 if (rc) { 4669 if (rc) {
3763 IPW_ERROR("Tx 2 queue init failed\n"); 4670 IPW_ERROR("Tx 2 queue init failed\n");
3764 goto error; 4671 goto error;
3765 } 4672 }
3766 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx, 4673 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
3767 CX2_TX_QUEUE_3_READ_INDEX, 4674 IPW_TX_QUEUE_3_READ_INDEX,
3768 CX2_TX_QUEUE_3_WRITE_INDEX, 4675 IPW_TX_QUEUE_3_WRITE_INDEX,
3769 CX2_TX_QUEUE_3_BD_BASE, CX2_TX_QUEUE_3_BD_SIZE); 4676 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
3770 if (rc) { 4677 if (rc) {
3771 IPW_ERROR("Tx 3 queue init failed\n"); 4678 IPW_ERROR("Tx 3 queue init failed\n");
3772 goto error; 4679 goto error;
@@ -3814,9 +4721,10 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
3814 priv->tx_packets++; 4721 priv->tx_packets++;
3815 } 4722 }
3816 done: 4723 done:
3817 if (ipw_queue_space(q) > q->low_mark && qindex >= 0) { 4724 if ((ipw_queue_space(q) > q->low_mark) &&
3818 __maybe_wake_tx(priv); 4725 (qindex >= 0) &&
3819 } 4726 (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
4727 netif_wake_queue(priv->net_dev);
3820 used = q->first_empty - q->last_used; 4728 used = q->first_empty - q->last_used;
3821 if (used < 0) 4729 if (used < 0)
3822 used += q->n_bd; 4730 used += q->n_bd;
@@ -3857,7 +4765,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
3857 * Rx theory of operation 4765 * Rx theory of operation
3858 * 4766 *
3859 * The host allocates 32 DMA target addresses and passes the host address 4767 * The host allocates 32 DMA target addresses and passes the host address
3860 * to the firmware at register CX2_RFDS_TABLE_LOWER + N * RFD_SIZE where N is 4768 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
3861 * 0 to 31 4769 * 0 to 31
3862 * 4770 *
3863 * Rx Queue Indexes 4771 * Rx Queue Indexes
@@ -3941,7 +4849,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3941 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4849 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3942 list_del(element); 4850 list_del(element);
3943 4851
3944 ipw_write32(priv, CX2_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE, 4852 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
3945 rxb->dma_addr); 4853 rxb->dma_addr);
3946 rxq->queue[rxq->write] = rxb; 4854 rxq->queue[rxq->write] = rxb;
3947 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE; 4855 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
@@ -3956,7 +4864,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3956 4864
3957 /* If we've added more space for the firmware to place data, tell it */ 4865 /* If we've added more space for the firmware to place data, tell it */
3958 if (write != rxq->write) 4866 if (write != rxq->write)
3959 ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write); 4867 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
3960} 4868}
3961 4869
3962/* 4870/*
@@ -3977,7 +4885,7 @@ static void ipw_rx_queue_replenish(void *data)
3977 while (!list_empty(&rxq->rx_used)) { 4885 while (!list_empty(&rxq->rx_used)) {
3978 element = rxq->rx_used.next; 4886 element = rxq->rx_used.next;
3979 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4887 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3980 rxb->skb = alloc_skb(CX2_RX_BUF_SIZE, GFP_ATOMIC); 4888 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
3981 if (!rxb->skb) { 4889 if (!rxb->skb) {
3982 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n", 4890 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
3983 priv->net_dev->name); 4891 priv->net_dev->name);
@@ -3991,7 +4899,7 @@ static void ipw_rx_queue_replenish(void *data)
3991 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; 4899 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
3992 rxb->dma_addr = 4900 rxb->dma_addr =
3993 pci_map_single(priv->pci_dev, rxb->skb->data, 4901 pci_map_single(priv->pci_dev, rxb->skb->data,
3994 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4902 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
3995 4903
3996 list_add_tail(&rxb->list, &rxq->rx_free); 4904 list_add_tail(&rxb->list, &rxq->rx_free);
3997 rxq->free_count++; 4905 rxq->free_count++;
@@ -4001,6 +4909,14 @@ static void ipw_rx_queue_replenish(void *data)
4001 ipw_rx_queue_restock(priv); 4909 ipw_rx_queue_restock(priv);
4002} 4910}
4003 4911
4912static void ipw_bg_rx_queue_replenish(void *data)
4913{
4914 struct ipw_priv *priv = data;
4915 down(&priv->sem);
4916 ipw_rx_queue_replenish(data);
4917 up(&priv->sem);
4918}
4919
4004/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 4920/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4005 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL 4921 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
4006 * This free routine walks the list of POOL entries and if SKB is set to 4922 * This free routine walks the list of POOL entries and if SKB is set to
@@ -4016,7 +4932,7 @@ static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
4016 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { 4932 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4017 if (rxq->pool[i].skb != NULL) { 4933 if (rxq->pool[i].skb != NULL) {
4018 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 4934 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
4019 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4935 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4020 dev_kfree_skb(rxq->pool[i].skb); 4936 dev_kfree_skb(rxq->pool[i].skb);
4021 } 4937 }
4022 } 4938 }
@@ -4135,8 +5051,18 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4135 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES); 5051 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
4136 rates->num_rates = 0; 5052 rates->num_rates = 0;
4137 for (i = 0; i < num_rates; i++) { 5053 for (i = 0; i < num_rates; i++) {
4138 if (!ipw_is_rate_in_mask 5054 if (!ipw_is_rate_in_mask(priv, network->mode,
4139 (priv, network->mode, network->rates[i])) { 5055 network->rates[i])) {
5056
5057 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
5058 IPW_DEBUG_SCAN("Adding masked mandatory "
5059 "rate %02X\n",
5060 network->rates[i]);
5061 rates->supported_rates[rates->num_rates++] =
5062 network->rates[i];
5063 continue;
5064 }
5065
4140 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5066 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4141 network->rates[i], priv->rates_mask); 5067 network->rates[i], priv->rates_mask);
4142 continue; 5068 continue;
@@ -4145,11 +5071,20 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4145 rates->supported_rates[rates->num_rates++] = network->rates[i]; 5071 rates->supported_rates[rates->num_rates++] = network->rates[i];
4146 } 5072 }
4147 5073
4148 num_rates = 5074 num_rates = min(network->rates_ex_len,
4149 min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates)); 5075 (u8) (IPW_MAX_RATES - num_rates));
4150 for (i = 0; i < num_rates; i++) { 5076 for (i = 0; i < num_rates; i++) {
4151 if (!ipw_is_rate_in_mask 5077 if (!ipw_is_rate_in_mask(priv, network->mode,
4152 (priv, network->mode, network->rates_ex[i])) { 5078 network->rates_ex[i])) {
5079 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
5080 IPW_DEBUG_SCAN("Adding masked mandatory "
5081 "rate %02X\n",
5082 network->rates_ex[i]);
5083 rates->supported_rates[rates->num_rates++] =
5084 network->rates[i];
5085 continue;
5086 }
5087
4153 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5088 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4154 network->rates_ex[i], priv->rates_mask); 5089 network->rates_ex[i], priv->rates_mask);
4155 continue; 5090 continue;
@@ -4159,7 +5094,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4159 network->rates_ex[i]; 5094 network->rates_ex[i];
4160 } 5095 }
4161 5096
4162 return rates->num_rates; 5097 return 1;
4163} 5098}
4164 5099
4165static inline void ipw_copy_rates(struct ipw_supported_rates *dest, 5100static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
@@ -4241,6 +5176,216 @@ struct ipw_network_match {
4241 struct ipw_supported_rates rates; 5176 struct ipw_supported_rates rates;
4242}; 5177};
4243 5178
5179static int ipw_find_adhoc_network(struct ipw_priv *priv,
5180 struct ipw_network_match *match,
5181 struct ieee80211_network *network,
5182 int roaming)
5183{
5184 struct ipw_supported_rates rates;
5185
5186 /* Verify that this network's capability is compatible with the
5187 * current mode (AdHoc or Infrastructure) */
5188 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
5189 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5190 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
5191 "capability mismatch.\n",
5192 escape_essid(network->ssid, network->ssid_len),
5193 MAC_ARG(network->bssid));
5194 return 0;
5195 }
5196
5197 /* If we do not have an ESSID for this AP, we can not associate with
5198 * it */
5199 if (network->flags & NETWORK_EMPTY_ESSID) {
5200 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5201 "because of hidden ESSID.\n",
5202 escape_essid(network->ssid, network->ssid_len),
5203 MAC_ARG(network->bssid));
5204 return 0;
5205 }
5206
5207 if (unlikely(roaming)) {
5208 /* If we are roaming, then ensure check if this is a valid
5209 * network to try and roam to */
5210 if ((network->ssid_len != match->network->ssid_len) ||
5211 memcmp(network->ssid, match->network->ssid,
5212 network->ssid_len)) {
5213 IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
5214 "because of non-network ESSID.\n",
5215 escape_essid(network->ssid,
5216 network->ssid_len),
5217 MAC_ARG(network->bssid));
5218 return 0;
5219 }
5220 } else {
5221 /* If an ESSID has been configured then compare the broadcast
5222 * ESSID to ours */
5223 if ((priv->config & CFG_STATIC_ESSID) &&
5224 ((network->ssid_len != priv->essid_len) ||
5225 memcmp(network->ssid, priv->essid,
5226 min(network->ssid_len, priv->essid_len)))) {
5227 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5228
5229 strncpy(escaped,
5230 escape_essid(network->ssid, network->ssid_len),
5231 sizeof(escaped));
5232 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5233 "because of ESSID mismatch: '%s'.\n",
5234 escaped, MAC_ARG(network->bssid),
5235 escape_essid(priv->essid,
5236 priv->essid_len));
5237 return 0;
5238 }
5239 }
5240
5241 /* If the old network rate is better than this one, don't bother
5242 * testing everything else. */
5243
5244 if (network->time_stamp[0] < match->network->time_stamp[0]) {
5245 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5246 "current network.\n",
5247 escape_essid(match->network->ssid,
5248 match->network->ssid_len));
5249 return 0;
5250 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
5251 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5252 "current network.\n",
5253 escape_essid(match->network->ssid,
5254 match->network->ssid_len));
5255 return 0;
5256 }
5257
5258 /* Now go through and see if the requested network is valid... */
5259 if (priv->ieee->scan_age != 0 &&
5260 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5261 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5262 "because of age: %lums.\n",
5263 escape_essid(network->ssid, network->ssid_len),
5264 MAC_ARG(network->bssid),
5265 1000 * (jiffies - network->last_scanned) / HZ);
5266 return 0;
5267 }
5268
5269 if ((priv->config & CFG_STATIC_CHANNEL) &&
5270 (network->channel != priv->channel)) {
5271 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5272 "because of channel mismatch: %d != %d.\n",
5273 escape_essid(network->ssid, network->ssid_len),
5274 MAC_ARG(network->bssid),
5275 network->channel, priv->channel);
5276 return 0;
5277 }
5278
5279 /* Verify privacy compatability */
5280 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5281 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5282 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5283 "because of privacy mismatch: %s != %s.\n",
5284 escape_essid(network->ssid, network->ssid_len),
5285 MAC_ARG(network->bssid),
5286 priv->
5287 capability & CAP_PRIVACY_ON ? "on" : "off",
5288 network->
5289 capability & WLAN_CAPABILITY_PRIVACY ? "on" :
5290 "off");
5291 return 0;
5292 }
5293
5294 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5295 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5296 "because of the same BSSID match: " MAC_FMT
5297 ".\n", escape_essid(network->ssid,
5298 network->ssid_len),
5299 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
5300 return 0;
5301 }
5302
5303 /* Filter out any incompatible freq / mode combinations */
5304 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5305 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5306 "because of invalid frequency/mode "
5307 "combination.\n",
5308 escape_essid(network->ssid, network->ssid_len),
5309 MAC_ARG(network->bssid));
5310 return 0;
5311 }
5312
5313 /* Ensure that the rates supported by the driver are compatible with
5314 * this AP, including verification of basic rates (mandatory) */
5315 if (!ipw_compatible_rates(priv, network, &rates)) {
5316 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5317 "because configured rate mask excludes "
5318 "AP mandatory rate.\n",
5319 escape_essid(network->ssid, network->ssid_len),
5320 MAC_ARG(network->bssid));
5321 return 0;
5322 }
5323
5324 if (rates.num_rates == 0) {
5325 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5326 "because of no compatible rates.\n",
5327 escape_essid(network->ssid, network->ssid_len),
5328 MAC_ARG(network->bssid));
5329 return 0;
5330 }
5331
5332 /* TODO: Perform any further minimal comparititive tests. We do not
5333 * want to put too much policy logic here; intelligent scan selection
5334 * should occur within a generic IEEE 802.11 user space tool. */
5335
5336 /* Set up 'new' AP to this network */
5337 ipw_copy_rates(&match->rates, &rates);
5338 match->network = network;
5339 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
5340 escape_essid(network->ssid, network->ssid_len),
5341 MAC_ARG(network->bssid));
5342
5343 return 1;
5344}
5345
5346static void ipw_merge_adhoc_network(void *data)
5347{
5348 struct ipw_priv *priv = data;
5349 struct ieee80211_network *network = NULL;
5350 struct ipw_network_match match = {
5351 .network = priv->assoc_network
5352 };
5353
5354 if ((priv->status & STATUS_ASSOCIATED) &&
5355 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5356 /* First pass through ROAM process -- look for a better
5357 * network */
5358 unsigned long flags;
5359
5360 spin_lock_irqsave(&priv->ieee->lock, flags);
5361 list_for_each_entry(network, &priv->ieee->network_list, list) {
5362 if (network != priv->assoc_network)
5363 ipw_find_adhoc_network(priv, &match, network,
5364 1);
5365 }
5366 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5367
5368 if (match.network == priv->assoc_network) {
5369 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5370 "merge to.\n");
5371 return;
5372 }
5373
5374 down(&priv->sem);
5375 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5376 IPW_DEBUG_MERGE("remove network %s\n",
5377 escape_essid(priv->essid,
5378 priv->essid_len));
5379 ipw_remove_current_network(priv);
5380 }
5381
5382 ipw_disassociate(priv);
5383 priv->assoc_network = match.network;
5384 up(&priv->sem);
5385 return;
5386 }
5387}
5388
4244static int ipw_best_network(struct ipw_priv *priv, 5389static int ipw_best_network(struct ipw_priv *priv,
4245 struct ipw_network_match *match, 5390 struct ipw_network_match *match,
4246 struct ieee80211_network *network, int roaming) 5391 struct ieee80211_network *network, int roaming)
@@ -4322,9 +5467,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4322 /* If this network has already had an association attempt within the 5467 /* If this network has already had an association attempt within the
4323 * last 3 seconds, do not try and associate again... */ 5468 * last 3 seconds, do not try and associate again... */
4324 if (network->last_associate && 5469 if (network->last_associate &&
4325 time_after(network->last_associate + (HZ * 5UL), jiffies)) { 5470 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
4326 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5471 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4327 "because of storming (%lu since last " 5472 "because of storming (%lus since last "
4328 "assoc attempt).\n", 5473 "assoc attempt).\n",
4329 escape_essid(network->ssid, network->ssid_len), 5474 escape_essid(network->ssid, network->ssid_len),
4330 MAC_ARG(network->bssid), 5475 MAC_ARG(network->bssid),
@@ -4334,12 +5479,12 @@ static int ipw_best_network(struct ipw_priv *priv,
4334 5479
4335 /* Now go through and see if the requested network is valid... */ 5480 /* Now go through and see if the requested network is valid... */
4336 if (priv->ieee->scan_age != 0 && 5481 if (priv->ieee->scan_age != 0 &&
4337 jiffies - network->last_scanned > priv->ieee->scan_age) { 5482 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
4338 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5483 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4339 "because of age: %lums.\n", 5484 "because of age: %lums.\n",
4340 escape_essid(network->ssid, network->ssid_len), 5485 escape_essid(network->ssid, network->ssid_len),
4341 MAC_ARG(network->bssid), 5486 MAC_ARG(network->bssid),
4342 (jiffies - network->last_scanned) / (HZ / 100)); 5487 1000 * (jiffies - network->last_scanned) / HZ);
4343 return 0; 5488 return 0;
4344 } 5489 }
4345 5490
@@ -4367,6 +5512,15 @@ static int ipw_best_network(struct ipw_priv *priv,
4367 return 0; 5512 return 0;
4368 } 5513 }
4369 5514
5515 if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
5516 network->rsn_ie_len > 0)) {
5517 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5518 "because of WPA capability mismatch.\n",
5519 escape_essid(network->ssid, network->ssid_len),
5520 MAC_ARG(network->bssid));
5521 return 0;
5522 }
5523
4370 if ((priv->config & CFG_STATIC_BSSID) && 5524 if ((priv->config & CFG_STATIC_BSSID) &&
4371 memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5525 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
4372 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5526 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -4386,7 +5540,26 @@ static int ipw_best_network(struct ipw_priv *priv,
4386 return 0; 5540 return 0;
4387 } 5541 }
4388 5542
4389 ipw_compatible_rates(priv, network, &rates); 5543 /* Filter out invalid channel in current GEO */
5544 if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
5545 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5546 "because of invalid channel in current GEO\n",
5547 escape_essid(network->ssid, network->ssid_len),
5548 MAC_ARG(network->bssid));
5549 return 0;
5550 }
5551
5552 /* Ensure that the rates supported by the driver are compatible with
5553 * this AP, including verification of basic rates (mandatory) */
5554 if (!ipw_compatible_rates(priv, network, &rates)) {
5555 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5556 "because configured rate mask excludes "
5557 "AP mandatory rate.\n",
5558 escape_essid(network->ssid, network->ssid_len),
5559 MAC_ARG(network->bssid));
5560 return 0;
5561 }
5562
4390 if (rates.num_rates == 0) { 5563 if (rates.num_rates == 0) {
4391 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5564 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4392 "because of no compatible rates.\n", 5565 "because of no compatible rates.\n",
@@ -4413,6 +5586,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4413static void ipw_adhoc_create(struct ipw_priv *priv, 5586static void ipw_adhoc_create(struct ipw_priv *priv,
4414 struct ieee80211_network *network) 5587 struct ieee80211_network *network)
4415{ 5588{
5589 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5590 int i;
5591
4416 /* 5592 /*
4417 * For the purposes of scanning, we can set our wireless mode 5593 * For the purposes of scanning, we can set our wireless mode
4418 * to trigger scans across combinations of bands, but when it 5594 * to trigger scans across combinations of bands, but when it
@@ -4423,22 +5599,47 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4423 * chossen band. Attempting to create a new ad-hoc network 5599 * chossen band. Attempting to create a new ad-hoc network
4424 * with an invalid channel for wireless mode will trigger a 5600 * with an invalid channel for wireless mode will trigger a
4425 * FW fatal error. 5601 * FW fatal error.
5602 *
4426 */ 5603 */
4427 network->mode = is_valid_channel(priv->ieee->mode, priv->channel); 5604 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
4428 if (network->mode) { 5605 case IEEE80211_52GHZ_BAND:
4429 network->channel = priv->channel; 5606 network->mode = IEEE_A;
4430 } else { 5607 i = ipw_channel_to_index(priv->ieee, priv->channel);
5608 if (i == -1)
5609 BUG();
5610 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5611 IPW_WARNING("Overriding invalid channel\n");
5612 priv->channel = geo->a[0].channel;
5613 }
5614 break;
5615
5616 case IEEE80211_24GHZ_BAND:
5617 if (priv->ieee->mode & IEEE_G)
5618 network->mode = IEEE_G;
5619 else
5620 network->mode = IEEE_B;
5621 i = ipw_channel_to_index(priv->ieee, priv->channel);
5622 if (i == -1)
5623 BUG();
5624 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5625 IPW_WARNING("Overriding invalid channel\n");
5626 priv->channel = geo->bg[0].channel;
5627 }
5628 break;
5629
5630 default:
4431 IPW_WARNING("Overriding invalid channel\n"); 5631 IPW_WARNING("Overriding invalid channel\n");
4432 if (priv->ieee->mode & IEEE_A) { 5632 if (priv->ieee->mode & IEEE_A) {
4433 network->mode = IEEE_A; 5633 network->mode = IEEE_A;
4434 priv->channel = band_a_active_channel[0]; 5634 priv->channel = geo->a[0].channel;
4435 } else if (priv->ieee->mode & IEEE_G) { 5635 } else if (priv->ieee->mode & IEEE_G) {
4436 network->mode = IEEE_G; 5636 network->mode = IEEE_G;
4437 priv->channel = band_b_active_channel[0]; 5637 priv->channel = geo->bg[0].channel;
4438 } else { 5638 } else {
4439 network->mode = IEEE_B; 5639 network->mode = IEEE_B;
4440 priv->channel = band_b_active_channel[0]; 5640 priv->channel = geo->bg[0].channel;
4441 } 5641 }
5642 break;
4442 } 5643 }
4443 5644
4444 network->channel = priv->channel; 5645 network->channel = priv->channel;
@@ -4448,6 +5649,8 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4448 memcpy(network->ssid, priv->essid, priv->essid_len); 5649 memcpy(network->ssid, priv->essid, priv->essid_len);
4449 memset(&network->stats, 0, sizeof(network->stats)); 5650 memset(&network->stats, 0, sizeof(network->stats));
4450 network->capability = WLAN_CAPABILITY_IBSS; 5651 network->capability = WLAN_CAPABILITY_IBSS;
5652 if (!(priv->config & CFG_PREAMBLE_LONG))
5653 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
4451 if (priv->capability & CAP_PRIVACY_ON) 5654 if (priv->capability & CAP_PRIVACY_ON)
4452 network->capability |= WLAN_CAPABILITY_PRIVACY; 5655 network->capability |= WLAN_CAPABILITY_PRIVACY;
4453 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); 5656 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
@@ -4464,13 +5667,35 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4464 network->beacon_interval = 100; /* Default */ 5667 network->beacon_interval = 100; /* Default */
4465 network->listen_interval = 10; /* Default */ 5668 network->listen_interval = 10; /* Default */
4466 network->atim_window = 0; /* Default */ 5669 network->atim_window = 0; /* Default */
4467#ifdef CONFIG_IEEE80211_WPA
4468 network->wpa_ie_len = 0; 5670 network->wpa_ie_len = 0;
4469 network->rsn_ie_len = 0; 5671 network->rsn_ie_len = 0;
4470#endif /* CONFIG_IEEE80211_WPA */
4471} 5672}
4472 5673
4473static void ipw_send_wep_keys(struct ipw_priv *priv) 5674static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5675{
5676 struct ipw_tgi_tx_key *key;
5677 struct host_cmd cmd = {
5678 .cmd = IPW_CMD_TGI_TX_KEY,
5679 .len = sizeof(*key)
5680 };
5681
5682 if (!(priv->ieee->sec.flags & (1 << index)))
5683 return;
5684
5685 key = (struct ipw_tgi_tx_key *)&cmd.param;
5686 key->key_id = index;
5687 memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5688 key->security_type = type;
5689 key->station_index = 0; /* always 0 for BSS */
5690 key->flags = 0;
5691 /* 0 for new key; previous value of counter (after fatal error) */
5692 key->tx_counter[0] = 0;
5693 key->tx_counter[1] = 0;
5694
5695 ipw_send_cmd(priv, &cmd);
5696}
5697
5698static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
4474{ 5699{
4475 struct ipw_wep_key *key; 5700 struct ipw_wep_key *key;
4476 int i; 5701 int i;
@@ -4483,19 +5708,97 @@ static void ipw_send_wep_keys(struct ipw_priv *priv)
4483 key->cmd_id = DINO_CMD_WEP_KEY; 5708 key->cmd_id = DINO_CMD_WEP_KEY;
4484 key->seq_num = 0; 5709 key->seq_num = 0;
4485 5710
5711 /* Note: AES keys cannot be set for multiple times.
5712 * Only set it at the first time. */
4486 for (i = 0; i < 4; i++) { 5713 for (i = 0; i < 4; i++) {
4487 key->key_index = i; 5714 key->key_index = i | type;
4488 if (!(priv->sec.flags & (1 << i))) { 5715 if (!(priv->ieee->sec.flags & (1 << i))) {
4489 key->key_size = 0; 5716 key->key_size = 0;
4490 } else { 5717 continue;
4491 key->key_size = priv->sec.key_sizes[i];
4492 memcpy(key->key, priv->sec.keys[i], key->key_size);
4493 } 5718 }
4494 5719
4495 if (ipw_send_cmd(priv, &cmd)) { 5720 key->key_size = priv->ieee->sec.key_sizes[i];
4496 IPW_ERROR("failed to send WEP_KEY command\n"); 5721 memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
4497 return; 5722
4498 } 5723 ipw_send_cmd(priv, &cmd);
5724 }
5725}
5726
5727static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
5728{
5729 if (priv->ieee->host_encrypt)
5730 return;
5731
5732 switch (level) {
5733 case SEC_LEVEL_3:
5734 priv->sys_config.disable_unicast_decryption = 0;
5735 priv->ieee->host_decrypt = 0;
5736 break;
5737 case SEC_LEVEL_2:
5738 priv->sys_config.disable_unicast_decryption = 1;
5739 priv->ieee->host_decrypt = 1;
5740 break;
5741 case SEC_LEVEL_1:
5742 priv->sys_config.disable_unicast_decryption = 0;
5743 priv->ieee->host_decrypt = 0;
5744 break;
5745 case SEC_LEVEL_0:
5746 priv->sys_config.disable_unicast_decryption = 1;
5747 break;
5748 default:
5749 break;
5750 }
5751}
5752
5753static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
5754{
5755 if (priv->ieee->host_encrypt)
5756 return;
5757
5758 switch (level) {
5759 case SEC_LEVEL_3:
5760 priv->sys_config.disable_multicast_decryption = 0;
5761 break;
5762 case SEC_LEVEL_2:
5763 priv->sys_config.disable_multicast_decryption = 1;
5764 break;
5765 case SEC_LEVEL_1:
5766 priv->sys_config.disable_multicast_decryption = 0;
5767 break;
5768 case SEC_LEVEL_0:
5769 priv->sys_config.disable_multicast_decryption = 1;
5770 break;
5771 default:
5772 break;
5773 }
5774}
5775
5776static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5777{
5778 switch (priv->ieee->sec.level) {
5779 case SEC_LEVEL_3:
5780 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5781 ipw_send_tgi_tx_key(priv,
5782 DCT_FLAG_EXT_SECURITY_CCM,
5783 priv->ieee->sec.active_key);
5784
5785 if (!priv->ieee->host_mc_decrypt)
5786 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
5787 break;
5788 case SEC_LEVEL_2:
5789 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5790 ipw_send_tgi_tx_key(priv,
5791 DCT_FLAG_EXT_SECURITY_TKIP,
5792 priv->ieee->sec.active_key);
5793 break;
5794 case SEC_LEVEL_1:
5795 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
5796 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
5797 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
5798 break;
5799 case SEC_LEVEL_0:
5800 default:
5801 break;
4499 } 5802 }
4500} 5803}
4501 5804
@@ -4503,9 +5806,12 @@ static void ipw_adhoc_check(void *data)
4503{ 5806{
4504 struct ipw_priv *priv = data; 5807 struct ipw_priv *priv = data;
4505 5808
4506 if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold && 5809 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
4507 !(priv->config & CFG_ADHOC_PERSIST)) { 5810 !(priv->config & CFG_ADHOC_PERSIST)) {
4508 IPW_DEBUG_SCAN("Disassociating due to missed beacons\n"); 5811 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
5812 IPW_DL_STATE | IPW_DL_ASSOC,
5813 "Missed beacon: %d - disassociate\n",
5814 priv->missed_adhoc_beacons);
4509 ipw_remove_current_network(priv); 5815 ipw_remove_current_network(priv);
4510 ipw_disassociate(priv); 5816 ipw_disassociate(priv);
4511 return; 5817 return;
@@ -4515,6 +5821,14 @@ static void ipw_adhoc_check(void *data)
4515 priv->assoc_request.beacon_interval); 5821 priv->assoc_request.beacon_interval);
4516} 5822}
4517 5823
5824static void ipw_bg_adhoc_check(void *data)
5825{
5826 struct ipw_priv *priv = data;
5827 down(&priv->sem);
5828 ipw_adhoc_check(data);
5829 up(&priv->sem);
5830}
5831
4518#ifdef CONFIG_IPW_DEBUG 5832#ifdef CONFIG_IPW_DEBUG
4519static void ipw_debug_config(struct ipw_priv *priv) 5833static void ipw_debug_config(struct ipw_priv *priv)
4520{ 5834{
@@ -4530,7 +5844,8 @@ static void ipw_debug_config(struct ipw_priv *priv)
4530 else 5844 else
4531 IPW_DEBUG_INFO("ESSID unlocked.\n"); 5845 IPW_DEBUG_INFO("ESSID unlocked.\n");
4532 if (priv->config & CFG_STATIC_BSSID) 5846 if (priv->config & CFG_STATIC_BSSID)
4533 IPW_DEBUG_INFO("BSSID locked to %d\n", priv->channel); 5847 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
5848 MAC_ARG(priv->bssid));
4534 else 5849 else
4535 IPW_DEBUG_INFO("BSSID unlocked.\n"); 5850 IPW_DEBUG_INFO("BSSID unlocked.\n");
4536 if (priv->capability & CAP_PRIVACY_ON) 5851 if (priv->capability & CAP_PRIVACY_ON)
@@ -4543,8 +5858,7 @@ static void ipw_debug_config(struct ipw_priv *priv)
4543#define ipw_debug_config(x) do {} while (0) 5858#define ipw_debug_config(x) do {} while (0)
4544#endif 5859#endif
4545 5860
4546static inline void ipw_set_fixed_rate(struct ipw_priv *priv, 5861static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
4547 struct ieee80211_network *network)
4548{ 5862{
4549 /* TODO: Verify that this works... */ 5863 /* TODO: Verify that this works... */
4550 struct ipw_fixed_rate fr = { 5864 struct ipw_fixed_rate fr = {
@@ -4561,6 +5875,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4561 /* IEEE_A */ 5875 /* IEEE_A */
4562 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) { 5876 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
4563 /* Invalid fixed rate mask */ 5877 /* Invalid fixed rate mask */
5878 IPW_DEBUG_WX
5879 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4564 fr.tx_rates = 0; 5880 fr.tx_rates = 0;
4565 break; 5881 break;
4566 } 5882 }
@@ -4570,9 +5886,11 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4570 5886
4571 default: /* 2.4Ghz or Mixed */ 5887 default: /* 2.4Ghz or Mixed */
4572 /* IEEE_B */ 5888 /* IEEE_B */
4573 if (network->mode == IEEE_B) { 5889 if (mode == IEEE_B) {
4574 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { 5890 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
4575 /* Invalid fixed rate mask */ 5891 /* Invalid fixed rate mask */
5892 IPW_DEBUG_WX
5893 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4576 fr.tx_rates = 0; 5894 fr.tx_rates = 0;
4577 } 5895 }
4578 break; 5896 break;
@@ -4582,6 +5900,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4582 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK | 5900 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
4583 IEEE80211_OFDM_RATES_MASK)) { 5901 IEEE80211_OFDM_RATES_MASK)) {
4584 /* Invalid fixed rate mask */ 5902 /* Invalid fixed rate mask */
5903 IPW_DEBUG_WX
5904 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4585 fr.tx_rates = 0; 5905 fr.tx_rates = 0;
4586 break; 5906 break;
4587 } 5907 }
@@ -4609,6 +5929,1112 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4609 ipw_write_reg32(priv, reg, *(u32 *) & fr); 5929 ipw_write_reg32(priv, reg, *(u32 *) & fr);
4610} 5930}
4611 5931
5932static void ipw_abort_scan(struct ipw_priv *priv)
5933{
5934 int err;
5935
5936 if (priv->status & STATUS_SCAN_ABORTING) {
5937 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5938 return;
5939 }
5940 priv->status |= STATUS_SCAN_ABORTING;
5941
5942 err = ipw_send_scan_abort(priv);
5943 if (err)
5944 IPW_DEBUG_HC("Request to abort scan failed.\n");
5945}
5946
5947static void ipw_add_scan_channels(struct ipw_priv *priv,
5948 struct ipw_scan_request_ext *scan,
5949 int scan_type)
5950{
5951 int channel_index = 0;
5952 const struct ieee80211_geo *geo;
5953 int i;
5954
5955 geo = ipw_get_geo(priv->ieee);
5956
5957 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5958 int start = channel_index;
5959 for (i = 0; i < geo->a_channels; i++) {
5960 if ((priv->status & STATUS_ASSOCIATED) &&
5961 geo->a[i].channel == priv->channel)
5962 continue;
5963 channel_index++;
5964 scan->channels_list[channel_index] = geo->a[i].channel;
5965 ipw_set_scan_type(scan, channel_index,
5966 geo->a[i].
5967 flags & IEEE80211_CH_PASSIVE_ONLY ?
5968 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
5969 scan_type);
5970 }
5971
5972 if (start != channel_index) {
5973 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
5974 (channel_index - start);
5975 channel_index++;
5976 }
5977 }
5978
5979 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5980 int start = channel_index;
5981 if (priv->config & CFG_SPEED_SCAN) {
5982 int index;
5983 u8 channels[IEEE80211_24GHZ_CHANNELS] = {
5984 /* nop out the list */
5985 [0] = 0
5986 };
5987
5988 u8 channel;
5989 while (channel_index < IPW_SCAN_CHANNELS) {
5990 channel =
5991 priv->speed_scan[priv->speed_scan_pos];
5992 if (channel == 0) {
5993 priv->speed_scan_pos = 0;
5994 channel = priv->speed_scan[0];
5995 }
5996 if ((priv->status & STATUS_ASSOCIATED) &&
5997 channel == priv->channel) {
5998 priv->speed_scan_pos++;
5999 continue;
6000 }
6001
6002 /* If this channel has already been
6003 * added in scan, break from loop
6004 * and this will be the first channel
6005 * in the next scan.
6006 */
6007 if (channels[channel - 1] != 0)
6008 break;
6009
6010 channels[channel - 1] = 1;
6011 priv->speed_scan_pos++;
6012 channel_index++;
6013 scan->channels_list[channel_index] = channel;
6014 index =
6015 ipw_channel_to_index(priv->ieee, channel);
6016 ipw_set_scan_type(scan, channel_index,
6017 geo->bg[index].
6018 flags &
6019 IEEE80211_CH_PASSIVE_ONLY ?
6020 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6021 : scan_type);
6022 }
6023 } else {
6024 for (i = 0; i < geo->bg_channels; i++) {
6025 if ((priv->status & STATUS_ASSOCIATED) &&
6026 geo->bg[i].channel == priv->channel)
6027 continue;
6028 channel_index++;
6029 scan->channels_list[channel_index] =
6030 geo->bg[i].channel;
6031 ipw_set_scan_type(scan, channel_index,
6032 geo->bg[i].
6033 flags &
6034 IEEE80211_CH_PASSIVE_ONLY ?
6035 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6036 : scan_type);
6037 }
6038 }
6039
6040 if (start != channel_index) {
6041 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
6042 (channel_index - start);
6043 }
6044 }
6045}
6046
6047static int ipw_request_scan(struct ipw_priv *priv)
6048{
6049 struct ipw_scan_request_ext scan;
6050 int err = 0, scan_type;
6051
6052 if (!(priv->status & STATUS_INIT) ||
6053 (priv->status & STATUS_EXIT_PENDING))
6054 return 0;
6055
6056 down(&priv->sem);
6057
6058 if (priv->status & STATUS_SCANNING) {
6059 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
6060 priv->status |= STATUS_SCAN_PENDING;
6061 goto done;
6062 }
6063
6064 if (!(priv->status & STATUS_SCAN_FORCED) &&
6065 priv->status & STATUS_SCAN_ABORTING) {
6066 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
6067 priv->status |= STATUS_SCAN_PENDING;
6068 goto done;
6069 }
6070
6071 if (priv->status & STATUS_RF_KILL_MASK) {
6072 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
6073 priv->status |= STATUS_SCAN_PENDING;
6074 goto done;
6075 }
6076
6077 memset(&scan, 0, sizeof(scan));
6078
6079 if (priv->config & CFG_SPEED_SCAN)
6080 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6081 cpu_to_le16(30);
6082 else
6083 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6084 cpu_to_le16(20);
6085
6086 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
6087 cpu_to_le16(20);
6088 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
6089
6090 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
6091
6092#ifdef CONFIG_IPW2200_MONITOR
6093 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
6094 u8 channel;
6095 u8 band = 0;
6096
6097 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
6098 case IEEE80211_52GHZ_BAND:
6099 band = (u8) (IPW_A_MODE << 6) | 1;
6100 channel = priv->channel;
6101 break;
6102
6103 case IEEE80211_24GHZ_BAND:
6104 band = (u8) (IPW_B_MODE << 6) | 1;
6105 channel = priv->channel;
6106 break;
6107
6108 default:
6109 band = (u8) (IPW_B_MODE << 6) | 1;
6110 channel = 9;
6111 break;
6112 }
6113
6114 scan.channels_list[0] = band;
6115 scan.channels_list[1] = channel;
6116 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
6117
6118 /* NOTE: The card will sit on this channel for this time
6119 * period. Scan aborts are timing sensitive and frequently
6120 * result in firmware restarts. As such, it is best to
6121 * set a small dwell_time here and just keep re-issuing
6122 * scans. Otherwise fast channel hopping will not actually
6123 * hop channels.
6124 *
6125 * TODO: Move SPEED SCAN support to all modes and bands */
6126 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6127 cpu_to_le16(2000);
6128 } else {
6129#endif /* CONFIG_IPW2200_MONITOR */
6130 /* If we are roaming, then make this a directed scan for the
6131 * current network. Otherwise, ensure that every other scan
6132 * is a fast channel hop scan */
6133 if ((priv->status & STATUS_ROAMING)
6134 || (!(priv->status & STATUS_ASSOCIATED)
6135 && (priv->config & CFG_STATIC_ESSID)
6136 && (le32_to_cpu(scan.full_scan_index) % 2))) {
6137 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6138 if (err) {
6139 IPW_DEBUG_HC("Attempt to send SSID command "
6140 "failed.\n");
6141 goto done;
6142 }
6143
6144 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
6145 } else
6146 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
6147
6148 ipw_add_scan_channels(priv, &scan, scan_type);
6149#ifdef CONFIG_IPW2200_MONITOR
6150 }
6151#endif
6152
6153 err = ipw_send_scan_request_ext(priv, &scan);
6154 if (err) {
6155 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
6156 goto done;
6157 }
6158
6159 priv->status |= STATUS_SCANNING;
6160 priv->status &= ~STATUS_SCAN_PENDING;
6161 queue_delayed_work(priv->workqueue, &priv->scan_check,
6162 IPW_SCAN_CHECK_WATCHDOG);
6163 done:
6164 up(&priv->sem);
6165 return err;
6166}
6167
6168static void ipw_bg_abort_scan(void *data)
6169{
6170 struct ipw_priv *priv = data;
6171 down(&priv->sem);
6172 ipw_abort_scan(data);
6173 up(&priv->sem);
6174}
6175
6176static int ipw_wpa_enable(struct ipw_priv *priv, int value)
6177{
6178 /* This is called when wpa_supplicant loads and closes the driver
6179 * interface. */
6180 priv->ieee->wpa_enabled = value;
6181 return 0;
6182}
6183
6184static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6185{
6186 struct ieee80211_device *ieee = priv->ieee;
6187 struct ieee80211_security sec = {
6188 .flags = SEC_AUTH_MODE,
6189 };
6190 int ret = 0;
6191
6192 if (value & IW_AUTH_ALG_SHARED_KEY) {
6193 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
6194 ieee->open_wep = 0;
6195 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
6196 sec.auth_mode = WLAN_AUTH_OPEN;
6197 ieee->open_wep = 1;
6198 } else
6199 return -EINVAL;
6200
6201 if (ieee->set_security)
6202 ieee->set_security(ieee->dev, &sec);
6203 else
6204 ret = -EOPNOTSUPP;
6205
6206 return ret;
6207}
6208
6209void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
6210{
6211 /* make sure WPA is enabled */
6212 ipw_wpa_enable(priv, 1);
6213
6214 ipw_disassociate(priv);
6215}
6216
6217static int ipw_set_rsn_capa(struct ipw_priv *priv,
6218 char *capabilities, int length)
6219{
6220 struct host_cmd cmd = {
6221 .cmd = IPW_CMD_RSN_CAPABILITIES,
6222 .len = length,
6223 };
6224
6225 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6226
6227 memcpy(cmd.param, capabilities, length);
6228 return ipw_send_cmd(priv, &cmd);
6229}
6230
6231/*
6232 * WE-18 support
6233 */
6234
6235/* SIOCSIWGENIE */
6236static int ipw_wx_set_genie(struct net_device *dev,
6237 struct iw_request_info *info,
6238 union iwreq_data *wrqu, char *extra)
6239{
6240 struct ipw_priv *priv = ieee80211_priv(dev);
6241 struct ieee80211_device *ieee = priv->ieee;
6242 u8 *buf;
6243 int err = 0;
6244
6245 if (wrqu->data.length > MAX_WPA_IE_LEN ||
6246 (wrqu->data.length && extra == NULL))
6247 return -EINVAL;
6248
6249 //down(&priv->sem);
6250
6251 //if (!ieee->wpa_enabled) {
6252 // err = -EOPNOTSUPP;
6253 // goto out;
6254 //}
6255
6256 if (wrqu->data.length) {
6257 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
6258 if (buf == NULL) {
6259 err = -ENOMEM;
6260 goto out;
6261 }
6262
6263 memcpy(buf, extra, wrqu->data.length);
6264 kfree(ieee->wpa_ie);
6265 ieee->wpa_ie = buf;
6266 ieee->wpa_ie_len = wrqu->data.length;
6267 } else {
6268 kfree(ieee->wpa_ie);
6269 ieee->wpa_ie = NULL;
6270 ieee->wpa_ie_len = 0;
6271 }
6272
6273 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6274 out:
6275 //up(&priv->sem);
6276 return err;
6277}
6278
6279/* SIOCGIWGENIE */
6280static int ipw_wx_get_genie(struct net_device *dev,
6281 struct iw_request_info *info,
6282 union iwreq_data *wrqu, char *extra)
6283{
6284 struct ipw_priv *priv = ieee80211_priv(dev);
6285 struct ieee80211_device *ieee = priv->ieee;
6286 int err = 0;
6287
6288 //down(&priv->sem);
6289
6290 //if (!ieee->wpa_enabled) {
6291 // err = -EOPNOTSUPP;
6292 // goto out;
6293 //}
6294
6295 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6296 wrqu->data.length = 0;
6297 goto out;
6298 }
6299
6300 if (wrqu->data.length < ieee->wpa_ie_len) {
6301 err = -E2BIG;
6302 goto out;
6303 }
6304
6305 wrqu->data.length = ieee->wpa_ie_len;
6306 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6307
6308 out:
6309 //up(&priv->sem);
6310 return err;
6311}
6312
6313static int wext_cipher2level(int cipher)
6314{
6315 switch (cipher) {
6316 case IW_AUTH_CIPHER_NONE:
6317 return SEC_LEVEL_0;
6318 case IW_AUTH_CIPHER_WEP40:
6319 case IW_AUTH_CIPHER_WEP104:
6320 return SEC_LEVEL_1;
6321 case IW_AUTH_CIPHER_TKIP:
6322 return SEC_LEVEL_2;
6323 case IW_AUTH_CIPHER_CCMP:
6324 return SEC_LEVEL_3;
6325 default:
6326 return -1;
6327 }
6328}
6329
6330/* SIOCSIWAUTH */
6331static int ipw_wx_set_auth(struct net_device *dev,
6332 struct iw_request_info *info,
6333 union iwreq_data *wrqu, char *extra)
6334{
6335 struct ipw_priv *priv = ieee80211_priv(dev);
6336 struct ieee80211_device *ieee = priv->ieee;
6337 struct iw_param *param = &wrqu->param;
6338 struct ieee80211_crypt_data *crypt;
6339 unsigned long flags;
6340 int ret = 0;
6341
6342 switch (param->flags & IW_AUTH_INDEX) {
6343 case IW_AUTH_WPA_VERSION:
6344 break;
6345 case IW_AUTH_CIPHER_PAIRWISE:
6346 ipw_set_hw_decrypt_unicast(priv,
6347 wext_cipher2level(param->value));
6348 break;
6349 case IW_AUTH_CIPHER_GROUP:
6350 ipw_set_hw_decrypt_multicast(priv,
6351 wext_cipher2level(param->value));
6352 break;
6353 case IW_AUTH_KEY_MGMT:
6354 /*
6355 * ipw2200 does not use these parameters
6356 */
6357 break;
6358
6359 case IW_AUTH_TKIP_COUNTERMEASURES:
6360 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6361 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
6362 break;
6363
6364 flags = crypt->ops->get_flags(crypt->priv);
6365
6366 if (param->value)
6367 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6368 else
6369 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6370
6371 crypt->ops->set_flags(flags, crypt->priv);
6372
6373 break;
6374
6375 case IW_AUTH_DROP_UNENCRYPTED:{
6376 /* HACK:
6377 *
6378 * wpa_supplicant calls set_wpa_enabled when the driver
6379 * is loaded and unloaded, regardless of if WPA is being
6380 * used. No other calls are made which can be used to
6381 * determine if encryption will be used or not prior to
6382 * association being expected. If encryption is not being
6383 * used, drop_unencrypted is set to false, else true -- we
6384 * can use this to determine if the CAP_PRIVACY_ON bit should
6385 * be set.
6386 */
6387 struct ieee80211_security sec = {
6388 .flags = SEC_ENABLED,
6389 .enabled = param->value,
6390 };
6391 priv->ieee->drop_unencrypted = param->value;
6392 /* We only change SEC_LEVEL for open mode. Others
6393 * are set by ipw_wpa_set_encryption.
6394 */
6395 if (!param->value) {
6396 sec.flags |= SEC_LEVEL;
6397 sec.level = SEC_LEVEL_0;
6398 } else {
6399 sec.flags |= SEC_LEVEL;
6400 sec.level = SEC_LEVEL_1;
6401 }
6402 if (priv->ieee->set_security)
6403 priv->ieee->set_security(priv->ieee->dev, &sec);
6404 break;
6405 }
6406
6407 case IW_AUTH_80211_AUTH_ALG:
6408 ret = ipw_wpa_set_auth_algs(priv, param->value);
6409 break;
6410
6411 case IW_AUTH_WPA_ENABLED:
6412 ret = ipw_wpa_enable(priv, param->value);
6413 break;
6414
6415 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6416 ieee->ieee802_1x = param->value;
6417 break;
6418
6419 //case IW_AUTH_ROAMING_CONTROL:
6420 case IW_AUTH_PRIVACY_INVOKED:
6421 ieee->privacy_invoked = param->value;
6422 break;
6423
6424 default:
6425 return -EOPNOTSUPP;
6426 }
6427 return ret;
6428}
6429
6430/* SIOCGIWAUTH */
6431static int ipw_wx_get_auth(struct net_device *dev,
6432 struct iw_request_info *info,
6433 union iwreq_data *wrqu, char *extra)
6434{
6435 struct ipw_priv *priv = ieee80211_priv(dev);
6436 struct ieee80211_device *ieee = priv->ieee;
6437 struct ieee80211_crypt_data *crypt;
6438 struct iw_param *param = &wrqu->param;
6439 int ret = 0;
6440
6441 switch (param->flags & IW_AUTH_INDEX) {
6442 case IW_AUTH_WPA_VERSION:
6443 case IW_AUTH_CIPHER_PAIRWISE:
6444 case IW_AUTH_CIPHER_GROUP:
6445 case IW_AUTH_KEY_MGMT:
6446 /*
6447 * wpa_supplicant will control these internally
6448 */
6449 ret = -EOPNOTSUPP;
6450 break;
6451
6452 case IW_AUTH_TKIP_COUNTERMEASURES:
6453 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6454 if (!crypt || !crypt->ops->get_flags)
6455 break;
6456
6457 param->value = (crypt->ops->get_flags(crypt->priv) &
6458 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
6459
6460 break;
6461
6462 case IW_AUTH_DROP_UNENCRYPTED:
6463 param->value = ieee->drop_unencrypted;
6464 break;
6465
6466 case IW_AUTH_80211_AUTH_ALG:
6467 param->value = ieee->sec.auth_mode;
6468 break;
6469
6470 case IW_AUTH_WPA_ENABLED:
6471 param->value = ieee->wpa_enabled;
6472 break;
6473
6474 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6475 param->value = ieee->ieee802_1x;
6476 break;
6477
6478 case IW_AUTH_ROAMING_CONTROL:
6479 case IW_AUTH_PRIVACY_INVOKED:
6480 param->value = ieee->privacy_invoked;
6481 break;
6482
6483 default:
6484 return -EOPNOTSUPP;
6485 }
6486 return 0;
6487}
6488
6489/* SIOCSIWENCODEEXT */
6490static int ipw_wx_set_encodeext(struct net_device *dev,
6491 struct iw_request_info *info,
6492 union iwreq_data *wrqu, char *extra)
6493{
6494 struct ipw_priv *priv = ieee80211_priv(dev);
6495 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6496
6497 if (hwcrypto) {
6498 if (ext->alg == IW_ENCODE_ALG_TKIP) {
6499 /* IPW HW can't build TKIP MIC,
6500 host decryption still needed */
6501 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6502 priv->ieee->host_mc_decrypt = 1;
6503 else {
6504 priv->ieee->host_encrypt = 0;
6505 priv->ieee->host_encrypt_msdu = 1;
6506 priv->ieee->host_decrypt = 1;
6507 }
6508 } else {
6509 priv->ieee->host_encrypt = 0;
6510 priv->ieee->host_encrypt_msdu = 0;
6511 priv->ieee->host_decrypt = 0;
6512 priv->ieee->host_mc_decrypt = 0;
6513 }
6514 }
6515
6516 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
6517}
6518
6519/* SIOCGIWENCODEEXT */
6520static int ipw_wx_get_encodeext(struct net_device *dev,
6521 struct iw_request_info *info,
6522 union iwreq_data *wrqu, char *extra)
6523{
6524 struct ipw_priv *priv = ieee80211_priv(dev);
6525 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
6526}
6527
6528/* SIOCSIWMLME */
6529static int ipw_wx_set_mlme(struct net_device *dev,
6530 struct iw_request_info *info,
6531 union iwreq_data *wrqu, char *extra)
6532{
6533 struct ipw_priv *priv = ieee80211_priv(dev);
6534 struct iw_mlme *mlme = (struct iw_mlme *)extra;
6535 u16 reason;
6536
6537 reason = cpu_to_le16(mlme->reason_code);
6538
6539 switch (mlme->cmd) {
6540 case IW_MLME_DEAUTH:
6541 // silently ignore
6542 break;
6543
6544 case IW_MLME_DISASSOC:
6545 ipw_disassociate(priv);
6546 break;
6547
6548 default:
6549 return -EOPNOTSUPP;
6550 }
6551 return 0;
6552}
6553
6554#ifdef CONFIG_IPW_QOS
6555
6556/* QoS */
6557/*
6558* get the modulation type of the current network or
6559* the card current mode
6560*/
6561u8 ipw_qos_current_mode(struct ipw_priv * priv)
6562{
6563 u8 mode = 0;
6564
6565 if (priv->status & STATUS_ASSOCIATED) {
6566 unsigned long flags;
6567
6568 spin_lock_irqsave(&priv->ieee->lock, flags);
6569 mode = priv->assoc_network->mode;
6570 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6571 } else {
6572 mode = priv->ieee->mode;
6573 }
6574 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
6575 return mode;
6576}
6577
6578/*
6579* Handle management frame beacon and probe response
6580*/
6581static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6582 int active_network,
6583 struct ieee80211_network *network)
6584{
6585 u32 size = sizeof(struct ieee80211_qos_parameters);
6586
6587 if (network->capability & WLAN_CAPABILITY_IBSS)
6588 network->qos_data.active = network->qos_data.supported;
6589
6590 if (network->flags & NETWORK_HAS_QOS_MASK) {
6591 if (active_network &&
6592 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
6593 network->qos_data.active = network->qos_data.supported;
6594
6595 if ((network->qos_data.active == 1) && (active_network == 1) &&
6596 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6597 (network->qos_data.old_param_count !=
6598 network->qos_data.param_count)) {
6599 network->qos_data.old_param_count =
6600 network->qos_data.param_count;
6601 schedule_work(&priv->qos_activate);
6602 IPW_DEBUG_QOS("QoS parameters change call "
6603 "qos_activate\n");
6604 }
6605 } else {
6606 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
6607 memcpy(&network->qos_data.parameters,
6608 &def_parameters_CCK, size);
6609 else
6610 memcpy(&network->qos_data.parameters,
6611 &def_parameters_OFDM, size);
6612
6613 if ((network->qos_data.active == 1) && (active_network == 1)) {
6614 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
6615 schedule_work(&priv->qos_activate);
6616 }
6617
6618 network->qos_data.active = 0;
6619 network->qos_data.supported = 0;
6620 }
6621 if ((priv->status & STATUS_ASSOCIATED) &&
6622 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6623 if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
6624 if ((network->capability & WLAN_CAPABILITY_IBSS) &&
6625 !(network->flags & NETWORK_EMPTY_ESSID))
6626 if ((network->ssid_len ==
6627 priv->assoc_network->ssid_len) &&
6628 !memcmp(network->ssid,
6629 priv->assoc_network->ssid,
6630 network->ssid_len)) {
6631 queue_work(priv->workqueue,
6632 &priv->merge_networks);
6633 }
6634 }
6635
6636 return 0;
6637}
6638
6639/*
6640* This function set up the firmware to support QoS. It sends
6641* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
6642*/
6643static int ipw_qos_activate(struct ipw_priv *priv,
6644 struct ieee80211_qos_data *qos_network_data)
6645{
6646 int err;
6647 struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
6648 struct ieee80211_qos_parameters *active_one = NULL;
6649 u32 size = sizeof(struct ieee80211_qos_parameters);
6650 u32 burst_duration;
6651 int i;
6652 u8 type;
6653
6654 type = ipw_qos_current_mode(priv);
6655
6656 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
6657 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
6658 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
6659 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
6660
6661 if (qos_network_data == NULL) {
6662 if (type == IEEE_B) {
6663 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
6664 active_one = &def_parameters_CCK;
6665 } else
6666 active_one = &def_parameters_OFDM;
6667
6668 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6669 burst_duration = ipw_qos_get_burst_duration(priv);
6670 for (i = 0; i < QOS_QUEUE_NUM; i++)
6671 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
6672 (u16) burst_duration;
6673 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6674 if (type == IEEE_B) {
6675 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
6676 type);
6677 if (priv->qos_data.qos_enable == 0)
6678 active_one = &def_parameters_CCK;
6679 else
6680 active_one = priv->qos_data.def_qos_parm_CCK;
6681 } else {
6682 if (priv->qos_data.qos_enable == 0)
6683 active_one = &def_parameters_OFDM;
6684 else
6685 active_one = priv->qos_data.def_qos_parm_OFDM;
6686 }
6687 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6688 } else {
6689 unsigned long flags;
6690 int active;
6691
6692 spin_lock_irqsave(&priv->ieee->lock, flags);
6693 active_one = &(qos_network_data->parameters);
6694 qos_network_data->old_param_count =
6695 qos_network_data->param_count;
6696 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6697 active = qos_network_data->supported;
6698 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6699
6700 if (active == 0) {
6701 burst_duration = ipw_qos_get_burst_duration(priv);
6702 for (i = 0; i < QOS_QUEUE_NUM; i++)
6703 qos_parameters[QOS_PARAM_SET_ACTIVE].
6704 tx_op_limit[i] = (u16) burst_duration;
6705 }
6706 }
6707
6708 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
6709 err = ipw_send_qos_params_command(priv,
6710 (struct ieee80211_qos_parameters *)
6711 &(qos_parameters[0]));
6712 if (err)
6713 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
6714
6715 return err;
6716}
6717
6718/*
6719* send IPW_CMD_WME_INFO to the firmware
6720*/
6721static int ipw_qos_set_info_element(struct ipw_priv *priv)
6722{
6723 int ret = 0;
6724 struct ieee80211_qos_information_element qos_info;
6725
6726 if (priv == NULL)
6727 return -1;
6728
6729 qos_info.elementID = QOS_ELEMENT_ID;
6730 qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
6731
6732 qos_info.version = QOS_VERSION_1;
6733 qos_info.ac_info = 0;
6734
6735 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
6736 qos_info.qui_type = QOS_OUI_TYPE;
6737 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
6738
6739 ret = ipw_send_qos_info_command(priv, &qos_info);
6740 if (ret != 0) {
6741 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
6742 }
6743 return ret;
6744}
6745
6746/*
6747* Set the QoS parameter with the association request structure
6748*/
6749static int ipw_qos_association(struct ipw_priv *priv,
6750 struct ieee80211_network *network)
6751{
6752 int err = 0;
6753 struct ieee80211_qos_data *qos_data = NULL;
6754 struct ieee80211_qos_data ibss_data = {
6755 .supported = 1,
6756 .active = 1,
6757 };
6758
6759 switch (priv->ieee->iw_mode) {
6760 case IW_MODE_ADHOC:
6761 if (!(network->capability & WLAN_CAPABILITY_IBSS))
6762 BUG();
6763
6764 qos_data = &ibss_data;
6765 break;
6766
6767 case IW_MODE_INFRA:
6768 qos_data = &network->qos_data;
6769 break;
6770
6771 default:
6772 BUG();
6773 break;
6774 }
6775
6776 err = ipw_qos_activate(priv, qos_data);
6777 if (err) {
6778 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
6779 return err;
6780 }
6781
6782 if (priv->qos_data.qos_enable && qos_data->supported) {
6783 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
6784 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
6785 return ipw_qos_set_info_element(priv);
6786 }
6787
6788 return 0;
6789}
6790
6791/*
6792* handling the beaconing responces. if we get different QoS setting
6793* of the network from the the associated setting adjust the QoS
6794* setting
6795*/
6796static int ipw_qos_association_resp(struct ipw_priv *priv,
6797 struct ieee80211_network *network)
6798{
6799 int ret = 0;
6800 unsigned long flags;
6801 u32 size = sizeof(struct ieee80211_qos_parameters);
6802 int set_qos_param = 0;
6803
6804 if ((priv == NULL) || (network == NULL) ||
6805 (priv->assoc_network == NULL))
6806 return ret;
6807
6808 if (!(priv->status & STATUS_ASSOCIATED))
6809 return ret;
6810
6811 if ((priv->ieee->iw_mode != IW_MODE_INFRA))
6812 return ret;
6813
6814 spin_lock_irqsave(&priv->ieee->lock, flags);
6815 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
6816 memcpy(&priv->assoc_network->qos_data, &network->qos_data,
6817 sizeof(struct ieee80211_qos_data));
6818 priv->assoc_network->qos_data.active = 1;
6819 if ((network->qos_data.old_param_count !=
6820 network->qos_data.param_count)) {
6821 set_qos_param = 1;
6822 network->qos_data.old_param_count =
6823 network->qos_data.param_count;
6824 }
6825
6826 } else {
6827 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
6828 memcpy(&priv->assoc_network->qos_data.parameters,
6829 &def_parameters_CCK, size);
6830 else
6831 memcpy(&priv->assoc_network->qos_data.parameters,
6832 &def_parameters_OFDM, size);
6833 priv->assoc_network->qos_data.active = 0;
6834 priv->assoc_network->qos_data.supported = 0;
6835 set_qos_param = 1;
6836 }
6837
6838 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6839
6840 if (set_qos_param == 1)
6841 schedule_work(&priv->qos_activate);
6842
6843 return ret;
6844}
6845
6846static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
6847{
6848 u32 ret = 0;
6849
6850 if ((priv == NULL))
6851 return 0;
6852
6853 if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION))
6854 ret = priv->qos_data.burst_duration_CCK;
6855 else
6856 ret = priv->qos_data.burst_duration_OFDM;
6857
6858 return ret;
6859}
6860
6861/*
6862* Initialize the setting of QoS global
6863*/
6864static void ipw_qos_init(struct ipw_priv *priv, int enable,
6865 int burst_enable, u32 burst_duration_CCK,
6866 u32 burst_duration_OFDM)
6867{
6868 priv->qos_data.qos_enable = enable;
6869
6870 if (priv->qos_data.qos_enable) {
6871 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
6872 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
6873 IPW_DEBUG_QOS("QoS is enabled\n");
6874 } else {
6875 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
6876 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
6877 IPW_DEBUG_QOS("QoS is not enabled\n");
6878 }
6879
6880 priv->qos_data.burst_enable = burst_enable;
6881
6882 if (burst_enable) {
6883 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
6884 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
6885 } else {
6886 priv->qos_data.burst_duration_CCK = 0;
6887 priv->qos_data.burst_duration_OFDM = 0;
6888 }
6889}
6890
6891/*
6892* map the packet priority to the right TX Queue
6893*/
6894static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
6895{
6896 if (priority > 7 || !priv->qos_data.qos_enable)
6897 priority = 0;
6898
6899 return from_priority_to_tx_queue[priority] - 1;
6900}
6901
6902/*
6903* add QoS parameter to the TX command
6904*/
6905static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
6906 u16 priority,
6907 struct tfd_data *tfd, u8 unicast)
6908{
6909 int ret = 0;
6910 int tx_queue_id = 0;
6911 struct ieee80211_qos_data *qos_data = NULL;
6912 int active, supported;
6913 unsigned long flags;
6914
6915 if (!(priv->status & STATUS_ASSOCIATED))
6916 return 0;
6917
6918 qos_data = &priv->assoc_network->qos_data;
6919
6920 spin_lock_irqsave(&priv->ieee->lock, flags);
6921
6922 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6923 if (unicast == 0)
6924 qos_data->active = 0;
6925 else
6926 qos_data->active = qos_data->supported;
6927 }
6928
6929 active = qos_data->active;
6930 supported = qos_data->supported;
6931
6932 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6933
6934 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
6935 "unicast %d\n",
6936 priv->qos_data.qos_enable, active, supported, unicast);
6937 if (active && priv->qos_data.qos_enable) {
6938 ret = from_priority_to_tx_queue[priority];
6939 tx_queue_id = ret - 1;
6940 IPW_DEBUG_QOS("QoS packet priority is %d \n", priority);
6941 if (priority <= 7) {
6942 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
6943 tfd->tfd.tfd_26.mchdr.qos_ctrl = priority;
6944 tfd->tfd.tfd_26.mchdr.frame_ctl |=
6945 IEEE80211_STYPE_QOS_DATA;
6946
6947 if (priv->qos_data.qos_no_ack_mask &
6948 (1UL << tx_queue_id)) {
6949 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
6950 tfd->tfd.tfd_26.mchdr.qos_ctrl |=
6951 CTRL_QOS_NO_ACK;
6952 }
6953 }
6954 }
6955
6956 return ret;
6957}
6958
6959/*
6960* background support to run QoS activate functionality
6961*/
6962static void ipw_bg_qos_activate(void *data)
6963{
6964 struct ipw_priv *priv = data;
6965
6966 if (priv == NULL)
6967 return;
6968
6969 down(&priv->sem);
6970
6971 if (priv->status & STATUS_ASSOCIATED)
6972 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
6973
6974 up(&priv->sem);
6975}
6976
6977static int ipw_handle_probe_response(struct net_device *dev,
6978 struct ieee80211_probe_response *resp,
6979 struct ieee80211_network *network)
6980{
6981 struct ipw_priv *priv = ieee80211_priv(dev);
6982 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6983 (network == priv->assoc_network));
6984
6985 ipw_qos_handle_probe_response(priv, active_network, network);
6986
6987 return 0;
6988}
6989
6990static int ipw_handle_beacon(struct net_device *dev,
6991 struct ieee80211_beacon *resp,
6992 struct ieee80211_network *network)
6993{
6994 struct ipw_priv *priv = ieee80211_priv(dev);
6995 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6996 (network == priv->assoc_network));
6997
6998 ipw_qos_handle_probe_response(priv, active_network, network);
6999
7000 return 0;
7001}
7002
7003static int ipw_handle_assoc_response(struct net_device *dev,
7004 struct ieee80211_assoc_response *resp,
7005 struct ieee80211_network *network)
7006{
7007 struct ipw_priv *priv = ieee80211_priv(dev);
7008 ipw_qos_association_resp(priv, network);
7009 return 0;
7010}
7011
7012static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
7013 *qos_param)
7014{
7015 struct host_cmd cmd = {
7016 .cmd = IPW_CMD_QOS_PARAMETERS,
7017 .len = (sizeof(struct ieee80211_qos_parameters) * 3)
7018 };
7019
7020 memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
7021 return ipw_send_cmd(priv, &cmd);
7022}
7023
7024static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
7025 *qos_param)
7026{
7027 struct host_cmd cmd = {
7028 .cmd = IPW_CMD_WME_INFO,
7029 .len = sizeof(*qos_param)
7030 };
7031
7032 memcpy(cmd.param, qos_param, sizeof(*qos_param));
7033 return ipw_send_cmd(priv, &cmd);
7034}
7035
7036#endif /* CONFIG_IPW_QOS */
7037
4612static int ipw_associate_network(struct ipw_priv *priv, 7038static int ipw_associate_network(struct ipw_priv *priv,
4613 struct ieee80211_network *network, 7039 struct ieee80211_network *network,
4614 struct ipw_supported_rates *rates, int roaming) 7040 struct ipw_supported_rates *rates, int roaming)
@@ -4616,7 +7042,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4616 int err; 7042 int err;
4617 7043
4618 if (priv->config & CFG_FIXED_RATE) 7044 if (priv->config & CFG_FIXED_RATE)
4619 ipw_set_fixed_rate(priv, network); 7045 ipw_set_fixed_rate(priv, network->mode);
4620 7046
4621 if (!(priv->config & CFG_STATIC_ESSID)) { 7047 if (!(priv->config & CFG_STATIC_ESSID)) {
4622 priv->essid_len = min(network->ssid_len, 7048 priv->essid_len = min(network->ssid_len,
@@ -4631,14 +7057,22 @@ static int ipw_associate_network(struct ipw_priv *priv,
4631 if ((priv->capability & CAP_PRIVACY_ON) && 7057 if ((priv->capability & CAP_PRIVACY_ON) &&
4632 (priv->capability & CAP_SHARED_KEY)) { 7058 (priv->capability & CAP_SHARED_KEY)) {
4633 priv->assoc_request.auth_type = AUTH_SHARED_KEY; 7059 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
4634 priv->assoc_request.auth_key = priv->sec.active_key; 7060 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7061
7062 if ((priv->capability & CAP_PRIVACY_ON) &&
7063 (priv->ieee->sec.level == SEC_LEVEL_1) &&
7064 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
7065 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
4635 } else { 7066 } else {
4636 priv->assoc_request.auth_type = AUTH_OPEN; 7067 priv->assoc_request.auth_type = AUTH_OPEN;
4637 priv->assoc_request.auth_key = 0; 7068 priv->assoc_request.auth_key = 0;
4638 } 7069 }
4639 7070
4640 if (priv->capability & CAP_PRIVACY_ON) 7071 if (priv->ieee->wpa_ie_len) {
4641 ipw_send_wep_keys(priv); 7072 priv->assoc_request.policy_support = 0x02; /* RSN active */
7073 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
7074 priv->ieee->wpa_ie_len);
7075 }
4642 7076
4643 /* 7077 /*
4644 * It is valid for our ieee device to support multiple modes, but 7078 * It is valid for our ieee device to support multiple modes, but
@@ -4652,20 +7086,41 @@ static int ipw_associate_network(struct ipw_priv *priv,
4652 else if (network->mode & priv->ieee->mode & IEEE_B) 7086 else if (network->mode & priv->ieee->mode & IEEE_B)
4653 priv->assoc_request.ieee_mode = IPW_B_MODE; 7087 priv->assoc_request.ieee_mode = IPW_B_MODE;
4654 7088
7089 priv->assoc_request.capability = network->capability;
7090 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
7091 && !(priv->config & CFG_PREAMBLE_LONG)) {
7092 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
7093 } else {
7094 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
7095
7096 /* Clear the short preamble if we won't be supporting it */
7097 priv->assoc_request.capability &=
7098 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
7099 }
7100
7101 /* Clear capability bits that aren't used in Ad Hoc */
7102 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7103 priv->assoc_request.capability &=
7104 ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
7105
4655 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, " 7106 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
4656 "802.11%c [%d], enc=%s%s%s%c%c\n", 7107 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
4657 roaming ? "Rea" : "A", 7108 roaming ? "Rea" : "A",
4658 escape_essid(priv->essid, priv->essid_len), 7109 escape_essid(priv->essid, priv->essid_len),
4659 network->channel, 7110 network->channel,
4660 ipw_modes[priv->assoc_request.ieee_mode], 7111 ipw_modes[priv->assoc_request.ieee_mode],
4661 rates->num_rates, 7112 rates->num_rates,
7113 (priv->assoc_request.preamble_length ==
7114 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
7115 network->capability &
7116 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
4662 priv->capability & CAP_PRIVACY_ON ? "on " : "off", 7117 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
4663 priv->capability & CAP_PRIVACY_ON ? 7118 priv->capability & CAP_PRIVACY_ON ?
4664 (priv->capability & CAP_SHARED_KEY ? "(shared)" : 7119 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
4665 "(open)") : "", 7120 "(open)") : "",
4666 priv->capability & CAP_PRIVACY_ON ? " key=" : "", 7121 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
4667 priv->capability & CAP_PRIVACY_ON ? 7122 priv->capability & CAP_PRIVACY_ON ?
4668 '1' + priv->sec.active_key : '.', 7123 '1' + priv->ieee->sec.active_key : '.',
4669 priv->capability & CAP_PRIVACY_ON ? '.' : ' '); 7124 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
4670 7125
4671 priv->assoc_request.beacon_interval = network->beacon_interval; 7126 priv->assoc_request.beacon_interval = network->beacon_interval;
@@ -4683,17 +7138,16 @@ static int ipw_associate_network(struct ipw_priv *priv,
4683 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0]; 7138 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
4684 } 7139 }
4685 7140
4686 memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN); 7141 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
4687 7142
4688 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7143 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
4689 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN); 7144 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
4690 priv->assoc_request.atim_window = network->atim_window; 7145 priv->assoc_request.atim_window = network->atim_window;
4691 } else { 7146 } else {
4692 memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN); 7147 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
4693 priv->assoc_request.atim_window = 0; 7148 priv->assoc_request.atim_window = 0;
4694 } 7149 }
4695 7150
4696 priv->assoc_request.capability = network->capability;
4697 priv->assoc_request.listen_interval = network->listen_interval; 7151 priv->assoc_request.listen_interval = network->listen_interval;
4698 7152
4699 err = ipw_send_ssid(priv, priv->essid, priv->essid_len); 7153 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
@@ -4710,6 +7164,12 @@ static int ipw_associate_network(struct ipw_priv *priv,
4710 priv->sys_config.dot11g_auto_detection = 1; 7164 priv->sys_config.dot11g_auto_detection = 1;
4711 else 7165 else
4712 priv->sys_config.dot11g_auto_detection = 0; 7166 priv->sys_config.dot11g_auto_detection = 0;
7167
7168 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7169 priv->sys_config.answer_broadcast_ssid_probe = 1;
7170 else
7171 priv->sys_config.answer_broadcast_ssid_probe = 0;
7172
4713 err = ipw_send_system_config(priv, &priv->sys_config); 7173 err = ipw_send_system_config(priv, &priv->sys_config);
4714 if (err) { 7174 if (err) {
4715 IPW_DEBUG_HC("Attempt to send sys config command failed.\n"); 7175 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
@@ -4717,7 +7177,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4717 } 7177 }
4718 7178
4719 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi); 7179 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
4720 err = ipw_set_sensitivity(priv, network->stats.rssi); 7180 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
4721 if (err) { 7181 if (err) {
4722 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7182 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
4723 return err; 7183 return err;
@@ -4735,6 +7195,10 @@ static int ipw_associate_network(struct ipw_priv *priv,
4735 7195
4736 priv->assoc_network = network; 7196 priv->assoc_network = network;
4737 7197
7198#ifdef CONFIG_IPW_QOS
7199 ipw_qos_association(priv, network);
7200#endif
7201
4738 err = ipw_send_associate(priv, &priv->assoc_request); 7202 err = ipw_send_associate(priv, &priv->assoc_request);
4739 if (err) { 7203 if (err) {
4740 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7204 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
@@ -4782,12 +7246,15 @@ static void ipw_roam(void *data)
4782 if (priv->status & STATUS_ASSOCIATED) { 7246 if (priv->status & STATUS_ASSOCIATED) {
4783 /* First pass through ROAM process -- look for a better 7247 /* First pass through ROAM process -- look for a better
4784 * network */ 7248 * network */
7249 unsigned long flags;
4785 u8 rssi = priv->assoc_network->stats.rssi; 7250 u8 rssi = priv->assoc_network->stats.rssi;
4786 priv->assoc_network->stats.rssi = -128; 7251 priv->assoc_network->stats.rssi = -128;
7252 spin_lock_irqsave(&priv->ieee->lock, flags);
4787 list_for_each_entry(network, &priv->ieee->network_list, list) { 7253 list_for_each_entry(network, &priv->ieee->network_list, list) {
4788 if (network != priv->assoc_network) 7254 if (network != priv->assoc_network)
4789 ipw_best_network(priv, &match, network, 1); 7255 ipw_best_network(priv, &match, network, 1);
4790 } 7256 }
7257 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4791 priv->assoc_network->stats.rssi = rssi; 7258 priv->assoc_network->stats.rssi = rssi;
4792 7259
4793 if (match.network == priv->assoc_network) { 7260 if (match.network == priv->assoc_network) {
@@ -4810,7 +7277,15 @@ static void ipw_roam(void *data)
4810 priv->status &= ~STATUS_ROAMING; 7277 priv->status &= ~STATUS_ROAMING;
4811} 7278}
4812 7279
4813static void ipw_associate(void *data) 7280static void ipw_bg_roam(void *data)
7281{
7282 struct ipw_priv *priv = data;
7283 down(&priv->sem);
7284 ipw_roam(data);
7285 up(&priv->sem);
7286}
7287
7288static int ipw_associate(void *data)
4814{ 7289{
4815 struct ipw_priv *priv = data; 7290 struct ipw_priv *priv = data;
4816 7291
@@ -4820,14 +7295,41 @@ static void ipw_associate(void *data)
4820 }; 7295 };
4821 struct ipw_supported_rates *rates; 7296 struct ipw_supported_rates *rates;
4822 struct list_head *element; 7297 struct list_head *element;
7298 unsigned long flags;
7299
7300 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7301 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7302 return 0;
7303 }
7304
7305 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7306 IPW_DEBUG_ASSOC("Not attempting association (already in "
7307 "progress)\n");
7308 return 0;
7309 }
7310
7311 if (priv->status & STATUS_DISASSOCIATING) {
7312 IPW_DEBUG_ASSOC("Not attempting association (in "
7313 "disassociating)\n ");
7314 queue_work(priv->workqueue, &priv->associate);
7315 return 0;
7316 }
7317
7318 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
7319 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
7320 "initialized)\n");
7321 return 0;
7322 }
4823 7323
4824 if (!(priv->config & CFG_ASSOCIATE) && 7324 if (!(priv->config & CFG_ASSOCIATE) &&
4825 !(priv->config & (CFG_STATIC_ESSID | 7325 !(priv->config & (CFG_STATIC_ESSID |
4826 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) { 7326 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
4827 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n"); 7327 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
4828 return; 7328 return 0;
4829 } 7329 }
4830 7330
7331 /* Protect our use of the network_list */
7332 spin_lock_irqsave(&priv->ieee->lock, flags);
4831 list_for_each_entry(network, &priv->ieee->network_list, list) 7333 list_for_each_entry(network, &priv->ieee->network_list, list)
4832 ipw_best_network(priv, &match, network, 0); 7334 ipw_best_network(priv, &match, network, 0);
4833 7335
@@ -4838,6 +7340,7 @@ static void ipw_associate(void *data)
4838 priv->ieee->iw_mode == IW_MODE_ADHOC && 7340 priv->ieee->iw_mode == IW_MODE_ADHOC &&
4839 priv->config & CFG_ADHOC_CREATE && 7341 priv->config & CFG_ADHOC_CREATE &&
4840 priv->config & CFG_STATIC_ESSID && 7342 priv->config & CFG_STATIC_ESSID &&
7343 priv->config & CFG_STATIC_CHANNEL &&
4841 !list_empty(&priv->ieee->network_free_list)) { 7344 !list_empty(&priv->ieee->network_free_list)) {
4842 element = priv->ieee->network_free_list.next; 7345 element = priv->ieee->network_free_list.next;
4843 network = list_entry(element, struct ieee80211_network, list); 7346 network = list_entry(element, struct ieee80211_network, list);
@@ -4846,25 +7349,83 @@ static void ipw_associate(void *data)
4846 list_del(element); 7349 list_del(element);
4847 list_add_tail(&network->list, &priv->ieee->network_list); 7350 list_add_tail(&network->list, &priv->ieee->network_list);
4848 } 7351 }
7352 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4849 7353
4850 /* If we reached the end of the list, then we don't have any valid 7354 /* If we reached the end of the list, then we don't have any valid
4851 * matching APs */ 7355 * matching APs */
4852 if (!network) { 7356 if (!network) {
4853 ipw_debug_config(priv); 7357 ipw_debug_config(priv);
4854 7358
4855 queue_delayed_work(priv->workqueue, &priv->request_scan, 7359 if (!(priv->status & STATUS_SCANNING)) {
4856 SCAN_INTERVAL); 7360 if (!(priv->config & CFG_SPEED_SCAN))
7361 queue_delayed_work(priv->workqueue,
7362 &priv->request_scan,
7363 SCAN_INTERVAL);
7364 else
7365 queue_work(priv->workqueue,
7366 &priv->request_scan);
7367 }
4857 7368
4858 return; 7369 return 0;
4859 } 7370 }
4860 7371
4861 ipw_associate_network(priv, network, rates, 0); 7372 ipw_associate_network(priv, network, rates, 0);
7373
7374 return 1;
4862} 7375}
4863 7376
4864static inline void ipw_handle_data_packet(struct ipw_priv *priv, 7377static void ipw_bg_associate(void *data)
4865 struct ipw_rx_mem_buffer *rxb,
4866 struct ieee80211_rx_stats *stats)
4867{ 7378{
7379 struct ipw_priv *priv = data;
7380 down(&priv->sem);
7381 ipw_associate(data);
7382 up(&priv->sem);
7383}
7384
7385static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7386 struct sk_buff *skb)
7387{
7388 struct ieee80211_hdr *hdr;
7389 u16 fc;
7390
7391 hdr = (struct ieee80211_hdr *)skb->data;
7392 fc = le16_to_cpu(hdr->frame_ctl);
7393 if (!(fc & IEEE80211_FCTL_PROTECTED))
7394 return;
7395
7396 fc &= ~IEEE80211_FCTL_PROTECTED;
7397 hdr->frame_ctl = cpu_to_le16(fc);
7398 switch (priv->ieee->sec.level) {
7399 case SEC_LEVEL_3:
7400 /* Remove CCMP HDR */
7401 memmove(skb->data + IEEE80211_3ADDR_LEN,
7402 skb->data + IEEE80211_3ADDR_LEN + 8,
7403 skb->len - IEEE80211_3ADDR_LEN - 8);
7404 skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */
7405 break;
7406 case SEC_LEVEL_2:
7407 break;
7408 case SEC_LEVEL_1:
7409 /* Remove IV */
7410 memmove(skb->data + IEEE80211_3ADDR_LEN,
7411 skb->data + IEEE80211_3ADDR_LEN + 4,
7412 skb->len - IEEE80211_3ADDR_LEN - 4);
7413 skb_trim(skb, skb->len - 8); /* IV + ICV */
7414 break;
7415 case SEC_LEVEL_0:
7416 break;
7417 default:
7418 printk(KERN_ERR "Unknow security level %d\n",
7419 priv->ieee->sec.level);
7420 break;
7421 }
7422}
7423
7424static void ipw_handle_data_packet(struct ipw_priv *priv,
7425 struct ipw_rx_mem_buffer *rxb,
7426 struct ieee80211_rx_stats *stats)
7427{
7428 struct ieee80211_hdr_4addr *hdr;
4868 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data; 7429 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
4869 7430
4870 /* We received data from the HW, so stop the watchdog */ 7431 /* We received data from the HW, so stop the watchdog */
@@ -4872,7 +7433,7 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4872 7433
4873 /* We only process data packets if the 7434 /* We only process data packets if the
4874 * interface is open */ 7435 * interface is open */
4875 if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) > 7436 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
4876 skb_tailroom(rxb->skb))) { 7437 skb_tailroom(rxb->skb))) {
4877 priv->ieee->stats.rx_errors++; 7438 priv->ieee->stats.rx_errors++;
4878 priv->wstats.discard.misc++; 7439 priv->wstats.discard.misc++;
@@ -4889,14 +7450,351 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4889 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data)); 7450 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
4890 7451
4891 /* Set the size of the skb to the size of the frame */ 7452 /* Set the size of the skb to the size of the frame */
4892 skb_put(rxb->skb, pkt->u.frame.length); 7453 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
4893 7454
4894 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); 7455 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
4895 7456
7457 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
7458 hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
7459 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
7460 ((is_multicast_ether_addr(hdr->addr1) ||
7461 is_broadcast_ether_addr(hdr->addr1)) ?
7462 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
7463 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7464
4896 if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) 7465 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
4897 priv->ieee->stats.rx_errors++; 7466 priv->ieee->stats.rx_errors++;
4898 else /* ieee80211_rx succeeded, so it now owns the SKB */ 7467 else { /* ieee80211_rx succeeded, so it now owns the SKB */
4899 rxb->skb = NULL; 7468 rxb->skb = NULL;
7469 __ipw_led_activity_on(priv);
7470 }
7471}
7472
7473#ifdef CONFIG_IEEE80211_RADIOTAP
7474static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7475 struct ipw_rx_mem_buffer *rxb,
7476 struct ieee80211_rx_stats *stats)
7477{
7478 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7479 struct ipw_rx_frame *frame = &pkt->u.frame;
7480
7481 /* initial pull of some data */
7482 u16 received_channel = frame->received_channel;
7483 u8 antennaAndPhy = frame->antennaAndPhy;
7484 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */
7485 u16 pktrate = frame->rate;
7486
7487 /* Magic struct that slots into the radiotap header -- no reason
7488 * to build this manually element by element, we can write it much
7489 * more efficiently than we can parse it. ORDER MATTERS HERE */
7490 struct ipw_rt_hdr {
7491 struct ieee80211_radiotap_header rt_hdr;
7492 u8 rt_flags; /* radiotap packet flags */
7493 u8 rt_rate; /* rate in 500kb/s */
7494 u16 rt_channel; /* channel in mhz */
7495 u16 rt_chbitmask; /* channel bitfield */
7496 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
7497 u8 rt_antenna; /* antenna number */
7498 } *ipw_rt;
7499
7500 short len = le16_to_cpu(pkt->u.frame.length);
7501
7502 /* We received data from the HW, so stop the watchdog */
7503 priv->net_dev->trans_start = jiffies;
7504
7505 /* We only process data packets if the
7506 * interface is open */
7507 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7508 skb_tailroom(rxb->skb))) {
7509 priv->ieee->stats.rx_errors++;
7510 priv->wstats.discard.misc++;
7511 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7512 return;
7513 } else if (unlikely(!netif_running(priv->net_dev))) {
7514 priv->ieee->stats.rx_dropped++;
7515 priv->wstats.discard.misc++;
7516 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7517 return;
7518 }
7519
7520 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7521 * that now */
7522 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7523 /* FIXME: Should alloc bigger skb instead */
7524 priv->ieee->stats.rx_dropped++;
7525 priv->wstats.discard.misc++;
7526 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7527 return;
7528 }
7529
7530 /* copy the frame itself */
7531 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
7532 rxb->skb->data + IPW_RX_FRAME_SIZE, len);
7533
7534 /* Zero the radiotap static buffer ... We only need to zero the bytes NOT
7535 * part of our real header, saves a little time.
7536 *
7537 * No longer necessary since we fill in all our data. Purge before merging
7538 * patch officially.
7539 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
7540 * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
7541 */
7542
7543 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
7544
7545 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7546 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
7547 ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total header+data */
7548
7549 /* Big bitfield of all the fields we provide in radiotap */
7550 ipw_rt->rt_hdr.it_present =
7551 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7552 (1 << IEEE80211_RADIOTAP_RATE) |
7553 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7554 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7555 (1 << IEEE80211_RADIOTAP_ANTENNA));
7556
7557 /* Zero the flags, we'll add to them as we go */
7558 ipw_rt->rt_flags = 0;
7559
7560 /* Convert signal to DBM */
7561 ipw_rt->rt_dbmsignal = antsignal;
7562
7563 /* Convert the channel data and set the flags */
7564 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
7565 if (received_channel > 14) { /* 802.11a */
7566 ipw_rt->rt_chbitmask =
7567 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7568 } else if (antennaAndPhy & 32) { /* 802.11b */
7569 ipw_rt->rt_chbitmask =
7570 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7571 } else { /* 802.11g */
7572 ipw_rt->rt_chbitmask =
7573 (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7574 }
7575
7576 /* set the rate in multiples of 500k/s */
7577 switch (pktrate) {
7578 case IPW_TX_RATE_1MB:
7579 ipw_rt->rt_rate = 2;
7580 break;
7581 case IPW_TX_RATE_2MB:
7582 ipw_rt->rt_rate = 4;
7583 break;
7584 case IPW_TX_RATE_5MB:
7585 ipw_rt->rt_rate = 10;
7586 break;
7587 case IPW_TX_RATE_6MB:
7588 ipw_rt->rt_rate = 12;
7589 break;
7590 case IPW_TX_RATE_9MB:
7591 ipw_rt->rt_rate = 18;
7592 break;
7593 case IPW_TX_RATE_11MB:
7594 ipw_rt->rt_rate = 22;
7595 break;
7596 case IPW_TX_RATE_12MB:
7597 ipw_rt->rt_rate = 24;
7598 break;
7599 case IPW_TX_RATE_18MB:
7600 ipw_rt->rt_rate = 36;
7601 break;
7602 case IPW_TX_RATE_24MB:
7603 ipw_rt->rt_rate = 48;
7604 break;
7605 case IPW_TX_RATE_36MB:
7606 ipw_rt->rt_rate = 72;
7607 break;
7608 case IPW_TX_RATE_48MB:
7609 ipw_rt->rt_rate = 96;
7610 break;
7611 case IPW_TX_RATE_54MB:
7612 ipw_rt->rt_rate = 108;
7613 break;
7614 default:
7615 ipw_rt->rt_rate = 0;
7616 break;
7617 }
7618
7619 /* antenna number */
7620 ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */
7621
7622 /* set the preamble flag if we have it */
7623 if ((antennaAndPhy & 64))
7624 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7625
7626 /* Set the size of the skb to the size of the frame */
7627 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
7628
7629 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7630
7631 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
7632 priv->ieee->stats.rx_errors++;
7633 else { /* ieee80211_rx succeeded, so it now owns the SKB */
7634 rxb->skb = NULL;
7635 /* no LED during capture */
7636 }
7637}
7638#endif
7639
7640static inline int is_network_packet(struct ipw_priv *priv,
7641 struct ieee80211_hdr_4addr *header)
7642{
7643 /* Filter incoming packets to determine if they are targetted toward
7644 * this network, discarding packets coming from ourselves */
7645 switch (priv->ieee->iw_mode) {
7646 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
7647 /* packets from our adapter are dropped (echo) */
7648 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
7649 return 0;
7650
7651 /* {broad,multi}cast packets to our BSSID go through */
7652 if (is_multicast_ether_addr(header->addr1) ||
7653 is_broadcast_ether_addr(header->addr1))
7654 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
7655
7656 /* packets to our adapter go through */
7657 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7658 ETH_ALEN);
7659
7660 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
7661 /* packets from our adapter are dropped (echo) */
7662 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
7663 return 0;
7664
7665 /* {broad,multi}cast packets to our BSS go through */
7666 if (is_multicast_ether_addr(header->addr1) ||
7667 is_broadcast_ether_addr(header->addr1))
7668 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
7669
7670 /* packets to our adapter go through */
7671 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7672 ETH_ALEN);
7673 }
7674
7675 return 1;
7676}
7677
7678#define IPW_PACKET_RETRY_TIME HZ
7679
7680static inline int is_duplicate_packet(struct ipw_priv *priv,
7681 struct ieee80211_hdr_4addr *header)
7682{
7683 u16 sc = le16_to_cpu(header->seq_ctl);
7684 u16 seq = WLAN_GET_SEQ_SEQ(sc);
7685 u16 frag = WLAN_GET_SEQ_FRAG(sc);
7686 u16 *last_seq, *last_frag;
7687 unsigned long *last_time;
7688
7689 switch (priv->ieee->iw_mode) {
7690 case IW_MODE_ADHOC:
7691 {
7692 struct list_head *p;
7693 struct ipw_ibss_seq *entry = NULL;
7694 u8 *mac = header->addr2;
7695 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
7696
7697 __list_for_each(p, &priv->ibss_mac_hash[index]) {
7698 entry =
7699 list_entry(p, struct ipw_ibss_seq, list);
7700 if (!memcmp(entry->mac, mac, ETH_ALEN))
7701 break;
7702 }
7703 if (p == &priv->ibss_mac_hash[index]) {
7704 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
7705 if (!entry) {
7706 IPW_ERROR
7707 ("Cannot malloc new mac entry\n");
7708 return 0;
7709 }
7710 memcpy(entry->mac, mac, ETH_ALEN);
7711 entry->seq_num = seq;
7712 entry->frag_num = frag;
7713 entry->packet_time = jiffies;
7714 list_add(&entry->list,
7715 &priv->ibss_mac_hash[index]);
7716 return 0;
7717 }
7718 last_seq = &entry->seq_num;
7719 last_frag = &entry->frag_num;
7720 last_time = &entry->packet_time;
7721 break;
7722 }
7723 case IW_MODE_INFRA:
7724 last_seq = &priv->last_seq_num;
7725 last_frag = &priv->last_frag_num;
7726 last_time = &priv->last_packet_time;
7727 break;
7728 default:
7729 return 0;
7730 }
7731 if ((*last_seq == seq) &&
7732 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
7733 if (*last_frag == frag)
7734 goto drop;
7735 if (*last_frag + 1 != frag)
7736 /* out-of-order fragment */
7737 goto drop;
7738 } else
7739 *last_seq = seq;
7740
7741 *last_frag = frag;
7742 *last_time = jiffies;
7743 return 0;
7744
7745 drop:
7746 /* Comment this line now since we observed the card receives
7747 * duplicate packets but the FCTL_RETRY bit is not set in the
7748 * IBSS mode with fragmentation enabled.
7749 BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
7750 return 1;
7751}
7752
7753static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
7754 struct ipw_rx_mem_buffer *rxb,
7755 struct ieee80211_rx_stats *stats)
7756{
7757 struct sk_buff *skb = rxb->skb;
7758 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
7759 struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
7760 (skb->data + IPW_RX_FRAME_SIZE);
7761
7762 ieee80211_rx_mgt(priv->ieee, header, stats);
7763
7764 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
7765 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7766 IEEE80211_STYPE_PROBE_RESP) ||
7767 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7768 IEEE80211_STYPE_BEACON))) {
7769 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
7770 ipw_add_station(priv, header->addr2);
7771 }
7772
7773 if (priv->config & CFG_NET_STATS) {
7774 IPW_DEBUG_HC("sending stat packet\n");
7775
7776 /* Set the size of the skb to the size of the full
7777 * ipw header and 802.11 frame */
7778 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
7779 IPW_RX_FRAME_SIZE);
7780
7781 /* Advance past the ipw packet header to the 802.11 frame */
7782 skb_pull(skb, IPW_RX_FRAME_SIZE);
7783
7784 /* Push the ieee80211_rx_stats before the 802.11 frame */
7785 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
7786
7787 skb->dev = priv->ieee->dev;
7788
7789 /* Point raw at the ieee80211_stats */
7790 skb->mac.raw = skb->data;
7791
7792 skb->pkt_type = PACKET_OTHERHOST;
7793 skb->protocol = __constant_htons(ETH_P_80211_STATS);
7794 memset(skb->cb, 0, sizeof(rxb->skb->cb));
7795 netif_rx(skb);
7796 rxb->skb = NULL;
7797 }
4900} 7798}
4901 7799
4902/* 7800/*
@@ -4912,8 +7810,8 @@ static void ipw_rx(struct ipw_priv *priv)
4912 u32 r, w, i; 7810 u32 r, w, i;
4913 u8 network_packet; 7811 u8 network_packet;
4914 7812
4915 r = ipw_read32(priv, CX2_RX_READ_INDEX); 7813 r = ipw_read32(priv, IPW_RX_READ_INDEX);
4916 w = ipw_read32(priv, CX2_RX_WRITE_INDEX); 7814 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
4917 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE; 7815 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
4918 7816
4919 while (i != r) { 7817 while (i != r) {
@@ -4927,7 +7825,7 @@ static void ipw_rx(struct ipw_priv *priv)
4927 priv->rxq->queue[i] = NULL; 7825 priv->rxq->queue[i] = NULL;
4928 7826
4929 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, 7827 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
4930 CX2_RX_BUF_SIZE, 7828 IPW_RX_BUF_SIZE,
4931 PCI_DMA_FROMDEVICE); 7829 PCI_DMA_FROMDEVICE);
4932 7830
4933 pkt = (struct ipw_rx_packet *)rxb->skb->data; 7831 pkt = (struct ipw_rx_packet *)rxb->skb->data;
@@ -4938,9 +7836,13 @@ static void ipw_rx(struct ipw_priv *priv)
4938 switch (pkt->header.message_type) { 7836 switch (pkt->header.message_type) {
4939 case RX_FRAME_TYPE: /* 802.11 frame */ { 7837 case RX_FRAME_TYPE: /* 802.11 frame */ {
4940 struct ieee80211_rx_stats stats = { 7838 struct ieee80211_rx_stats stats = {
4941 .rssi = pkt->u.frame.rssi_dbm - 7839 .rssi =
7840 le16_to_cpu(pkt->u.frame.rssi_dbm) -
4942 IPW_RSSI_TO_DBM, 7841 IPW_RSSI_TO_DBM,
4943 .signal = pkt->u.frame.signal, 7842 .signal =
7843 le16_to_cpu(pkt->u.frame.signal),
7844 .noise =
7845 le16_to_cpu(pkt->u.frame.noise),
4944 .rate = pkt->u.frame.rate, 7846 .rate = pkt->u.frame.rate,
4945 .mac_time = jiffies, 7847 .mac_time = jiffies,
4946 .received_channel = 7848 .received_channel =
@@ -4950,22 +7852,30 @@ static void ipw_rx(struct ipw_priv *priv)
4950 control & (1 << 0)) ? 7852 control & (1 << 0)) ?
4951 IEEE80211_24GHZ_BAND : 7853 IEEE80211_24GHZ_BAND :
4952 IEEE80211_52GHZ_BAND, 7854 IEEE80211_52GHZ_BAND,
4953 .len = pkt->u.frame.length, 7855 .len = le16_to_cpu(pkt->u.frame.length),
4954 }; 7856 };
4955 7857
4956 if (stats.rssi != 0) 7858 if (stats.rssi != 0)
4957 stats.mask |= IEEE80211_STATMASK_RSSI; 7859 stats.mask |= IEEE80211_STATMASK_RSSI;
4958 if (stats.signal != 0) 7860 if (stats.signal != 0)
4959 stats.mask |= IEEE80211_STATMASK_SIGNAL; 7861 stats.mask |= IEEE80211_STATMASK_SIGNAL;
7862 if (stats.noise != 0)
7863 stats.mask |= IEEE80211_STATMASK_NOISE;
4960 if (stats.rate != 0) 7864 if (stats.rate != 0)
4961 stats.mask |= IEEE80211_STATMASK_RATE; 7865 stats.mask |= IEEE80211_STATMASK_RATE;
4962 7866
4963 priv->rx_packets++; 7867 priv->rx_packets++;
4964 7868
4965#ifdef CONFIG_IPW_PROMISC 7869#ifdef CONFIG_IPW2200_MONITOR
4966 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 7870 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7871#ifdef CONFIG_IEEE80211_RADIOTAP
7872 ipw_handle_data_packet_monitor(priv,
7873 rxb,
7874 &stats);
7875#else
4967 ipw_handle_data_packet(priv, rxb, 7876 ipw_handle_data_packet(priv, rxb,
4968 &stats); 7877 &stats);
7878#endif
4969 break; 7879 break;
4970 } 7880 }
4971#endif 7881#endif
@@ -4979,35 +7889,9 @@ static void ipw_rx(struct ipw_priv *priv)
4979 * correctly -- we should probably use the 7889 * correctly -- we should probably use the
4980 * frame control of the packet and disregard 7890 * frame control of the packet and disregard
4981 * the current iw_mode */ 7891 * the current iw_mode */
4982 switch (priv->ieee->iw_mode) {
4983 case IW_MODE_ADHOC:
4984 network_packet =
4985 !memcmp(header->addr1,
4986 priv->net_dev->dev_addr,
4987 ETH_ALEN) ||
4988 !memcmp(header->addr3,
4989 priv->bssid, ETH_ALEN) ||
4990 is_broadcast_ether_addr(header->
4991 addr1)
4992 || is_multicast_ether_addr(header->
4993 addr1);
4994 break;
4995
4996 case IW_MODE_INFRA:
4997 default:
4998 network_packet =
4999 !memcmp(header->addr3,
5000 priv->bssid, ETH_ALEN) ||
5001 !memcmp(header->addr1,
5002 priv->net_dev->dev_addr,
5003 ETH_ALEN) ||
5004 is_broadcast_ether_addr(header->
5005 addr1)
5006 || is_multicast_ether_addr(header->
5007 addr1);
5008 break;
5009 }
5010 7892
7893 network_packet =
7894 is_network_packet(priv, header);
5011 if (network_packet && priv->assoc_network) { 7895 if (network_packet && priv->assoc_network) {
5012 priv->assoc_network->stats.rssi = 7896 priv->assoc_network->stats.rssi =
5013 stats.rssi; 7897 stats.rssi;
@@ -5017,9 +7901,10 @@ static void ipw_rx(struct ipw_priv *priv)
5017 } 7901 }
5018 7902
5019 IPW_DEBUG_RX("Frame: len=%u\n", 7903 IPW_DEBUG_RX("Frame: len=%u\n",
5020 pkt->u.frame.length); 7904 le16_to_cpu(pkt->u.frame.length));
5021 7905
5022 if (pkt->u.frame.length < frame_hdr_len(header)) { 7906 if (le16_to_cpu(pkt->u.frame.length) <
7907 frame_hdr_len(header)) {
5023 IPW_DEBUG_DROP 7908 IPW_DEBUG_DROP
5024 ("Received packet is too small. " 7909 ("Received packet is too small. "
5025 "Dropping.\n"); 7910 "Dropping.\n");
@@ -5028,34 +7913,22 @@ static void ipw_rx(struct ipw_priv *priv)
5028 break; 7913 break;
5029 } 7914 }
5030 7915
5031 switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { 7916 switch (WLAN_FC_GET_TYPE
7917 (le16_to_cpu(header->frame_ctl))) {
7918
5032 case IEEE80211_FTYPE_MGMT: 7919 case IEEE80211_FTYPE_MGMT:
5033 ieee80211_rx_mgt(priv->ieee, header, 7920 ipw_handle_mgmt_packet(priv, rxb,
5034 &stats); 7921 &stats);
5035 if (priv->ieee->iw_mode == IW_MODE_ADHOC
5036 &&
5037 ((WLAN_FC_GET_STYPE
5038 (header->frame_ctl) ==
5039 IEEE80211_STYPE_PROBE_RESP)
5040 ||
5041 (WLAN_FC_GET_STYPE
5042 (header->frame_ctl) ==
5043 IEEE80211_STYPE_BEACON))
5044 && !memcmp(header->addr3,
5045 priv->bssid, ETH_ALEN))
5046 ipw_add_station(priv,
5047 header->addr2);
5048 break; 7922 break;
5049 7923
5050 case IEEE80211_FTYPE_CTL: 7924 case IEEE80211_FTYPE_CTL:
5051 break; 7925 break;
5052 7926
5053 case IEEE80211_FTYPE_DATA: 7927 case IEEE80211_FTYPE_DATA:
5054 if (network_packet) 7928 if (unlikely(!network_packet ||
5055 ipw_handle_data_packet(priv, 7929 is_duplicate_packet(priv,
5056 rxb, 7930 header)))
5057 &stats); 7931 {
5058 else
5059 IPW_DEBUG_DROP("Dropping: " 7932 IPW_DEBUG_DROP("Dropping: "
5060 MAC_FMT ", " 7933 MAC_FMT ", "
5061 MAC_FMT ", " 7934 MAC_FMT ", "
@@ -5066,6 +7939,12 @@ static void ipw_rx(struct ipw_priv *priv)
5066 addr2), 7939 addr2),
5067 MAC_ARG(header-> 7940 MAC_ARG(header->
5068 addr3)); 7941 addr3));
7942 break;
7943 }
7944
7945 ipw_handle_data_packet(priv, rxb,
7946 &stats);
7947
5069 break; 7948 break;
5070 } 7949 }
5071 break; 7950 break;
@@ -5096,7 +7975,7 @@ static void ipw_rx(struct ipw_priv *priv)
5096 } 7975 }
5097 7976
5098 pci_unmap_single(priv->pci_dev, rxb->dma_addr, 7977 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
5099 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 7978 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
5100 list_add_tail(&rxb->list, &priv->rxq->rx_used); 7979 list_add_tail(&rxb->list, &priv->rxq->rx_used);
5101 7980
5102 i = (i + 1) % RX_QUEUE_SIZE; 7981 i = (i + 1) % RX_QUEUE_SIZE;
@@ -5108,128 +7987,129 @@ static void ipw_rx(struct ipw_priv *priv)
5108 ipw_rx_queue_restock(priv); 7987 ipw_rx_queue_restock(priv);
5109} 7988}
5110 7989
5111static void ipw_abort_scan(struct ipw_priv *priv) 7990#define DEFAULT_RTS_THRESHOLD 2304U
7991#define MIN_RTS_THRESHOLD 1U
7992#define MAX_RTS_THRESHOLD 2304U
7993#define DEFAULT_BEACON_INTERVAL 100U
7994#define DEFAULT_SHORT_RETRY_LIMIT 7U
7995#define DEFAULT_LONG_RETRY_LIMIT 4U
7996
7997static int ipw_sw_reset(struct ipw_priv *priv, int init)
5112{ 7998{
5113 int err; 7999 int band, modulation;
8000 int old_mode = priv->ieee->iw_mode;
5114 8001
5115 if (priv->status & STATUS_SCAN_ABORTING) { 8002 /* Initialize module parameter values here */
5116 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n"); 8003 priv->config = 0;
5117 return;
5118 }
5119 priv->status |= STATUS_SCAN_ABORTING;
5120 8004
5121 err = ipw_send_scan_abort(priv); 8005 /* We default to disabling the LED code as right now it causes
5122 if (err) 8006 * too many systems to lock up... */
5123 IPW_DEBUG_HC("Request to abort scan failed.\n"); 8007 if (!led)
5124} 8008 priv->config |= CFG_NO_LED;
5125 8009
5126static int ipw_request_scan(struct ipw_priv *priv) 8010 if (associate)
5127{ 8011 priv->config |= CFG_ASSOCIATE;
5128 struct ipw_scan_request_ext scan; 8012 else
5129 int channel_index = 0; 8013 IPW_DEBUG_INFO("Auto associate disabled.\n");
5130 int i, err, scan_type;
5131 8014
5132 if (priv->status & STATUS_EXIT_PENDING) { 8015 if (auto_create)
5133 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n"); 8016 priv->config |= CFG_ADHOC_CREATE;
5134 priv->status |= STATUS_SCAN_PENDING; 8017 else
5135 return 0; 8018 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
5136 }
5137 8019
5138 if (priv->status & STATUS_SCANNING) { 8020 if (disable) {
5139 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n"); 8021 priv->status |= STATUS_RF_KILL_SW;
5140 priv->status |= STATUS_SCAN_PENDING; 8022 IPW_DEBUG_INFO("Radio disabled.\n");
5141 ipw_abort_scan(priv);
5142 return 0;
5143 } 8023 }
5144 8024
5145 if (priv->status & STATUS_SCAN_ABORTING) { 8025 if (channel != 0) {
5146 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); 8026 priv->config |= CFG_STATIC_CHANNEL;
5147 priv->status |= STATUS_SCAN_PENDING; 8027 priv->channel = channel;
5148 return 0; 8028 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
8029 /* TODO: Validate that provided channel is in range */
5149 } 8030 }
8031#ifdef CONFIG_IPW_QOS
8032 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8033 burst_duration_CCK, burst_duration_OFDM);
8034#endif /* CONFIG_IPW_QOS */
5150 8035
5151 if (priv->status & STATUS_RF_KILL_MASK) { 8036 switch (mode) {
5152 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n"); 8037 case 1:
5153 priv->status |= STATUS_SCAN_PENDING; 8038 priv->ieee->iw_mode = IW_MODE_ADHOC;
5154 return 0; 8039 priv->net_dev->type = ARPHRD_ETHER;
8040
8041 break;
8042#ifdef CONFIG_IPW2200_MONITOR
8043 case 2:
8044 priv->ieee->iw_mode = IW_MODE_MONITOR;
8045#ifdef CONFIG_IEEE80211_RADIOTAP
8046 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8047#else
8048 priv->net_dev->type = ARPHRD_IEEE80211;
8049#endif
8050 break;
8051#endif
8052 default:
8053 case 0:
8054 priv->net_dev->type = ARPHRD_ETHER;
8055 priv->ieee->iw_mode = IW_MODE_INFRA;
8056 break;
5155 } 8057 }
5156 8058
5157 memset(&scan, 0, sizeof(scan)); 8059 if (hwcrypto) {
8060 priv->ieee->host_encrypt = 0;
8061 priv->ieee->host_encrypt_msdu = 0;
8062 priv->ieee->host_decrypt = 0;
8063 priv->ieee->host_mc_decrypt = 0;
8064 }
8065 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
5158 8066
5159 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20; 8067 /* IPW2200/2915 is abled to do hardware fragmentation. */
5160 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20; 8068 priv->ieee->host_open_frag = 0;
5161 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
5162
5163 scan.full_scan_index = ieee80211_get_scans(priv->ieee);
5164 /* If we are roaming, then make this a directed scan for the current
5165 * network. Otherwise, ensure that every other scan is a fast
5166 * channel hop scan */
5167 if ((priv->status & STATUS_ROAMING)
5168 || (!(priv->status & STATUS_ASSOCIATED)
5169 && (priv->config & CFG_STATIC_ESSID)
5170 && (scan.full_scan_index % 2))) {
5171 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5172 if (err) {
5173 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
5174 return err;
5175 }
5176 8069
5177 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; 8070 if ((priv->pci_dev->device == 0x4223) ||
8071 (priv->pci_dev->device == 0x4224)) {
8072 if (init)
8073 printk(KERN_INFO DRV_NAME
8074 ": Detected Intel PRO/Wireless 2915ABG Network "
8075 "Connection\n");
8076 priv->ieee->abg_true = 1;
8077 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
8078 modulation = IEEE80211_OFDM_MODULATION |
8079 IEEE80211_CCK_MODULATION;
8080 priv->adapter = IPW_2915ABG;
8081 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
5178 } else { 8082 } else {
5179 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN; 8083 if (init)
5180 } 8084 printk(KERN_INFO DRV_NAME
5181 8085 ": Detected Intel PRO/Wireless 2200BG Network "
5182 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { 8086 "Connection\n");
5183 int start = channel_index;
5184 for (i = 0; i < MAX_A_CHANNELS; i++) {
5185 if (band_a_active_channel[i] == 0)
5186 break;
5187 if ((priv->status & STATUS_ASSOCIATED) &&
5188 band_a_active_channel[i] == priv->channel)
5189 continue;
5190 channel_index++;
5191 scan.channels_list[channel_index] =
5192 band_a_active_channel[i];
5193 ipw_set_scan_type(&scan, channel_index, scan_type);
5194 }
5195 8087
5196 if (start != channel_index) { 8088 priv->ieee->abg_true = 0;
5197 scan.channels_list[start] = (u8) (IPW_A_MODE << 6) | 8089 band = IEEE80211_24GHZ_BAND;
5198 (channel_index - start); 8090 modulation = IEEE80211_OFDM_MODULATION |
5199 channel_index++; 8091 IEEE80211_CCK_MODULATION;
5200 } 8092 priv->adapter = IPW_2200BG;
8093 priv->ieee->mode = IEEE_G | IEEE_B;
5201 } 8094 }
5202 8095
5203 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) { 8096 priv->ieee->freq_band = band;
5204 int start = channel_index; 8097 priv->ieee->modulation = modulation;
5205 for (i = 0; i < MAX_B_CHANNELS; i++) {
5206 if (band_b_active_channel[i] == 0)
5207 break;
5208 if ((priv->status & STATUS_ASSOCIATED) &&
5209 band_b_active_channel[i] == priv->channel)
5210 continue;
5211 channel_index++;
5212 scan.channels_list[channel_index] =
5213 band_b_active_channel[i];
5214 ipw_set_scan_type(&scan, channel_index, scan_type);
5215 }
5216 8098
5217 if (start != channel_index) { 8099 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
5218 scan.channels_list[start] = (u8) (IPW_B_MODE << 6) |
5219 (channel_index - start);
5220 }
5221 }
5222 8100
5223 err = ipw_send_scan_request_ext(priv, &scan); 8101 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
5224 if (err) { 8102 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
5225 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
5226 return -EIO;
5227 }
5228 8103
5229 priv->status |= STATUS_SCANNING; 8104 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5230 priv->status &= ~STATUS_SCAN_PENDING; 8105 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
8106 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
5231 8107
5232 return 0; 8108 /* If power management is turned on, default to AC mode */
8109 priv->power_mode = IPW_POWER_AC;
8110 priv->tx_power = IPW_TX_POWER_DEFAULT;
8111
8112 return old_mode == priv->ieee->iw_mode;
5233} 8113}
5234 8114
5235/* 8115/*
@@ -5247,12 +8127,16 @@ static int ipw_wx_get_name(struct net_device *dev,
5247 union iwreq_data *wrqu, char *extra) 8127 union iwreq_data *wrqu, char *extra)
5248{ 8128{
5249 struct ipw_priv *priv = ieee80211_priv(dev); 8129 struct ipw_priv *priv = ieee80211_priv(dev);
5250 if (!(priv->status & STATUS_ASSOCIATED)) 8130 down(&priv->sem);
8131 if (priv->status & STATUS_RF_KILL_MASK)
8132 strcpy(wrqu->name, "radio off");
8133 else if (!(priv->status & STATUS_ASSOCIATED))
5251 strcpy(wrqu->name, "unassociated"); 8134 strcpy(wrqu->name, "unassociated");
5252 else 8135 else
5253 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", 8136 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
5254 ipw_modes[priv->assoc_request.ieee_mode]); 8137 ipw_modes[priv->assoc_request.ieee_mode]);
5255 IPW_DEBUG_WX("Name: %s\n", wrqu->name); 8138 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
8139 up(&priv->sem);
5256 return 0; 8140 return 0;
5257} 8141}
5258 8142
@@ -5261,13 +8145,9 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5261 if (channel == 0) { 8145 if (channel == 0) {
5262 IPW_DEBUG_INFO("Setting channel to ANY (0)\n"); 8146 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
5263 priv->config &= ~CFG_STATIC_CHANNEL; 8147 priv->config &= ~CFG_STATIC_CHANNEL;
5264 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8148 IPW_DEBUG_ASSOC("Attempting to associate with new "
5265 STATUS_ASSOCIATING))) { 8149 "parameters.\n");
5266 IPW_DEBUG_ASSOC("Attempting to associate with new " 8150 ipw_associate(priv);
5267 "parameters.\n");
5268 ipw_associate(priv);
5269 }
5270
5271 return 0; 8151 return 0;
5272 } 8152 }
5273 8153
@@ -5282,14 +8162,32 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5282 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel); 8162 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
5283 priv->channel = channel; 8163 priv->channel = channel;
5284 8164
5285 /* If we are currently associated, or trying to associate 8165#ifdef CONFIG_IPW2200_MONITOR
5286 * then see if this is a new channel (causing us to disassociate) */ 8166 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5287 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8167 int i;
5288 IPW_DEBUG_ASSOC("Disassociating due to channel change.\n"); 8168 if (priv->status & STATUS_SCANNING) {
5289 ipw_disassociate(priv); 8169 IPW_DEBUG_SCAN("Scan abort triggered due to "
5290 } else { 8170 "channel change.\n");
5291 ipw_associate(priv); 8171 ipw_abort_scan(priv);
8172 }
8173
8174 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
8175 udelay(10);
8176
8177 if (priv->status & STATUS_SCANNING)
8178 IPW_DEBUG_SCAN("Still scanning...\n");
8179 else
8180 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
8181 1000 - i);
8182
8183 return 0;
5292 } 8184 }
8185#endif /* CONFIG_IPW2200_MONITOR */
8186
8187 /* Network configuration changed -- force [re]association */
8188 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
8189 if (!ipw_disassociate(priv))
8190 ipw_associate(priv);
5293 8191
5294 return 0; 8192 return 0;
5295} 8193}
@@ -5299,29 +8197,48 @@ static int ipw_wx_set_freq(struct net_device *dev,
5299 union iwreq_data *wrqu, char *extra) 8197 union iwreq_data *wrqu, char *extra)
5300{ 8198{
5301 struct ipw_priv *priv = ieee80211_priv(dev); 8199 struct ipw_priv *priv = ieee80211_priv(dev);
8200 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5302 struct iw_freq *fwrq = &wrqu->freq; 8201 struct iw_freq *fwrq = &wrqu->freq;
5303 8202 int ret = 0, i;
8203 u8 channel, flags;
8204 int band;
8205
8206 if (fwrq->m == 0) {
8207 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
8208 down(&priv->sem);
8209 ret = ipw_set_channel(priv, 0);
8210 up(&priv->sem);
8211 return ret;
8212 }
5304 /* if setting by freq convert to channel */ 8213 /* if setting by freq convert to channel */
5305 if (fwrq->e == 1) { 8214 if (fwrq->e == 1) {
5306 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) { 8215 channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
5307 int f = fwrq->m / 100000; 8216 if (channel == 0)
5308 int c = 0; 8217 return -EINVAL;
8218 } else
8219 channel = fwrq->m;
8220
8221 if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
8222 return -EINVAL;
5309 8223
5310 while ((c < REG_MAX_CHANNEL) && 8224 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5311 (f != ipw_frequencies[c])) 8225 i = ipw_channel_to_index(priv->ieee, channel);
5312 c++; 8226 if (i == -1)
8227 return -EINVAL;
5313 8228
5314 /* hack to fall through */ 8229 flags = (band == IEEE80211_24GHZ_BAND) ?
5315 fwrq->e = 0; 8230 geo->bg[i].flags : geo->a[i].flags;
5316 fwrq->m = c + 1; 8231 if (flags & IEEE80211_CH_PASSIVE_ONLY) {
8232 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
8233 return -EINVAL;
5317 } 8234 }
5318 } 8235 }
5319 8236
5320 if (fwrq->e > 0 || fwrq->m > 1000)
5321 return -EOPNOTSUPP;
5322
5323 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 8237 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
5324 return ipw_set_channel(priv, (u8) fwrq->m); 8238 down(&priv->sem);
8239 ret = ipw_set_channel(priv, channel);
8240 up(&priv->sem);
8241 return ret;
5325} 8242}
5326 8243
5327static int ipw_wx_get_freq(struct net_device *dev, 8244static int ipw_wx_get_freq(struct net_device *dev,
@@ -5334,12 +8251,14 @@ static int ipw_wx_get_freq(struct net_device *dev,
5334 8251
5335 /* If we are associated, trying to associate, or have a statically 8252 /* If we are associated, trying to associate, or have a statically
5336 * configured CHANNEL then return that; otherwise return ANY */ 8253 * configured CHANNEL then return that; otherwise return ANY */
8254 down(&priv->sem);
5337 if (priv->config & CFG_STATIC_CHANNEL || 8255 if (priv->config & CFG_STATIC_CHANNEL ||
5338 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) 8256 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
5339 wrqu->freq.m = priv->channel; 8257 wrqu->freq.m = priv->channel;
5340 else 8258 else
5341 wrqu->freq.m = 0; 8259 wrqu->freq.m = 0;
5342 8260
8261 up(&priv->sem);
5343 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 8262 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
5344 return 0; 8263 return 0;
5345} 8264}
@@ -5353,11 +8272,8 @@ static int ipw_wx_set_mode(struct net_device *dev,
5353 8272
5354 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode); 8273 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
5355 8274
5356 if (wrqu->mode == priv->ieee->iw_mode)
5357 return 0;
5358
5359 switch (wrqu->mode) { 8275 switch (wrqu->mode) {
5360#ifdef CONFIG_IPW_PROMISC 8276#ifdef CONFIG_IPW2200_MONITOR
5361 case IW_MODE_MONITOR: 8277 case IW_MODE_MONITOR:
5362#endif 8278#endif
5363 case IW_MODE_ADHOC: 8279 case IW_MODE_ADHOC:
@@ -5369,31 +8285,33 @@ static int ipw_wx_set_mode(struct net_device *dev,
5369 default: 8285 default:
5370 return -EINVAL; 8286 return -EINVAL;
5371 } 8287 }
8288 if (wrqu->mode == priv->ieee->iw_mode)
8289 return 0;
8290
8291 down(&priv->sem);
8292
8293 ipw_sw_reset(priv, 0);
5372 8294
5373#ifdef CONFIG_IPW_PROMISC 8295#ifdef CONFIG_IPW2200_MONITOR
5374 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8296 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5375 priv->net_dev->type = ARPHRD_ETHER; 8297 priv->net_dev->type = ARPHRD_ETHER;
5376 8298
5377 if (wrqu->mode == IW_MODE_MONITOR) 8299 if (wrqu->mode == IW_MODE_MONITOR)
8300#ifdef CONFIG_IEEE80211_RADIOTAP
8301 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8302#else
5378 priv->net_dev->type = ARPHRD_IEEE80211; 8303 priv->net_dev->type = ARPHRD_IEEE80211;
5379#endif /* CONFIG_IPW_PROMISC */ 8304#endif
8305#endif /* CONFIG_IPW2200_MONITOR */
5380 8306
5381#ifdef CONFIG_PM
5382 /* Free the existing firmware and reset the fw_loaded 8307 /* Free the existing firmware and reset the fw_loaded
5383 * flag so ipw_load() will bring in the new firmawre */ 8308 * flag so ipw_load() will bring in the new firmawre */
5384 if (fw_loaded) { 8309 free_firmware();
5385 fw_loaded = 0;
5386 }
5387
5388 release_firmware(bootfw);
5389 release_firmware(ucode);
5390 release_firmware(firmware);
5391 bootfw = ucode = firmware = NULL;
5392#endif
5393 8310
5394 priv->ieee->iw_mode = wrqu->mode; 8311 priv->ieee->iw_mode = wrqu->mode;
5395 ipw_adapter_restart(priv);
5396 8312
8313 queue_work(priv->workqueue, &priv->adapter_restart);
8314 up(&priv->sem);
5397 return err; 8315 return err;
5398} 8316}
5399 8317
@@ -5402,20 +8320,13 @@ static int ipw_wx_get_mode(struct net_device *dev,
5402 union iwreq_data *wrqu, char *extra) 8320 union iwreq_data *wrqu, char *extra)
5403{ 8321{
5404 struct ipw_priv *priv = ieee80211_priv(dev); 8322 struct ipw_priv *priv = ieee80211_priv(dev);
5405 8323 down(&priv->sem);
5406 wrqu->mode = priv->ieee->iw_mode; 8324 wrqu->mode = priv->ieee->iw_mode;
5407 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode); 8325 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
5408 8326 up(&priv->sem);
5409 return 0; 8327 return 0;
5410} 8328}
5411 8329
5412#define DEFAULT_RTS_THRESHOLD 2304U
5413#define MIN_RTS_THRESHOLD 1U
5414#define MAX_RTS_THRESHOLD 2304U
5415#define DEFAULT_BEACON_INTERVAL 100U
5416#define DEFAULT_SHORT_RETRY_LIMIT 7U
5417#define DEFAULT_LONG_RETRY_LIMIT 4U
5418
5419/* Values are in microsecond */ 8330/* Values are in microsecond */
5420static const s32 timeout_duration[] = { 8331static const s32 timeout_duration[] = {
5421 350000, 8332 350000,
@@ -5439,8 +8350,8 @@ static int ipw_wx_get_range(struct net_device *dev,
5439{ 8350{
5440 struct ipw_priv *priv = ieee80211_priv(dev); 8351 struct ipw_priv *priv = ieee80211_priv(dev);
5441 struct iw_range *range = (struct iw_range *)extra; 8352 struct iw_range *range = (struct iw_range *)extra;
5442 u16 val; 8353 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5443 int i; 8354 int i = 0, j;
5444 8355
5445 wrqu->data.length = sizeof(*range); 8356 wrqu->data.length = sizeof(*range);
5446 memset(range, 0, sizeof(*range)); 8357 memset(range, 0, sizeof(*range));
@@ -5451,7 +8362,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5451 range->max_qual.qual = 100; 8362 range->max_qual.qual = 100;
5452 /* TODO: Find real max RSSI and stick here */ 8363 /* TODO: Find real max RSSI and stick here */
5453 range->max_qual.level = 0; 8364 range->max_qual.level = 0;
5454 range->max_qual.noise = 0; 8365 range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
5455 range->max_qual.updated = 7; /* Updated all three */ 8366 range->max_qual.updated = 7; /* Updated all three */
5456 8367
5457 range->avg_qual.qual = 70; 8368 range->avg_qual.qual = 70;
@@ -5459,7 +8370,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5459 range->avg_qual.level = 0; /* FIXME to real average level */ 8370 range->avg_qual.level = 0; /* FIXME to real average level */
5460 range->avg_qual.noise = 0; 8371 range->avg_qual.noise = 0;
5461 range->avg_qual.updated = 7; /* Updated all three */ 8372 range->avg_qual.updated = 7; /* Updated all three */
5462 8373 down(&priv->sem);
5463 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); 8374 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
5464 8375
5465 for (i = 0; i < range->num_bitrates; i++) 8376 for (i = 0; i < range->num_bitrates; i++)
@@ -5479,19 +8390,35 @@ static int ipw_wx_get_range(struct net_device *dev,
5479 range->we_version_compiled = WIRELESS_EXT; 8390 range->we_version_compiled = WIRELESS_EXT;
5480 range->we_version_source = 16; 8391 range->we_version_source = 16;
5481 8392
5482 range->num_channels = FREQ_COUNT; 8393 i = 0;
5483 8394 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
5484 val = 0; 8395 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
5485 for (i = 0; i < FREQ_COUNT; i++) { 8396 i++, j++) {
5486 range->freq[val].i = i + 1; 8397 range->freq[i].i = geo->bg[j].channel;
5487 range->freq[val].m = ipw_frequencies[i] * 100000; 8398 range->freq[i].m = geo->bg[j].freq * 100000;
5488 range->freq[val].e = 1; 8399 range->freq[i].e = 1;
5489 val++; 8400 }
8401 }
5490 8402
5491 if (val == IW_MAX_FREQUENCIES) 8403 if (priv->ieee->mode & IEEE_A) {
5492 break; 8404 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
8405 i++, j++) {
8406 range->freq[i].i = geo->a[j].channel;
8407 range->freq[i].m = geo->a[j].freq * 100000;
8408 range->freq[i].e = 1;
8409 }
5493 } 8410 }
5494 range->num_frequency = val; 8411
8412 range->num_channels = i;
8413 range->num_frequency = i;
8414
8415 up(&priv->sem);
8416
8417 /* Event capability (kernel + driver) */
8418 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
8419 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
8420 IW_EVENT_CAPA_MASK(SIOCGIWAP));
8421 range->event_capa[1] = IW_EVENT_CAPA_K_1;
5495 8422
5496 IPW_DEBUG_WX("GET Range\n"); 8423 IPW_DEBUG_WX("GET Range\n");
5497 return 0; 8424 return 0;
@@ -5512,25 +8439,23 @@ static int ipw_wx_set_wap(struct net_device *dev,
5512 8439
5513 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) 8440 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
5514 return -EINVAL; 8441 return -EINVAL;
5515 8442 down(&priv->sem);
5516 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || 8443 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
5517 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8444 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5518 /* we disable mandatory BSSID association */ 8445 /* we disable mandatory BSSID association */
5519 IPW_DEBUG_WX("Setting AP BSSID to ANY\n"); 8446 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
5520 priv->config &= ~CFG_STATIC_BSSID; 8447 priv->config &= ~CFG_STATIC_BSSID;
5521 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8448 IPW_DEBUG_ASSOC("Attempting to associate with new "
5522 STATUS_ASSOCIATING))) { 8449 "parameters.\n");
5523 IPW_DEBUG_ASSOC("Attempting to associate with new " 8450 ipw_associate(priv);
5524 "parameters.\n"); 8451 up(&priv->sem);
5525 ipw_associate(priv);
5526 }
5527
5528 return 0; 8452 return 0;
5529 } 8453 }
5530 8454
5531 priv->config |= CFG_STATIC_BSSID; 8455 priv->config |= CFG_STATIC_BSSID;
5532 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8456 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5533 IPW_DEBUG_WX("BSSID set to current BSSID.\n"); 8457 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
8458 up(&priv->sem);
5534 return 0; 8459 return 0;
5535 } 8460 }
5536 8461
@@ -5539,15 +8464,12 @@ static int ipw_wx_set_wap(struct net_device *dev,
5539 8464
5540 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN); 8465 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
5541 8466
5542 /* If we are currently associated, or trying to associate 8467 /* Network configuration changed -- force [re]association */
5543 * then see if this is a new BSSID (causing us to disassociate) */ 8468 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
5544 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8469 if (!ipw_disassociate(priv))
5545 IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
5546 ipw_disassociate(priv);
5547 } else {
5548 ipw_associate(priv); 8470 ipw_associate(priv);
5549 }
5550 8471
8472 up(&priv->sem);
5551 return 0; 8473 return 0;
5552} 8474}
5553 8475
@@ -5558,15 +8480,17 @@ static int ipw_wx_get_wap(struct net_device *dev,
5558 struct ipw_priv *priv = ieee80211_priv(dev); 8480 struct ipw_priv *priv = ieee80211_priv(dev);
5559 /* If we are associated, trying to associate, or have a statically 8481 /* If we are associated, trying to associate, or have a statically
5560 * configured BSSID then return that; otherwise return ANY */ 8482 * configured BSSID then return that; otherwise return ANY */
8483 down(&priv->sem);
5561 if (priv->config & CFG_STATIC_BSSID || 8484 if (priv->config & CFG_STATIC_BSSID ||
5562 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8485 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5563 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 8486 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
5564 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 8487 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
5565 } else 8488 } else
5566 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 8489 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
5567 8490
5568 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", 8491 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
5569 MAC_ARG(wrqu->ap_addr.sa_data)); 8492 MAC_ARG(wrqu->ap_addr.sa_data));
8493 up(&priv->sem);
5570 return 0; 8494 return 0;
5571} 8495}
5572 8496
@@ -5577,21 +8501,22 @@ static int ipw_wx_set_essid(struct net_device *dev,
5577 struct ipw_priv *priv = ieee80211_priv(dev); 8501 struct ipw_priv *priv = ieee80211_priv(dev);
5578 char *essid = ""; /* ANY */ 8502 char *essid = ""; /* ANY */
5579 int length = 0; 8503 int length = 0;
5580 8504 down(&priv->sem);
5581 if (wrqu->essid.flags && wrqu->essid.length) { 8505 if (wrqu->essid.flags && wrqu->essid.length) {
5582 length = wrqu->essid.length - 1; 8506 length = wrqu->essid.length - 1;
5583 essid = extra; 8507 essid = extra;
5584 } 8508 }
5585 if (length == 0) { 8509 if (length == 0) {
5586 IPW_DEBUG_WX("Setting ESSID to ANY\n"); 8510 IPW_DEBUG_WX("Setting ESSID to ANY\n");
5587 priv->config &= ~CFG_STATIC_ESSID; 8511 if ((priv->config & CFG_STATIC_ESSID) &&
5588 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8512 !(priv->status & (STATUS_ASSOCIATED |
5589 STATUS_ASSOCIATING))) { 8513 STATUS_ASSOCIATING))) {
5590 IPW_DEBUG_ASSOC("Attempting to associate with new " 8514 IPW_DEBUG_ASSOC("Attempting to associate with new "
5591 "parameters.\n"); 8515 "parameters.\n");
8516 priv->config &= ~CFG_STATIC_ESSID;
5592 ipw_associate(priv); 8517 ipw_associate(priv);
5593 } 8518 }
5594 8519 up(&priv->sem);
5595 return 0; 8520 return 0;
5596 } 8521 }
5597 8522
@@ -5601,6 +8526,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
5601 8526
5602 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { 8527 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
5603 IPW_DEBUG_WX("ESSID set to current ESSID.\n"); 8528 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
8529 up(&priv->sem);
5604 return 0; 8530 return 0;
5605 } 8531 }
5606 8532
@@ -5610,15 +8536,12 @@ static int ipw_wx_set_essid(struct net_device *dev,
5610 priv->essid_len = length; 8536 priv->essid_len = length;
5611 memcpy(priv->essid, essid, priv->essid_len); 8537 memcpy(priv->essid, essid, priv->essid_len);
5612 8538
5613 /* If we are currently associated, or trying to associate 8539 /* Network configuration changed -- force [re]association */
5614 * then see if this is a new ESSID (causing us to disassociate) */ 8540 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
5615 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8541 if (!ipw_disassociate(priv))
5616 IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
5617 ipw_disassociate(priv);
5618 } else {
5619 ipw_associate(priv); 8542 ipw_associate(priv);
5620 }
5621 8543
8544 up(&priv->sem);
5622 return 0; 8545 return 0;
5623} 8546}
5624 8547
@@ -5630,6 +8553,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5630 8553
5631 /* If we are associated, trying to associate, or have a statically 8554 /* If we are associated, trying to associate, or have a statically
5632 * configured ESSID then return that; otherwise return ANY */ 8555 * configured ESSID then return that; otherwise return ANY */
8556 down(&priv->sem);
5633 if (priv->config & CFG_STATIC_ESSID || 8557 if (priv->config & CFG_STATIC_ESSID ||
5634 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8558 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5635 IPW_DEBUG_WX("Getting essid: '%s'\n", 8559 IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -5642,7 +8566,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5642 wrqu->essid.length = 0; 8566 wrqu->essid.length = 0;
5643 wrqu->essid.flags = 0; /* active */ 8567 wrqu->essid.flags = 0; /* active */
5644 } 8568 }
5645 8569 up(&priv->sem);
5646 return 0; 8570 return 0;
5647} 8571}
5648 8572
@@ -5655,11 +8579,12 @@ static int ipw_wx_set_nick(struct net_device *dev,
5655 IPW_DEBUG_WX("Setting nick to '%s'\n", extra); 8579 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
5656 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 8580 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
5657 return -E2BIG; 8581 return -E2BIG;
5658 8582 down(&priv->sem);
5659 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 8583 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
5660 memset(priv->nick, 0, sizeof(priv->nick)); 8584 memset(priv->nick, 0, sizeof(priv->nick));
5661 memcpy(priv->nick, extra, wrqu->data.length); 8585 memcpy(priv->nick, extra, wrqu->data.length);
5662 IPW_DEBUG_TRACE("<<\n"); 8586 IPW_DEBUG_TRACE("<<\n");
8587 up(&priv->sem);
5663 return 0; 8588 return 0;
5664 8589
5665} 8590}
@@ -5670,9 +8595,11 @@ static int ipw_wx_get_nick(struct net_device *dev,
5670{ 8595{
5671 struct ipw_priv *priv = ieee80211_priv(dev); 8596 struct ipw_priv *priv = ieee80211_priv(dev);
5672 IPW_DEBUG_WX("Getting nick\n"); 8597 IPW_DEBUG_WX("Getting nick\n");
8598 down(&priv->sem);
5673 wrqu->data.length = strlen(priv->nick) + 1; 8599 wrqu->data.length = strlen(priv->nick) + 1;
5674 memcpy(extra, priv->nick, wrqu->data.length); 8600 memcpy(extra, priv->nick, wrqu->data.length);
5675 wrqu->data.flags = 1; /* active */ 8601 wrqu->data.flags = 1; /* active */
8602 up(&priv->sem);
5676 return 0; 8603 return 0;
5677} 8604}
5678 8605
@@ -5680,8 +8607,113 @@ static int ipw_wx_set_rate(struct net_device *dev,
5680 struct iw_request_info *info, 8607 struct iw_request_info *info,
5681 union iwreq_data *wrqu, char *extra) 8608 union iwreq_data *wrqu, char *extra)
5682{ 8609{
5683 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8610 /* TODO: We should use semaphores or locks for access to priv */
5684 return -EOPNOTSUPP; 8611 struct ipw_priv *priv = ieee80211_priv(dev);
8612 u32 target_rate = wrqu->bitrate.value;
8613 u32 fixed, mask;
8614
8615 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
8616 /* value = X, fixed = 1 means only rate X */
8617 /* value = X, fixed = 0 means all rates lower equal X */
8618
8619 if (target_rate == -1) {
8620 fixed = 0;
8621 mask = IEEE80211_DEFAULT_RATES_MASK;
8622 /* Now we should reassociate */
8623 goto apply;
8624 }
8625
8626 mask = 0;
8627 fixed = wrqu->bitrate.fixed;
8628
8629 if (target_rate == 1000000 || !fixed)
8630 mask |= IEEE80211_CCK_RATE_1MB_MASK;
8631 if (target_rate == 1000000)
8632 goto apply;
8633
8634 if (target_rate == 2000000 || !fixed)
8635 mask |= IEEE80211_CCK_RATE_2MB_MASK;
8636 if (target_rate == 2000000)
8637 goto apply;
8638
8639 if (target_rate == 5500000 || !fixed)
8640 mask |= IEEE80211_CCK_RATE_5MB_MASK;
8641 if (target_rate == 5500000)
8642 goto apply;
8643
8644 if (target_rate == 6000000 || !fixed)
8645 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
8646 if (target_rate == 6000000)
8647 goto apply;
8648
8649 if (target_rate == 9000000 || !fixed)
8650 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
8651 if (target_rate == 9000000)
8652 goto apply;
8653
8654 if (target_rate == 11000000 || !fixed)
8655 mask |= IEEE80211_CCK_RATE_11MB_MASK;
8656 if (target_rate == 11000000)
8657 goto apply;
8658
8659 if (target_rate == 12000000 || !fixed)
8660 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
8661 if (target_rate == 12000000)
8662 goto apply;
8663
8664 if (target_rate == 18000000 || !fixed)
8665 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
8666 if (target_rate == 18000000)
8667 goto apply;
8668
8669 if (target_rate == 24000000 || !fixed)
8670 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
8671 if (target_rate == 24000000)
8672 goto apply;
8673
8674 if (target_rate == 36000000 || !fixed)
8675 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
8676 if (target_rate == 36000000)
8677 goto apply;
8678
8679 if (target_rate == 48000000 || !fixed)
8680 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
8681 if (target_rate == 48000000)
8682 goto apply;
8683
8684 if (target_rate == 54000000 || !fixed)
8685 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
8686 if (target_rate == 54000000)
8687 goto apply;
8688
8689 IPW_DEBUG_WX("invalid rate specified, returning error\n");
8690 return -EINVAL;
8691
8692 apply:
8693 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
8694 mask, fixed ? "fixed" : "sub-rates");
8695 down(&priv->sem);
8696 if (mask == IEEE80211_DEFAULT_RATES_MASK) {
8697 priv->config &= ~CFG_FIXED_RATE;
8698 ipw_set_fixed_rate(priv, priv->ieee->mode);
8699 } else
8700 priv->config |= CFG_FIXED_RATE;
8701
8702 if (priv->rates_mask == mask) {
8703 IPW_DEBUG_WX("Mask set to current mask.\n");
8704 up(&priv->sem);
8705 return 0;
8706 }
8707
8708 priv->rates_mask = mask;
8709
8710 /* Network configuration changed -- force [re]association */
8711 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
8712 if (!ipw_disassociate(priv))
8713 ipw_associate(priv);
8714
8715 up(&priv->sem);
8716 return 0;
5685} 8717}
5686 8718
5687static int ipw_wx_get_rate(struct net_device *dev, 8719static int ipw_wx_get_rate(struct net_device *dev,
@@ -5689,8 +8721,9 @@ static int ipw_wx_get_rate(struct net_device *dev,
5689 union iwreq_data *wrqu, char *extra) 8721 union iwreq_data *wrqu, char *extra)
5690{ 8722{
5691 struct ipw_priv *priv = ieee80211_priv(dev); 8723 struct ipw_priv *priv = ieee80211_priv(dev);
8724 down(&priv->sem);
5692 wrqu->bitrate.value = priv->last_rate; 8725 wrqu->bitrate.value = priv->last_rate;
5693 8726 up(&priv->sem);
5694 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 8727 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
5695 return 0; 8728 return 0;
5696} 8729}
@@ -5700,18 +8733,20 @@ static int ipw_wx_set_rts(struct net_device *dev,
5700 union iwreq_data *wrqu, char *extra) 8733 union iwreq_data *wrqu, char *extra)
5701{ 8734{
5702 struct ipw_priv *priv = ieee80211_priv(dev); 8735 struct ipw_priv *priv = ieee80211_priv(dev);
5703 8736 down(&priv->sem);
5704 if (wrqu->rts.disabled) 8737 if (wrqu->rts.disabled)
5705 priv->rts_threshold = DEFAULT_RTS_THRESHOLD; 8738 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5706 else { 8739 else {
5707 if (wrqu->rts.value < MIN_RTS_THRESHOLD || 8740 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
5708 wrqu->rts.value > MAX_RTS_THRESHOLD) 8741 wrqu->rts.value > MAX_RTS_THRESHOLD) {
8742 up(&priv->sem);
5709 return -EINVAL; 8743 return -EINVAL;
5710 8744 }
5711 priv->rts_threshold = wrqu->rts.value; 8745 priv->rts_threshold = wrqu->rts.value;
5712 } 8746 }
5713 8747
5714 ipw_send_rts_threshold(priv, priv->rts_threshold); 8748 ipw_send_rts_threshold(priv, priv->rts_threshold);
8749 up(&priv->sem);
5715 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); 8750 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
5716 return 0; 8751 return 0;
5717} 8752}
@@ -5721,10 +8756,11 @@ static int ipw_wx_get_rts(struct net_device *dev,
5721 union iwreq_data *wrqu, char *extra) 8756 union iwreq_data *wrqu, char *extra)
5722{ 8757{
5723 struct ipw_priv *priv = ieee80211_priv(dev); 8758 struct ipw_priv *priv = ieee80211_priv(dev);
8759 down(&priv->sem);
5724 wrqu->rts.value = priv->rts_threshold; 8760 wrqu->rts.value = priv->rts_threshold;
5725 wrqu->rts.fixed = 0; /* no auto select */ 8761 wrqu->rts.fixed = 0; /* no auto select */
5726 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 8762 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
5727 8763 up(&priv->sem);
5728 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); 8764 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
5729 return 0; 8765 return 0;
5730} 8766}
@@ -5734,41 +8770,33 @@ static int ipw_wx_set_txpow(struct net_device *dev,
5734 union iwreq_data *wrqu, char *extra) 8770 union iwreq_data *wrqu, char *extra)
5735{ 8771{
5736 struct ipw_priv *priv = ieee80211_priv(dev); 8772 struct ipw_priv *priv = ieee80211_priv(dev);
5737 struct ipw_tx_power tx_power; 8773 int err = 0;
5738 int i;
5739
5740 if (ipw_radio_kill_sw(priv, wrqu->power.disabled))
5741 return -EINPROGRESS;
5742
5743 if (wrqu->power.flags != IW_TXPOW_DBM)
5744 return -EINVAL;
5745 8774
5746 if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) 8775 down(&priv->sem);
5747 return -EINVAL; 8776 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
8777 err = -EINPROGRESS;
8778 goto out;
8779 }
5748 8780
5749 priv->tx_power = wrqu->power.value; 8781 if (!wrqu->power.fixed)
8782 wrqu->power.value = IPW_TX_POWER_DEFAULT;
5750 8783
5751 memset(&tx_power, 0, sizeof(tx_power)); 8784 if (wrqu->power.flags != IW_TXPOW_DBM) {
5752 8785 err = -EINVAL;
5753 /* configure device for 'G' band */ 8786 goto out;
5754 tx_power.ieee_mode = IPW_G_MODE;
5755 tx_power.num_channels = 11;
5756 for (i = 0; i < 11; i++) {
5757 tx_power.channels_tx_power[i].channel_number = i + 1;
5758 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
5759 } 8787 }
5760 if (ipw_send_tx_power(priv, &tx_power))
5761 goto error;
5762 8788
5763 /* configure device to also handle 'B' band */ 8789 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
5764 tx_power.ieee_mode = IPW_B_MODE; 8790 (wrqu->power.value < IPW_TX_POWER_MIN)) {
5765 if (ipw_send_tx_power(priv, &tx_power)) 8791 err = -EINVAL;
5766 goto error; 8792 goto out;
5767 8793 }
5768 return 0;
5769 8794
5770 error: 8795 priv->tx_power = wrqu->power.value;
5771 return -EIO; 8796 err = ipw_set_tx_power(priv);
8797 out:
8798 up(&priv->sem);
8799 return err;
5772} 8800}
5773 8801
5774static int ipw_wx_get_txpow(struct net_device *dev, 8802static int ipw_wx_get_txpow(struct net_device *dev,
@@ -5776,14 +8804,15 @@ static int ipw_wx_get_txpow(struct net_device *dev,
5776 union iwreq_data *wrqu, char *extra) 8804 union iwreq_data *wrqu, char *extra)
5777{ 8805{
5778 struct ipw_priv *priv = ieee80211_priv(dev); 8806 struct ipw_priv *priv = ieee80211_priv(dev);
5779 8807 down(&priv->sem);
5780 wrqu->power.value = priv->tx_power; 8808 wrqu->power.value = priv->tx_power;
5781 wrqu->power.fixed = 1; 8809 wrqu->power.fixed = 1;
5782 wrqu->power.flags = IW_TXPOW_DBM; 8810 wrqu->power.flags = IW_TXPOW_DBM;
5783 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; 8811 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
8812 up(&priv->sem);
5784 8813
5785 IPW_DEBUG_WX("GET TX Power -> %s %d \n", 8814 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
5786 wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value); 8815 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
5787 8816
5788 return 0; 8817 return 0;
5789} 8818}
@@ -5793,18 +8822,21 @@ static int ipw_wx_set_frag(struct net_device *dev,
5793 union iwreq_data *wrqu, char *extra) 8822 union iwreq_data *wrqu, char *extra)
5794{ 8823{
5795 struct ipw_priv *priv = ieee80211_priv(dev); 8824 struct ipw_priv *priv = ieee80211_priv(dev);
5796 8825 down(&priv->sem);
5797 if (wrqu->frag.disabled) 8826 if (wrqu->frag.disabled)
5798 priv->ieee->fts = DEFAULT_FTS; 8827 priv->ieee->fts = DEFAULT_FTS;
5799 else { 8828 else {
5800 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 8829 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
5801 wrqu->frag.value > MAX_FRAG_THRESHOLD) 8830 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
8831 up(&priv->sem);
5802 return -EINVAL; 8832 return -EINVAL;
8833 }
5803 8834
5804 priv->ieee->fts = wrqu->frag.value & ~0x1; 8835 priv->ieee->fts = wrqu->frag.value & ~0x1;
5805 } 8836 }
5806 8837
5807 ipw_send_frag_threshold(priv, wrqu->frag.value); 8838 ipw_send_frag_threshold(priv, wrqu->frag.value);
8839 up(&priv->sem);
5808 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); 8840 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
5809 return 0; 8841 return 0;
5810} 8842}
@@ -5814,10 +8846,11 @@ static int ipw_wx_get_frag(struct net_device *dev,
5814 union iwreq_data *wrqu, char *extra) 8846 union iwreq_data *wrqu, char *extra)
5815{ 8847{
5816 struct ipw_priv *priv = ieee80211_priv(dev); 8848 struct ipw_priv *priv = ieee80211_priv(dev);
8849 down(&priv->sem);
5817 wrqu->frag.value = priv->ieee->fts; 8850 wrqu->frag.value = priv->ieee->fts;
5818 wrqu->frag.fixed = 0; /* no auto select */ 8851 wrqu->frag.fixed = 0; /* no auto select */
5819 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); 8852 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
5820 8853 up(&priv->sem);
5821 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 8854 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
5822 8855
5823 return 0; 8856 return 0;
@@ -5827,16 +8860,128 @@ static int ipw_wx_set_retry(struct net_device *dev,
5827 struct iw_request_info *info, 8860 struct iw_request_info *info,
5828 union iwreq_data *wrqu, char *extra) 8861 union iwreq_data *wrqu, char *extra)
5829{ 8862{
5830 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8863 struct ipw_priv *priv = ieee80211_priv(dev);
5831 return -EOPNOTSUPP; 8864
8865 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
8866 return -EINVAL;
8867
8868 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
8869 return 0;
8870
8871 if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
8872 return -EINVAL;
8873
8874 down(&priv->sem);
8875 if (wrqu->retry.flags & IW_RETRY_MIN)
8876 priv->short_retry_limit = (u8) wrqu->retry.value;
8877 else if (wrqu->retry.flags & IW_RETRY_MAX)
8878 priv->long_retry_limit = (u8) wrqu->retry.value;
8879 else {
8880 priv->short_retry_limit = (u8) wrqu->retry.value;
8881 priv->long_retry_limit = (u8) wrqu->retry.value;
8882 }
8883
8884 ipw_send_retry_limit(priv, priv->short_retry_limit,
8885 priv->long_retry_limit);
8886 up(&priv->sem);
8887 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
8888 priv->short_retry_limit, priv->long_retry_limit);
8889 return 0;
5832} 8890}
5833 8891
5834static int ipw_wx_get_retry(struct net_device *dev, 8892static int ipw_wx_get_retry(struct net_device *dev,
5835 struct iw_request_info *info, 8893 struct iw_request_info *info,
5836 union iwreq_data *wrqu, char *extra) 8894 union iwreq_data *wrqu, char *extra)
5837{ 8895{
5838 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8896 struct ipw_priv *priv = ieee80211_priv(dev);
5839 return -EOPNOTSUPP; 8897
8898 down(&priv->sem);
8899 wrqu->retry.disabled = 0;
8900
8901 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
8902 up(&priv->sem);
8903 return -EINVAL;
8904 }
8905
8906 if (wrqu->retry.flags & IW_RETRY_MAX) {
8907 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
8908 wrqu->retry.value = priv->long_retry_limit;
8909 } else if (wrqu->retry.flags & IW_RETRY_MIN) {
8910 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
8911 wrqu->retry.value = priv->short_retry_limit;
8912 } else {
8913 wrqu->retry.flags = IW_RETRY_LIMIT;
8914 wrqu->retry.value = priv->short_retry_limit;
8915 }
8916 up(&priv->sem);
8917
8918 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
8919
8920 return 0;
8921}
8922
8923static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
8924 int essid_len)
8925{
8926 struct ipw_scan_request_ext scan;
8927 int err = 0, scan_type;
8928
8929 down(&priv->sem);
8930
8931 if (priv->status & STATUS_RF_KILL_MASK) {
8932 IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
8933 priv->status |= STATUS_SCAN_PENDING;
8934 goto done;
8935 }
8936
8937 IPW_DEBUG_HC("starting request direct scan!\n");
8938
8939 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
8940 err = wait_event_interruptible(priv->wait_state,
8941 !(priv->
8942 status & (STATUS_SCANNING |
8943 STATUS_SCAN_ABORTING)));
8944 if (err) {
8945 IPW_DEBUG_HC("aborting direct scan");
8946 goto done;
8947 }
8948 }
8949 memset(&scan, 0, sizeof(scan));
8950
8951 if (priv->config & CFG_SPEED_SCAN)
8952 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8953 cpu_to_le16(30);
8954 else
8955 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8956 cpu_to_le16(20);
8957
8958 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
8959 cpu_to_le16(20);
8960 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
8961 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
8962
8963 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
8964
8965 err = ipw_send_ssid(priv, essid, essid_len);
8966 if (err) {
8967 IPW_DEBUG_HC("Attempt to send SSID command failed\n");
8968 goto done;
8969 }
8970 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
8971
8972 ipw_add_scan_channels(priv, &scan, scan_type);
8973
8974 err = ipw_send_scan_request_ext(priv, &scan);
8975 if (err) {
8976 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
8977 goto done;
8978 }
8979
8980 priv->status |= STATUS_SCANNING;
8981
8982 done:
8983 up(&priv->sem);
8984 return err;
5840} 8985}
5841 8986
5842static int ipw_wx_set_scan(struct net_device *dev, 8987static int ipw_wx_set_scan(struct net_device *dev,
@@ -5844,9 +8989,21 @@ static int ipw_wx_set_scan(struct net_device *dev,
5844 union iwreq_data *wrqu, char *extra) 8989 union iwreq_data *wrqu, char *extra)
5845{ 8990{
5846 struct ipw_priv *priv = ieee80211_priv(dev); 8991 struct ipw_priv *priv = ieee80211_priv(dev);
8992 struct iw_scan_req *req = NULL;
8993 if (wrqu->data.length
8994 && wrqu->data.length == sizeof(struct iw_scan_req)) {
8995 req = (struct iw_scan_req *)extra;
8996 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
8997 ipw_request_direct_scan(priv, req->essid,
8998 req->essid_len);
8999 return 0;
9000 }
9001 }
9002
5847 IPW_DEBUG_WX("Start scan\n"); 9003 IPW_DEBUG_WX("Start scan\n");
5848 if (ipw_request_scan(priv)) 9004
5849 return -EIO; 9005 queue_work(priv->workqueue, &priv->request_scan);
9006
5850 return 0; 9007 return 0;
5851} 9008}
5852 9009
@@ -5863,7 +9020,21 @@ static int ipw_wx_set_encode(struct net_device *dev,
5863 union iwreq_data *wrqu, char *key) 9020 union iwreq_data *wrqu, char *key)
5864{ 9021{
5865 struct ipw_priv *priv = ieee80211_priv(dev); 9022 struct ipw_priv *priv = ieee80211_priv(dev);
5866 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); 9023 int ret;
9024 u32 cap = priv->capability;
9025
9026 down(&priv->sem);
9027 ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
9028
9029 /* In IBSS mode, we need to notify the firmware to update
9030 * the beacon info after we changed the capability. */
9031 if (cap != priv->capability &&
9032 priv->ieee->iw_mode == IW_MODE_ADHOC &&
9033 priv->status & STATUS_ASSOCIATED)
9034 ipw_disassociate(priv);
9035
9036 up(&priv->sem);
9037 return ret;
5867} 9038}
5868 9039
5869static int ipw_wx_get_encode(struct net_device *dev, 9040static int ipw_wx_get_encode(struct net_device *dev,
@@ -5880,17 +9051,17 @@ static int ipw_wx_set_power(struct net_device *dev,
5880{ 9051{
5881 struct ipw_priv *priv = ieee80211_priv(dev); 9052 struct ipw_priv *priv = ieee80211_priv(dev);
5882 int err; 9053 int err;
5883 9054 down(&priv->sem);
5884 if (wrqu->power.disabled) { 9055 if (wrqu->power.disabled) {
5885 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode); 9056 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
5886 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM); 9057 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
5887 if (err) { 9058 if (err) {
5888 IPW_DEBUG_WX("failed setting power mode.\n"); 9059 IPW_DEBUG_WX("failed setting power mode.\n");
9060 up(&priv->sem);
5889 return err; 9061 return err;
5890 } 9062 }
5891
5892 IPW_DEBUG_WX("SET Power Management Mode -> off\n"); 9063 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
5893 9064 up(&priv->sem);
5894 return 0; 9065 return 0;
5895 } 9066 }
5896 9067
@@ -5902,6 +9073,7 @@ static int ipw_wx_set_power(struct net_device *dev,
5902 default: /* Otherwise we don't support it */ 9073 default: /* Otherwise we don't support it */
5903 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 9074 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
5904 wrqu->power.flags); 9075 wrqu->power.flags);
9076 up(&priv->sem);
5905 return -EOPNOTSUPP; 9077 return -EOPNOTSUPP;
5906 } 9078 }
5907 9079
@@ -5914,11 +9086,12 @@ static int ipw_wx_set_power(struct net_device *dev,
5914 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 9086 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
5915 if (err) { 9087 if (err) {
5916 IPW_DEBUG_WX("failed setting power mode.\n"); 9088 IPW_DEBUG_WX("failed setting power mode.\n");
9089 up(&priv->sem);
5917 return err; 9090 return err;
5918 } 9091 }
5919 9092
5920 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); 9093 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
5921 9094 up(&priv->sem);
5922 return 0; 9095 return 0;
5923} 9096}
5924 9097
@@ -5927,13 +9100,13 @@ static int ipw_wx_get_power(struct net_device *dev,
5927 union iwreq_data *wrqu, char *extra) 9100 union iwreq_data *wrqu, char *extra)
5928{ 9101{
5929 struct ipw_priv *priv = ieee80211_priv(dev); 9102 struct ipw_priv *priv = ieee80211_priv(dev);
5930 9103 down(&priv->sem);
5931 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 9104 if (!(priv->power_mode & IPW_POWER_ENABLED))
5932 wrqu->power.disabled = 1; 9105 wrqu->power.disabled = 1;
5933 } else { 9106 else
5934 wrqu->power.disabled = 0; 9107 wrqu->power.disabled = 0;
5935 }
5936 9108
9109 up(&priv->sem);
5937 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); 9110 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
5938 9111
5939 return 0; 9112 return 0;
@@ -5946,7 +9119,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5946 struct ipw_priv *priv = ieee80211_priv(dev); 9119 struct ipw_priv *priv = ieee80211_priv(dev);
5947 int mode = *(int *)extra; 9120 int mode = *(int *)extra;
5948 int err; 9121 int err;
5949 9122 down(&priv->sem);
5950 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { 9123 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
5951 mode = IPW_POWER_AC; 9124 mode = IPW_POWER_AC;
5952 priv->power_mode = mode; 9125 priv->power_mode = mode;
@@ -5959,10 +9132,11 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5959 9132
5960 if (err) { 9133 if (err) {
5961 IPW_DEBUG_WX("failed setting power mode.\n"); 9134 IPW_DEBUG_WX("failed setting power mode.\n");
9135 up(&priv->sem);
5962 return err; 9136 return err;
5963 } 9137 }
5964 } 9138 }
5965 9139 up(&priv->sem);
5966 return 0; 9140 return 0;
5967} 9141}
5968 9142
@@ -6011,7 +9185,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6011 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); 9185 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
6012 return -EINVAL; 9186 return -EINVAL;
6013 } 9187 }
6014 9188 down(&priv->sem);
6015 if (priv->adapter == IPW_2915ABG) { 9189 if (priv->adapter == IPW_2915ABG) {
6016 priv->ieee->abg_true = 1; 9190 priv->ieee->abg_true = 1;
6017 if (mode & IEEE_A) { 9191 if (mode & IEEE_A) {
@@ -6023,6 +9197,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6023 if (mode & IEEE_A) { 9197 if (mode & IEEE_A) {
6024 IPW_WARNING("Attempt to set 2200BG into " 9198 IPW_WARNING("Attempt to set 2200BG into "
6025 "802.11a mode\n"); 9199 "802.11a mode\n");
9200 up(&priv->sem);
6026 return -EINVAL; 9201 return -EINVAL;
6027 } 9202 }
6028 9203
@@ -6046,20 +9221,20 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6046 priv->ieee->modulation = modulation; 9221 priv->ieee->modulation = modulation;
6047 init_supported_rates(priv, &priv->rates); 9222 init_supported_rates(priv, &priv->rates);
6048 9223
6049 /* If we are currently associated, or trying to associate 9224 /* Network configuration changed -- force [re]association */
6050 * then see if this is a new configuration (causing us to 9225 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
6051 * disassociate) */ 9226 if (!ipw_disassociate(priv)) {
6052 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6053 /* The resulting association will trigger
6054 * the new rates to be sent to the device */
6055 IPW_DEBUG_ASSOC("Disassociating due to mode change.\n");
6056 ipw_disassociate(priv);
6057 } else
6058 ipw_send_supported_rates(priv, &priv->rates); 9227 ipw_send_supported_rates(priv, &priv->rates);
9228 ipw_associate(priv);
9229 }
9230
9231 /* Update the band LEDs */
9232 ipw_led_band_on(priv);
6059 9233
6060 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", 9234 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
6061 mode & IEEE_A ? 'a' : '.', 9235 mode & IEEE_A ? 'a' : '.',
6062 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); 9236 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
9237 up(&priv->sem);
6063 return 0; 9238 return 0;
6064} 9239}
6065 9240
@@ -6068,124 +9243,234 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
6068 union iwreq_data *wrqu, char *extra) 9243 union iwreq_data *wrqu, char *extra)
6069{ 9244{
6070 struct ipw_priv *priv = ieee80211_priv(dev); 9245 struct ipw_priv *priv = ieee80211_priv(dev);
6071 9246 down(&priv->sem);
6072 switch (priv->ieee->freq_band) { 9247 switch (priv->ieee->mode) {
6073 case IEEE80211_24GHZ_BAND: 9248 case IEEE_A:
6074 switch (priv->ieee->modulation) {
6075 case IEEE80211_CCK_MODULATION:
6076 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6077 break;
6078 case IEEE80211_OFDM_MODULATION:
6079 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6080 break;
6081 default:
6082 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
6083 break;
6084 }
6085 break;
6086
6087 case IEEE80211_52GHZ_BAND:
6088 strncpy(extra, "802.11a (1)", MAX_WX_STRING); 9249 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
6089 break; 9250 break;
6090 9251 case IEEE_B:
6091 default: /* Mixed Band */ 9252 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6092 switch (priv->ieee->modulation) { 9253 break;
6093 case IEEE80211_CCK_MODULATION: 9254 case IEEE_A | IEEE_B:
6094 strncpy(extra, "802.11ab (3)", MAX_WX_STRING); 9255 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
6095 break; 9256 break;
6096 case IEEE80211_OFDM_MODULATION: 9257 case IEEE_G:
6097 strncpy(extra, "802.11ag (5)", MAX_WX_STRING); 9258 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6098 break; 9259 break;
6099 default: 9260 case IEEE_A | IEEE_G:
6100 strncpy(extra, "802.11abg (7)", MAX_WX_STRING); 9261 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
6101 break; 9262 break;
6102 } 9263 case IEEE_B | IEEE_G:
9264 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
9265 break;
9266 case IEEE_A | IEEE_B | IEEE_G:
9267 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
9268 break;
9269 default:
9270 strncpy(extra, "unknown", MAX_WX_STRING);
6103 break; 9271 break;
6104 } 9272 }
6105 9273
6106 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); 9274 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
6107 9275
6108 wrqu->data.length = strlen(extra) + 1; 9276 wrqu->data.length = strlen(extra) + 1;
9277 up(&priv->sem);
6109 9278
6110 return 0; 9279 return 0;
6111} 9280}
6112 9281
6113#ifdef CONFIG_IPW_PROMISC 9282static int ipw_wx_set_preamble(struct net_device *dev,
6114static int ipw_wx_set_promisc(struct net_device *dev, 9283 struct iw_request_info *info,
9284 union iwreq_data *wrqu, char *extra)
9285{
9286 struct ipw_priv *priv = ieee80211_priv(dev);
9287 int mode = *(int *)extra;
9288 down(&priv->sem);
9289 /* Switching from SHORT -> LONG requires a disassociation */
9290 if (mode == 1) {
9291 if (!(priv->config & CFG_PREAMBLE_LONG)) {
9292 priv->config |= CFG_PREAMBLE_LONG;
9293
9294 /* Network configuration changed -- force [re]association */
9295 IPW_DEBUG_ASSOC
9296 ("[re]association triggered due to preamble change.\n");
9297 if (!ipw_disassociate(priv))
9298 ipw_associate(priv);
9299 }
9300 goto done;
9301 }
9302
9303 if (mode == 0) {
9304 priv->config &= ~CFG_PREAMBLE_LONG;
9305 goto done;
9306 }
9307 up(&priv->sem);
9308 return -EINVAL;
9309
9310 done:
9311 up(&priv->sem);
9312 return 0;
9313}
9314
9315static int ipw_wx_get_preamble(struct net_device *dev,
9316 struct iw_request_info *info,
9317 union iwreq_data *wrqu, char *extra)
9318{
9319 struct ipw_priv *priv = ieee80211_priv(dev);
9320 down(&priv->sem);
9321 if (priv->config & CFG_PREAMBLE_LONG)
9322 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9323 else
9324 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
9325 up(&priv->sem);
9326 return 0;
9327}
9328
9329#ifdef CONFIG_IPW2200_MONITOR
9330static int ipw_wx_set_monitor(struct net_device *dev,
6115 struct iw_request_info *info, 9331 struct iw_request_info *info,
6116 union iwreq_data *wrqu, char *extra) 9332 union iwreq_data *wrqu, char *extra)
6117{ 9333{
6118 struct ipw_priv *priv = ieee80211_priv(dev); 9334 struct ipw_priv *priv = ieee80211_priv(dev);
6119 int *parms = (int *)extra; 9335 int *parms = (int *)extra;
6120 int enable = (parms[0] > 0); 9336 int enable = (parms[0] > 0);
6121 9337 down(&priv->sem);
6122 IPW_DEBUG_WX("SET PROMISC: %d %d\n", enable, parms[1]); 9338 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
6123 if (enable) { 9339 if (enable) {
6124 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 9340 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9341#ifdef CONFIG_IEEE80211_RADIOTAP
9342 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
9343#else
6125 priv->net_dev->type = ARPHRD_IEEE80211; 9344 priv->net_dev->type = ARPHRD_IEEE80211;
6126 ipw_adapter_restart(priv); 9345#endif
9346 queue_work(priv->workqueue, &priv->adapter_restart);
6127 } 9347 }
6128 9348
6129 ipw_set_channel(priv, parms[1]); 9349 ipw_set_channel(priv, parms[1]);
6130 } else { 9350 } else {
6131 if (priv->ieee->iw_mode != IW_MODE_MONITOR) 9351 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9352 up(&priv->sem);
6132 return 0; 9353 return 0;
9354 }
6133 priv->net_dev->type = ARPHRD_ETHER; 9355 priv->net_dev->type = ARPHRD_ETHER;
6134 ipw_adapter_restart(priv); 9356 queue_work(priv->workqueue, &priv->adapter_restart);
6135 } 9357 }
9358 up(&priv->sem);
6136 return 0; 9359 return 0;
6137} 9360}
6138 9361
9362#endif // CONFIG_IPW2200_MONITOR
9363
6139static int ipw_wx_reset(struct net_device *dev, 9364static int ipw_wx_reset(struct net_device *dev,
6140 struct iw_request_info *info, 9365 struct iw_request_info *info,
6141 union iwreq_data *wrqu, char *extra) 9366 union iwreq_data *wrqu, char *extra)
6142{ 9367{
6143 struct ipw_priv *priv = ieee80211_priv(dev); 9368 struct ipw_priv *priv = ieee80211_priv(dev);
6144 IPW_DEBUG_WX("RESET\n"); 9369 IPW_DEBUG_WX("RESET\n");
6145 ipw_adapter_restart(priv); 9370 queue_work(priv->workqueue, &priv->adapter_restart);
9371 return 0;
9372}
9373
9374static int ipw_wx_sw_reset(struct net_device *dev,
9375 struct iw_request_info *info,
9376 union iwreq_data *wrqu, char *extra)
9377{
9378 struct ipw_priv *priv = ieee80211_priv(dev);
9379 union iwreq_data wrqu_sec = {
9380 .encoding = {
9381 .flags = IW_ENCODE_DISABLED,
9382 },
9383 };
9384 int ret;
9385
9386 IPW_DEBUG_WX("SW_RESET\n");
9387
9388 down(&priv->sem);
9389
9390 ret = ipw_sw_reset(priv, 0);
9391 if (!ret) {
9392 free_firmware();
9393 ipw_adapter_restart(priv);
9394 }
9395
9396 /* The SW reset bit might have been toggled on by the 'disable'
9397 * module parameter, so take appropriate action */
9398 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
9399
9400 up(&priv->sem);
9401 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
9402 down(&priv->sem);
9403
9404 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9405 /* Configuration likely changed -- force [re]association */
9406 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
9407 "reset.\n");
9408 if (!ipw_disassociate(priv))
9409 ipw_associate(priv);
9410 }
9411
9412 up(&priv->sem);
9413
6146 return 0; 9414 return 0;
6147} 9415}
6148#endif // CONFIG_IPW_PROMISC
6149 9416
6150/* Rebase the WE IOCTLs to zero for the handler array */ 9417/* Rebase the WE IOCTLs to zero for the handler array */
6151#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 9418#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
6152static iw_handler ipw_wx_handlers[] = { 9419static iw_handler ipw_wx_handlers[] = {
6153 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, 9420 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
6154 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 9421 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
6155 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 9422 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
6156 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 9423 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
6157 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 9424 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
6158 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 9425 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
6159 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 9426 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
6160 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 9427 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
6161 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 9428 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
6162 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 9429 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
6163 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 9430 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
6164 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 9431 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
6165 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 9432 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
6166 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 9433 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
6167 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 9434 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
6168 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 9435 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
6169 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 9436 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
6170 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 9437 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
6171 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 9438 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
6172 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 9439 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
6173 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 9440 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
6174 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 9441 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
6175 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 9442 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
6176 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 9443 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
6177 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 9444 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
6178 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 9445 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
6179 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 9446 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
6180 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 9447 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
9448 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
9449 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
9450 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
9451 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
9452 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
9453 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
9454 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
9455 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
9456 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
9457 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
9458 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
6181}; 9459};
6182 9460
6183#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV 9461enum {
6184#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1 9462 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
6185#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2 9463 IPW_PRIV_GET_POWER,
6186#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3 9464 IPW_PRIV_SET_MODE,
6187#define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4 9465 IPW_PRIV_GET_MODE,
6188#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 9466 IPW_PRIV_SET_PREAMBLE,
9467 IPW_PRIV_GET_PREAMBLE,
9468 IPW_PRIV_RESET,
9469 IPW_PRIV_SW_RESET,
9470#ifdef CONFIG_IPW2200_MONITOR
9471 IPW_PRIV_SET_MONITOR,
9472#endif
9473};
6189 9474
6190static struct iw_priv_args ipw_priv_args[] = { 9475static struct iw_priv_args ipw_priv_args[] = {
6191 { 9476 {
@@ -6204,14 +9489,25 @@ static struct iw_priv_args ipw_priv_args[] = {
6204 .cmd = IPW_PRIV_GET_MODE, 9489 .cmd = IPW_PRIV_GET_MODE,
6205 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, 9490 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
6206 .name = "get_mode"}, 9491 .name = "get_mode"},
6207#ifdef CONFIG_IPW_PROMISC
6208 { 9492 {
6209 IPW_PRIV_SET_PROMISC, 9493 .cmd = IPW_PRIV_SET_PREAMBLE,
6210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"}, 9494 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9495 .name = "set_preamble"},
9496 {
9497 .cmd = IPW_PRIV_GET_PREAMBLE,
9498 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
9499 .name = "get_preamble"},
6211 { 9500 {
6212 IPW_PRIV_RESET, 9501 IPW_PRIV_RESET,
6213 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"}, 9502 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
6214#endif /* CONFIG_IPW_PROMISC */ 9503 {
9504 IPW_PRIV_SW_RESET,
9505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
9506#ifdef CONFIG_IPW2200_MONITOR
9507 {
9508 IPW_PRIV_SET_MONITOR,
9509 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
9510#endif /* CONFIG_IPW2200_MONITOR */
6215}; 9511};
6216 9512
6217static iw_handler ipw_priv_handler[] = { 9513static iw_handler ipw_priv_handler[] = {
@@ -6219,19 +9515,23 @@ static iw_handler ipw_priv_handler[] = {
6219 ipw_wx_get_powermode, 9515 ipw_wx_get_powermode,
6220 ipw_wx_set_wireless_mode, 9516 ipw_wx_set_wireless_mode,
6221 ipw_wx_get_wireless_mode, 9517 ipw_wx_get_wireless_mode,
6222#ifdef CONFIG_IPW_PROMISC 9518 ipw_wx_set_preamble,
6223 ipw_wx_set_promisc, 9519 ipw_wx_get_preamble,
6224 ipw_wx_reset, 9520 ipw_wx_reset,
9521 ipw_wx_sw_reset,
9522#ifdef CONFIG_IPW2200_MONITOR
9523 ipw_wx_set_monitor,
6225#endif 9524#endif
6226}; 9525};
6227 9526
6228static struct iw_handler_def ipw_wx_handler_def = { 9527static struct iw_handler_def ipw_wx_handler_def = {
6229 .standard = ipw_wx_handlers, 9528 .standard = ipw_wx_handlers,
6230 .num_standard = ARRAY_SIZE(ipw_wx_handlers), 9529 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
6231 .num_private = ARRAY_SIZE(ipw_priv_handler), 9530 .num_private = ARRAY_SIZE(ipw_priv_handler),
6232 .num_private_args = ARRAY_SIZE(ipw_priv_args), 9531 .num_private_args = ARRAY_SIZE(ipw_priv_args),
6233 .private = ipw_priv_handler, 9532 .private = ipw_priv_handler,
6234 .private_args = ipw_priv_args, 9533 .private_args = ipw_priv_args,
9534 .get_wireless_stats = ipw_get_wireless_stats,
6235}; 9535};
6236 9536
6237/* 9537/*
@@ -6246,8 +9546,8 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
6246 9546
6247 wstats = &priv->wstats; 9547 wstats = &priv->wstats;
6248 9548
6249 /* if hw is disabled, then ipw2100_get_ordinal() can't be called. 9549 /* if hw is disabled, then ipw_get_ordinal() can't be called.
6250 * ipw2100_wx_wireless_stats seems to be called before fw is 9550 * netdev->get_wireless_stats seems to be called before fw is
6251 * initialized. STATUS_ASSOCIATED will only be set if the hw is up 9551 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
6252 * and associated; if not associcated, the values are all meaningless 9552 * and associated; if not associcated, the values are all meaningless
6253 * anyway, so set them all to NULL and INVALID */ 9553 * anyway, so set them all to NULL and INVALID */
@@ -6298,7 +9598,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config)
6298 sys_config->dot11g_auto_detection = 0; 9598 sys_config->dot11g_auto_detection = 0;
6299 sys_config->enable_cts_to_self = 0; 9599 sys_config->enable_cts_to_self = 0;
6300 sys_config->bt_coexist_collision_thr = 0; 9600 sys_config->bt_coexist_collision_thr = 0;
6301 sys_config->pass_noise_stats_to_host = 1; 9601 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
6302} 9602}
6303 9603
6304static int ipw_net_open(struct net_device *dev) 9604static int ipw_net_open(struct net_device *dev)
@@ -6306,9 +9606,11 @@ static int ipw_net_open(struct net_device *dev)
6306 struct ipw_priv *priv = ieee80211_priv(dev); 9606 struct ipw_priv *priv = ieee80211_priv(dev);
6307 IPW_DEBUG_INFO("dev->open\n"); 9607 IPW_DEBUG_INFO("dev->open\n");
6308 /* we should be verifying the device is ready to be opened */ 9608 /* we should be verifying the device is ready to be opened */
9609 down(&priv->sem);
6309 if (!(priv->status & STATUS_RF_KILL_MASK) && 9610 if (!(priv->status & STATUS_RF_KILL_MASK) &&
6310 (priv->status & STATUS_ASSOCIATED)) 9611 (priv->status & STATUS_ASSOCIATED))
6311 netif_start_queue(dev); 9612 netif_start_queue(dev);
9613 up(&priv->sem);
6312 return 0; 9614 return 0;
6313} 9615}
6314 9616
@@ -6326,22 +9628,34 @@ modify to send one tfd per fragment instead of using chunking. otherwise
6326we need to heavily modify the ieee80211_skb_to_txb. 9628we need to heavily modify the ieee80211_skb_to_txb.
6327*/ 9629*/
6328 9630
6329static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) 9631static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9632 int pri)
6330{ 9633{
6331 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) 9634 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
6332 txb->fragments[0]->data; 9635 txb->fragments[0]->data;
6333 int i = 0; 9636 int i = 0;
6334 struct tfd_frame *tfd; 9637 struct tfd_frame *tfd;
9638#ifdef CONFIG_IPW_QOS
9639 int tx_id = ipw_get_tx_queue_number(priv, pri);
9640 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9641#else
6335 struct clx2_tx_queue *txq = &priv->txq[0]; 9642 struct clx2_tx_queue *txq = &priv->txq[0];
9643#endif
6336 struct clx2_queue *q = &txq->q; 9644 struct clx2_queue *q = &txq->q;
6337 u8 id, hdr_len, unicast; 9645 u8 id, hdr_len, unicast;
6338 u16 remaining_bytes; 9646 u16 remaining_bytes;
9647 int fc;
9648
9649 /* If there isn't room in the queue, we return busy and let the
9650 * network stack requeue the packet for us */
9651 if (ipw_queue_space(q) < q->high_mark)
9652 return NETDEV_TX_BUSY;
6339 9653
6340 switch (priv->ieee->iw_mode) { 9654 switch (priv->ieee->iw_mode) {
6341 case IW_MODE_ADHOC: 9655 case IW_MODE_ADHOC:
6342 hdr_len = IEEE80211_3ADDR_LEN; 9656 hdr_len = IEEE80211_3ADDR_LEN;
6343 unicast = !is_broadcast_ether_addr(hdr->addr1) && 9657 unicast = !(is_multicast_ether_addr(hdr->addr1) ||
6344 !is_multicast_ether_addr(hdr->addr1); 9658 is_broadcast_ether_addr(hdr->addr1));
6345 id = ipw_find_station(priv, hdr->addr1); 9659 id = ipw_find_station(priv, hdr->addr1);
6346 if (id == IPW_INVALID_STATION) { 9660 if (id == IPW_INVALID_STATION) {
6347 id = ipw_add_station(priv, hdr->addr1); 9661 id = ipw_add_station(priv, hdr->addr1);
@@ -6356,8 +9670,8 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6356 9670
6357 case IW_MODE_INFRA: 9671 case IW_MODE_INFRA:
6358 default: 9672 default:
6359 unicast = !is_broadcast_ether_addr(hdr->addr3) && 9673 unicast = !(is_multicast_ether_addr(hdr->addr3) ||
6360 !is_multicast_ether_addr(hdr->addr3); 9674 is_broadcast_ether_addr(hdr->addr3));
6361 hdr_len = IEEE80211_3ADDR_LEN; 9675 hdr_len = IEEE80211_3ADDR_LEN;
6362 id = 0; 9676 id = 0;
6363 break; 9677 break;
@@ -6372,26 +9686,83 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6372 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK; 9686 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
6373 9687
6374 tfd->u.data.cmd_id = DINO_CMD_TX; 9688 tfd->u.data.cmd_id = DINO_CMD_TX;
6375 tfd->u.data.len = txb->payload_size; 9689 tfd->u.data.len = cpu_to_le16(txb->payload_size);
6376 remaining_bytes = txb->payload_size; 9690 remaining_bytes = txb->payload_size;
6377 if (unlikely(!unicast))
6378 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
6379 else
6380 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD;
6381 9691
6382 if (priv->assoc_request.ieee_mode == IPW_B_MODE) 9692 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
6383 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK; 9693 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
6384 else 9694 else
6385 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM; 9695 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
6386 9696
6387 if (priv->config & CFG_PREAMBLE) 9697 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
6388 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL; 9698 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
9699
9700 fc = le16_to_cpu(hdr->frame_ctl);
9701 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
6389 9702
6390 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); 9703 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
6391 9704
9705 if (likely(unicast))
9706 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9707
9708 if (txb->encrypted && !priv->ieee->host_encrypt) {
9709 switch (priv->ieee->sec.level) {
9710 case SEC_LEVEL_3:
9711 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9712 IEEE80211_FCTL_PROTECTED;
9713 /* XXX: ACK flag must be set for CCMP even if it
9714 * is a multicast/broadcast packet, because CCMP
9715 * group communication encrypted by GTK is
9716 * actually done by the AP. */
9717 if (!unicast)
9718 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9719
9720 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9721 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
9722 tfd->u.data.key_index = 0;
9723 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
9724 break;
9725 case SEC_LEVEL_2:
9726 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9727 IEEE80211_FCTL_PROTECTED;
9728 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9729 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
9730 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
9731 break;
9732 case SEC_LEVEL_1:
9733 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9734 IEEE80211_FCTL_PROTECTED;
9735 tfd->u.data.key_index = priv->ieee->tx_keyidx;
9736 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
9737 40)
9738 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
9739 else
9740 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
9741 break;
9742 case SEC_LEVEL_0:
9743 break;
9744 default:
9745 printk(KERN_ERR "Unknow security level %d\n",
9746 priv->ieee->sec.level);
9747 break;
9748 }
9749 } else
9750 /* No hardware encryption */
9751 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
9752
9753#ifdef CONFIG_IPW_QOS
9754 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast);
9755#endif /* CONFIG_IPW_QOS */
9756
6392 /* payload */ 9757 /* payload */
6393 tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags); 9758 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
6394 for (i = 0; i < tfd->u.data.num_chunks; i++) { 9759 txb->nr_frags));
9760 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
9761 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
9762 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
9763 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
9764 i, le32_to_cpu(tfd->u.data.num_chunks),
9765 txb->fragments[i]->len - hdr_len);
6395 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", 9766 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
6396 i, tfd->u.data.num_chunks, 9767 i, tfd->u.data.num_chunks,
6397 txb->fragments[i]->len - hdr_len); 9768 txb->fragments[i]->len - hdr_len);
@@ -6399,11 +9770,13 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6399 txb->fragments[i]->len - hdr_len); 9770 txb->fragments[i]->len - hdr_len);
6400 9771
6401 tfd->u.data.chunk_ptr[i] = 9772 tfd->u.data.chunk_ptr[i] =
6402 pci_map_single(priv->pci_dev, 9773 cpu_to_le32(pci_map_single
6403 txb->fragments[i]->data + hdr_len, 9774 (priv->pci_dev,
6404 txb->fragments[i]->len - hdr_len, 9775 txb->fragments[i]->data + hdr_len,
6405 PCI_DMA_TODEVICE); 9776 txb->fragments[i]->len - hdr_len,
6406 tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len; 9777 PCI_DMA_TODEVICE));
9778 tfd->u.data.chunk_len[i] =
9779 cpu_to_le16(txb->fragments[i]->len - hdr_len);
6407 } 9780 }
6408 9781
6409 if (i != txb->nr_frags) { 9782 if (i != txb->nr_frags) {
@@ -6418,9 +9791,10 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6418 remaining_bytes); 9791 remaining_bytes);
6419 skb = alloc_skb(remaining_bytes, GFP_ATOMIC); 9792 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
6420 if (skb != NULL) { 9793 if (skb != NULL) {
6421 tfd->u.data.chunk_len[i] = remaining_bytes; 9794 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
6422 for (j = i; j < txb->nr_frags; j++) { 9795 for (j = i; j < txb->nr_frags; j++) {
6423 int size = txb->fragments[j]->len - hdr_len; 9796 int size = txb->fragments[j]->len - hdr_len;
9797
6424 printk(KERN_INFO "Adding frag %d %d...\n", 9798 printk(KERN_INFO "Adding frag %d %d...\n",
6425 j, size); 9799 j, size);
6426 memcpy(skb_put(skb, size), 9800 memcpy(skb_put(skb, size),
@@ -6429,10 +9803,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6429 dev_kfree_skb_any(txb->fragments[i]); 9803 dev_kfree_skb_any(txb->fragments[i]);
6430 txb->fragments[i] = skb; 9804 txb->fragments[i] = skb;
6431 tfd->u.data.chunk_ptr[i] = 9805 tfd->u.data.chunk_ptr[i] =
6432 pci_map_single(priv->pci_dev, skb->data, 9806 cpu_to_le32(pci_map_single
6433 tfd->u.data.chunk_len[i], 9807 (priv->pci_dev, skb->data,
6434 PCI_DMA_TODEVICE); 9808 tfd->u.data.chunk_len[i],
6435 tfd->u.data.num_chunks++; 9809 PCI_DMA_TODEVICE));
9810
9811 tfd->u.data.num_chunks =
9812 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
9813 1);
6436 } 9814 }
6437 } 9815 }
6438 9816
@@ -6440,14 +9818,28 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6440 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); 9818 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
6441 ipw_write32(priv, q->reg_w, q->first_empty); 9819 ipw_write32(priv, q->reg_w, q->first_empty);
6442 9820
6443 if (ipw_queue_space(q) < q->high_mark) 9821 return NETDEV_TX_OK;
6444 netif_stop_queue(priv->net_dev);
6445
6446 return;
6447 9822
6448 drop: 9823 drop:
6449 IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); 9824 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
6450 ieee80211_txb_free(txb); 9825 ieee80211_txb_free(txb);
9826 return NETDEV_TX_OK;
9827}
9828
9829static int ipw_net_is_queue_full(struct net_device *dev, int pri)
9830{
9831 struct ipw_priv *priv = ieee80211_priv(dev);
9832#ifdef CONFIG_IPW_QOS
9833 int tx_id = ipw_get_tx_queue_number(priv, pri);
9834 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9835#else
9836 struct clx2_tx_queue *txq = &priv->txq[0];
9837#endif /* CONFIG_IPW_QOS */
9838
9839 if (ipw_queue_space(&txq->q) < txq->q.high_mark)
9840 return 1;
9841
9842 return 0;
6451} 9843}
6452 9844
6453static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, 9845static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
@@ -6455,9 +9847,9 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6455{ 9847{
6456 struct ipw_priv *priv = ieee80211_priv(dev); 9848 struct ipw_priv *priv = ieee80211_priv(dev);
6457 unsigned long flags; 9849 unsigned long flags;
9850 int ret;
6458 9851
6459 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size); 9852 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
6460
6461 spin_lock_irqsave(&priv->lock, flags); 9853 spin_lock_irqsave(&priv->lock, flags);
6462 9854
6463 if (!(priv->status & STATUS_ASSOCIATED)) { 9855 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -6467,10 +9859,12 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6467 goto fail_unlock; 9859 goto fail_unlock;
6468 } 9860 }
6469 9861
6470 ipw_tx_skb(priv, txb); 9862 ret = ipw_tx_skb(priv, txb, pri);
6471 9863 if (ret == NETDEV_TX_OK)
9864 __ipw_led_activity_on(priv);
6472 spin_unlock_irqrestore(&priv->lock, flags); 9865 spin_unlock_irqrestore(&priv->lock, flags);
6473 return 0; 9866
9867 return ret;
6474 9868
6475 fail_unlock: 9869 fail_unlock:
6476 spin_unlock_irqrestore(&priv->lock, flags); 9870 spin_unlock_irqrestore(&priv->lock, flags);
@@ -6497,11 +9891,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
6497 struct sockaddr *addr = p; 9891 struct sockaddr *addr = p;
6498 if (!is_valid_ether_addr(addr->sa_data)) 9892 if (!is_valid_ether_addr(addr->sa_data))
6499 return -EADDRNOTAVAIL; 9893 return -EADDRNOTAVAIL;
9894 down(&priv->sem);
6500 priv->config |= CFG_CUSTOM_MAC; 9895 priv->config |= CFG_CUSTOM_MAC;
6501 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); 9896 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
6502 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", 9897 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
6503 priv->net_dev->name, MAC_ARG(priv->mac_addr)); 9898 priv->net_dev->name, MAC_ARG(priv->mac_addr));
6504 ipw_adapter_restart(priv); 9899 queue_work(priv->workqueue, &priv->adapter_restart);
9900 up(&priv->sem);
6505 return 0; 9901 return 0;
6506} 9902}
6507 9903
@@ -6524,7 +9920,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6524 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)", 9920 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
6525 vers, date); 9921 vers, date);
6526 strcpy(info->bus_info, pci_name(p->pci_dev)); 9922 strcpy(info->bus_info, pci_name(p->pci_dev));
6527 info->eedump_len = CX2_EEPROM_IMAGE_SIZE; 9923 info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
6528} 9924}
6529 9925
6530static u32 ipw_ethtool_get_link(struct net_device *dev) 9926static u32 ipw_ethtool_get_link(struct net_device *dev)
@@ -6535,7 +9931,7 @@ static u32 ipw_ethtool_get_link(struct net_device *dev)
6535 9931
6536static int ipw_ethtool_get_eeprom_len(struct net_device *dev) 9932static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
6537{ 9933{
6538 return CX2_EEPROM_IMAGE_SIZE; 9934 return IPW_EEPROM_IMAGE_SIZE;
6539} 9935}
6540 9936
6541static int ipw_ethtool_get_eeprom(struct net_device *dev, 9937static int ipw_ethtool_get_eeprom(struct net_device *dev,
@@ -6543,10 +9939,11 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
6543{ 9939{
6544 struct ipw_priv *p = ieee80211_priv(dev); 9940 struct ipw_priv *p = ieee80211_priv(dev);
6545 9941
6546 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9942 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6547 return -EINVAL; 9943 return -EINVAL;
6548 9944 down(&p->sem);
6549 memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len); 9945 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
9946 up(&p->sem);
6550 return 0; 9947 return 0;
6551} 9948}
6552 9949
@@ -6556,23 +9953,23 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
6556 struct ipw_priv *p = ieee80211_priv(dev); 9953 struct ipw_priv *p = ieee80211_priv(dev);
6557 int i; 9954 int i;
6558 9955
6559 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9956 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6560 return -EINVAL; 9957 return -EINVAL;
6561 9958 down(&p->sem);
6562 memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len); 9959 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
6563 for (i = IPW_EEPROM_DATA; 9960 for (i = IPW_EEPROM_DATA;
6564 i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++) 9961 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
6565 ipw_write8(p, i, p->eeprom[i]); 9962 ipw_write8(p, i, p->eeprom[i]);
6566 9963 up(&p->sem);
6567 return 0; 9964 return 0;
6568} 9965}
6569 9966
6570static struct ethtool_ops ipw_ethtool_ops = { 9967static struct ethtool_ops ipw_ethtool_ops = {
6571 .get_link = ipw_ethtool_get_link, 9968 .get_link = ipw_ethtool_get_link,
6572 .get_drvinfo = ipw_ethtool_get_drvinfo, 9969 .get_drvinfo = ipw_ethtool_get_drvinfo,
6573 .get_eeprom_len = ipw_ethtool_get_eeprom_len, 9970 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
6574 .get_eeprom = ipw_ethtool_get_eeprom, 9971 .get_eeprom = ipw_ethtool_get_eeprom,
6575 .set_eeprom = ipw_ethtool_set_eeprom, 9972 .set_eeprom = ipw_ethtool_set_eeprom,
6576}; 9973};
6577 9974
6578static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) 9975static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
@@ -6590,8 +9987,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6590 goto none; 9987 goto none;
6591 } 9988 }
6592 9989
6593 inta = ipw_read32(priv, CX2_INTA_RW); 9990 inta = ipw_read32(priv, IPW_INTA_RW);
6594 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 9991 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
6595 9992
6596 if (inta == 0xFFFFFFFF) { 9993 if (inta == 0xFFFFFFFF) {
6597 /* Hardware disappeared */ 9994 /* Hardware disappeared */
@@ -6599,7 +9996,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6599 goto none; 9996 goto none;
6600 } 9997 }
6601 9998
6602 if (!(inta & (CX2_INTA_MASK_ALL & inta_mask))) { 9999 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
6603 /* Shared interrupt */ 10000 /* Shared interrupt */
6604 goto none; 10001 goto none;
6605 } 10002 }
@@ -6608,8 +10005,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6608 ipw_disable_interrupts(priv); 10005 ipw_disable_interrupts(priv);
6609 10006
6610 /* ack current interrupts */ 10007 /* ack current interrupts */
6611 inta &= (CX2_INTA_MASK_ALL & inta_mask); 10008 inta &= (IPW_INTA_MASK_ALL & inta_mask);
6612 ipw_write32(priv, CX2_INTA_RW, inta); 10009 ipw_write32(priv, IPW_INTA_RW, inta);
6613 10010
6614 /* Cache INTA value for our tasklet */ 10011 /* Cache INTA value for our tasklet */
6615 priv->isr_inta = inta; 10012 priv->isr_inta = inta;
@@ -6655,28 +10052,116 @@ static void ipw_rf_kill(void *adapter)
6655 spin_unlock_irqrestore(&priv->lock, flags); 10052 spin_unlock_irqrestore(&priv->lock, flags);
6656} 10053}
6657 10054
10055static void ipw_bg_rf_kill(void *data)
10056{
10057 struct ipw_priv *priv = data;
10058 down(&priv->sem);
10059 ipw_rf_kill(data);
10060 up(&priv->sem);
10061}
10062
10063void ipw_link_up(struct ipw_priv *priv)
10064{
10065 priv->last_seq_num = -1;
10066 priv->last_frag_num = -1;
10067 priv->last_packet_time = 0;
10068
10069 netif_carrier_on(priv->net_dev);
10070 if (netif_queue_stopped(priv->net_dev)) {
10071 IPW_DEBUG_NOTIF("waking queue\n");
10072 netif_wake_queue(priv->net_dev);
10073 } else {
10074 IPW_DEBUG_NOTIF("starting queue\n");
10075 netif_start_queue(priv->net_dev);
10076 }
10077
10078 cancel_delayed_work(&priv->request_scan);
10079 ipw_reset_stats(priv);
10080 /* Ensure the rate is updated immediately */
10081 priv->last_rate = ipw_get_current_rate(priv);
10082 ipw_gather_stats(priv);
10083 ipw_led_link_up(priv);
10084 notify_wx_assoc_event(priv);
10085
10086 if (priv->config & CFG_BACKGROUND_SCAN)
10087 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
10088}
10089
10090static void ipw_bg_link_up(void *data)
10091{
10092 struct ipw_priv *priv = data;
10093 down(&priv->sem);
10094 ipw_link_up(data);
10095 up(&priv->sem);
10096}
10097
10098void ipw_link_down(struct ipw_priv *priv)
10099{
10100 ipw_led_link_down(priv);
10101 netif_carrier_off(priv->net_dev);
10102 netif_stop_queue(priv->net_dev);
10103 notify_wx_assoc_event(priv);
10104
10105 /* Cancel any queued work ... */
10106 cancel_delayed_work(&priv->request_scan);
10107 cancel_delayed_work(&priv->adhoc_check);
10108 cancel_delayed_work(&priv->gather_stats);
10109
10110 ipw_reset_stats(priv);
10111
10112 if (!(priv->status & STATUS_EXIT_PENDING)) {
10113 /* Queue up another scan... */
10114 queue_work(priv->workqueue, &priv->request_scan);
10115 }
10116}
10117
10118static void ipw_bg_link_down(void *data)
10119{
10120 struct ipw_priv *priv = data;
10121 down(&priv->sem);
10122 ipw_link_down(data);
10123 up(&priv->sem);
10124}
10125
6658static int ipw_setup_deferred_work(struct ipw_priv *priv) 10126static int ipw_setup_deferred_work(struct ipw_priv *priv)
6659{ 10127{
6660 int ret = 0; 10128 int ret = 0;
6661 10129
6662 priv->workqueue = create_workqueue(DRV_NAME); 10130 priv->workqueue = create_workqueue(DRV_NAME);
6663 init_waitqueue_head(&priv->wait_command_queue); 10131 init_waitqueue_head(&priv->wait_command_queue);
6664 10132 init_waitqueue_head(&priv->wait_state);
6665 INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv); 10133
6666 INIT_WORK(&priv->associate, ipw_associate, priv); 10134 INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
6667 INIT_WORK(&priv->disassociate, ipw_disassociate, priv); 10135 INIT_WORK(&priv->associate, ipw_bg_associate, priv);
6668 INIT_WORK(&priv->rx_replenish, ipw_rx_queue_replenish, priv); 10136 INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
6669 INIT_WORK(&priv->adapter_restart, ipw_adapter_restart, priv); 10137 INIT_WORK(&priv->system_config, ipw_system_config, priv);
6670 INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv); 10138 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
6671 INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv); 10139 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
6672 INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv); 10140 INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
10141 INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
10142 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
6673 INIT_WORK(&priv->request_scan, 10143 INIT_WORK(&priv->request_scan,
6674 (void (*)(void *))ipw_request_scan, priv); 10144 (void (*)(void *))ipw_request_scan, priv);
6675 INIT_WORK(&priv->gather_stats, 10145 INIT_WORK(&priv->gather_stats,
6676 (void (*)(void *))ipw_gather_stats, priv); 10146 (void (*)(void *))ipw_bg_gather_stats, priv);
6677 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv); 10147 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
6678 INIT_WORK(&priv->roam, ipw_roam, priv); 10148 INIT_WORK(&priv->roam, ipw_bg_roam, priv);
6679 INIT_WORK(&priv->scan_check, ipw_scan_check, priv); 10149 INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
10150 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
10151 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
10152 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
10153 priv);
10154 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
10155 priv);
10156 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
10157 priv);
10158 INIT_WORK(&priv->merge_networks,
10159 (void (*)(void *))ipw_merge_adhoc_network, priv);
10160
10161#ifdef CONFIG_IPW_QOS
10162 INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
10163 priv);
10164#endif /* CONFIG_IPW_QOS */
6680 10165
6681 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 10166 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6682 ipw_irq_tasklet, (unsigned long)priv); 10167 ipw_irq_tasklet, (unsigned long)priv);
@@ -6689,34 +10174,36 @@ static void shim__set_security(struct net_device *dev,
6689{ 10174{
6690 struct ipw_priv *priv = ieee80211_priv(dev); 10175 struct ipw_priv *priv = ieee80211_priv(dev);
6691 int i; 10176 int i;
6692
6693 for (i = 0; i < 4; i++) { 10177 for (i = 0; i < 4; i++) {
6694 if (sec->flags & (1 << i)) { 10178 if (sec->flags & (1 << i)) {
6695 priv->sec.key_sizes[i] = sec->key_sizes[i]; 10179 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
10180 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
6696 if (sec->key_sizes[i] == 0) 10181 if (sec->key_sizes[i] == 0)
6697 priv->sec.flags &= ~(1 << i); 10182 priv->ieee->sec.flags &= ~(1 << i);
6698 else 10183 else {
6699 memcpy(priv->sec.keys[i], sec->keys[i], 10184 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
6700 sec->key_sizes[i]); 10185 sec->key_sizes[i]);
6701 priv->sec.flags |= (1 << i); 10186 priv->ieee->sec.flags |= (1 << i);
10187 }
6702 priv->status |= STATUS_SECURITY_UPDATED; 10188 priv->status |= STATUS_SECURITY_UPDATED;
6703 } 10189 } else if (sec->level != SEC_LEVEL_1)
10190 priv->ieee->sec.flags &= ~(1 << i);
6704 } 10191 }
6705 10192
6706 if ((sec->flags & SEC_ACTIVE_KEY) && 10193 if (sec->flags & SEC_ACTIVE_KEY) {
6707 priv->sec.active_key != sec->active_key) {
6708 if (sec->active_key <= 3) { 10194 if (sec->active_key <= 3) {
6709 priv->sec.active_key = sec->active_key; 10195 priv->ieee->sec.active_key = sec->active_key;
6710 priv->sec.flags |= SEC_ACTIVE_KEY; 10196 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
6711 } else 10197 } else
6712 priv->sec.flags &= ~SEC_ACTIVE_KEY; 10198 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6713 priv->status |= STATUS_SECURITY_UPDATED; 10199 priv->status |= STATUS_SECURITY_UPDATED;
6714 } 10200 } else
10201 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6715 10202
6716 if ((sec->flags & SEC_AUTH_MODE) && 10203 if ((sec->flags & SEC_AUTH_MODE) &&
6717 (priv->sec.auth_mode != sec->auth_mode)) { 10204 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
6718 priv->sec.auth_mode = sec->auth_mode; 10205 priv->ieee->sec.auth_mode = sec->auth_mode;
6719 priv->sec.flags |= SEC_AUTH_MODE; 10206 priv->ieee->sec.flags |= SEC_AUTH_MODE;
6720 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY) 10207 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
6721 priv->capability |= CAP_SHARED_KEY; 10208 priv->capability |= CAP_SHARED_KEY;
6722 else 10209 else
@@ -6724,9 +10211,9 @@ static void shim__set_security(struct net_device *dev,
6724 priv->status |= STATUS_SECURITY_UPDATED; 10211 priv->status |= STATUS_SECURITY_UPDATED;
6725 } 10212 }
6726 10213
6727 if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) { 10214 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
6728 priv->sec.flags |= SEC_ENABLED; 10215 priv->ieee->sec.flags |= SEC_ENABLED;
6729 priv->sec.enabled = sec->enabled; 10216 priv->ieee->sec.enabled = sec->enabled;
6730 priv->status |= STATUS_SECURITY_UPDATED; 10217 priv->status |= STATUS_SECURITY_UPDATED;
6731 if (sec->enabled) 10218 if (sec->enabled)
6732 priv->capability |= CAP_PRIVACY_ON; 10219 priv->capability |= CAP_PRIVACY_ON;
@@ -6734,12 +10221,18 @@ static void shim__set_security(struct net_device *dev,
6734 priv->capability &= ~CAP_PRIVACY_ON; 10221 priv->capability &= ~CAP_PRIVACY_ON;
6735 } 10222 }
6736 10223
6737 if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) { 10224 if (sec->flags & SEC_ENCRYPT)
6738 priv->sec.level = sec->level; 10225 priv->ieee->sec.encrypt = sec->encrypt;
6739 priv->sec.flags |= SEC_LEVEL; 10226
10227 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
10228 priv->ieee->sec.level = sec->level;
10229 priv->ieee->sec.flags |= SEC_LEVEL;
6740 priv->status |= STATUS_SECURITY_UPDATED; 10230 priv->status |= STATUS_SECURITY_UPDATED;
6741 } 10231 }
6742 10232
10233 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
10234 ipw_set_hwcrypto_keys(priv);
10235
6743 /* To match current functionality of ipw2100 (which works well w/ 10236 /* To match current functionality of ipw2100 (which works well w/
6744 * various supplicants, we don't force a disassociate if the 10237 * various supplicants, we don't force a disassociate if the
6745 * privacy capability changes ... */ 10238 * privacy capability changes ... */
@@ -6788,29 +10281,10 @@ static int init_supported_rates(struct ipw_priv *priv,
6788 10281
6789static int ipw_config(struct ipw_priv *priv) 10282static int ipw_config(struct ipw_priv *priv)
6790{ 10283{
6791 int i;
6792 struct ipw_tx_power tx_power;
6793
6794 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
6795 memset(&tx_power, 0, sizeof(tx_power));
6796
6797 /* This is only called from ipw_up, which resets/reloads the firmware 10284 /* This is only called from ipw_up, which resets/reloads the firmware
6798 so, we don't need to first disable the card before we configure 10285 so, we don't need to first disable the card before we configure
6799 it */ 10286 it */
6800 10287 if (ipw_set_tx_power(priv))
6801 /* configure device for 'G' band */
6802 tx_power.ieee_mode = IPW_G_MODE;
6803 tx_power.num_channels = 11;
6804 for (i = 0; i < 11; i++) {
6805 tx_power.channels_tx_power[i].channel_number = i + 1;
6806 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
6807 }
6808 if (ipw_send_tx_power(priv, &tx_power))
6809 goto error;
6810
6811 /* configure device to also handle 'B' band */
6812 tx_power.ieee_mode = IPW_B_MODE;
6813 if (ipw_send_tx_power(priv, &tx_power))
6814 goto error; 10288 goto error;
6815 10289
6816 /* initialize adapter address */ 10290 /* initialize adapter address */
@@ -6819,6 +10293,11 @@ static int ipw_config(struct ipw_priv *priv)
6819 10293
6820 /* set basic system config settings */ 10294 /* set basic system config settings */
6821 init_sys_config(&priv->sys_config); 10295 init_sys_config(&priv->sys_config);
10296 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10297 priv->sys_config.answer_broadcast_ssid_probe = 1;
10298 else
10299 priv->sys_config.answer_broadcast_ssid_probe = 0;
10300
6822 if (ipw_send_system_config(priv, &priv->sys_config)) 10301 if (ipw_send_system_config(priv, &priv->sys_config))
6823 goto error; 10302 goto error;
6824 10303
@@ -6831,6 +10310,10 @@ static int ipw_config(struct ipw_priv *priv)
6831 if (ipw_send_rts_threshold(priv, priv->rts_threshold)) 10310 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
6832 goto error; 10311 goto error;
6833 } 10312 }
10313#ifdef CONFIG_IPW_QOS
10314 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
10315 ipw_qos_activate(priv, NULL);
10316#endif /* CONFIG_IPW_QOS */
6834 10317
6835 if (ipw_set_random_seed(priv)) 10318 if (ipw_set_random_seed(priv))
6836 goto error; 10319 goto error;
@@ -6839,9 +10322,17 @@ static int ipw_config(struct ipw_priv *priv)
6839 if (ipw_send_host_complete(priv)) 10322 if (ipw_send_host_complete(priv))
6840 goto error; 10323 goto error;
6841 10324
6842 /* If configured to try and auto-associate, kick off a scan */ 10325 priv->status |= STATUS_INIT;
6843 if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv)) 10326
6844 goto error; 10327 ipw_led_init(priv);
10328 ipw_led_radio_on(priv);
10329 priv->notif_missed_beacons = 0;
10330
10331 /* Set hardware WEP key if it is configured. */
10332 if ((priv->capability & CAP_PRIVACY_ON) &&
10333 (priv->ieee->sec.level == SEC_LEVEL_1) &&
10334 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
10335 ipw_set_hwcrypto_keys(priv);
6845 10336
6846 return 0; 10337 return 0;
6847 10338
@@ -6849,20 +10340,379 @@ static int ipw_config(struct ipw_priv *priv)
6849 return -EIO; 10340 return -EIO;
6850} 10341}
6851 10342
10343/*
10344 * NOTE:
10345 *
10346 * These tables have been tested in conjunction with the
10347 * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
10348 *
10349 * Altering this values, using it on other hardware, or in geographies
10350 * not intended for resale of the above mentioned Intel adapters has
10351 * not been tested.
10352 *
10353 */
10354static const struct ieee80211_geo ipw_geos[] = {
10355 { /* Restricted */
10356 "---",
10357 .bg_channels = 11,
10358 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10359 {2427, 4}, {2432, 5}, {2437, 6},
10360 {2442, 7}, {2447, 8}, {2452, 9},
10361 {2457, 10}, {2462, 11}},
10362 },
10363
10364 { /* Custom US/Canada */
10365 "ZZF",
10366 .bg_channels = 11,
10367 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10368 {2427, 4}, {2432, 5}, {2437, 6},
10369 {2442, 7}, {2447, 8}, {2452, 9},
10370 {2457, 10}, {2462, 11}},
10371 .a_channels = 8,
10372 .a = {{5180, 36},
10373 {5200, 40},
10374 {5220, 44},
10375 {5240, 48},
10376 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10377 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10378 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10379 {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
10380 },
10381
10382 { /* Rest of World */
10383 "ZZD",
10384 .bg_channels = 13,
10385 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10386 {2427, 4}, {2432, 5}, {2437, 6},
10387 {2442, 7}, {2447, 8}, {2452, 9},
10388 {2457, 10}, {2462, 11}, {2467, 12},
10389 {2472, 13}},
10390 },
10391
10392 { /* Custom USA & Europe & High */
10393 "ZZA",
10394 .bg_channels = 11,
10395 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10396 {2427, 4}, {2432, 5}, {2437, 6},
10397 {2442, 7}, {2447, 8}, {2452, 9},
10398 {2457, 10}, {2462, 11}},
10399 .a_channels = 13,
10400 .a = {{5180, 36},
10401 {5200, 40},
10402 {5220, 44},
10403 {5240, 48},
10404 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10405 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10406 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10407 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10408 {5745, 149},
10409 {5765, 153},
10410 {5785, 157},
10411 {5805, 161},
10412 {5825, 165}},
10413 },
10414
10415 { /* Custom NA & Europe */
10416 "ZZB",
10417 .bg_channels = 11,
10418 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10419 {2427, 4}, {2432, 5}, {2437, 6},
10420 {2442, 7}, {2447, 8}, {2452, 9},
10421 {2457, 10}, {2462, 11}},
10422 .a_channels = 13,
10423 .a = {{5180, 36},
10424 {5200, 40},
10425 {5220, 44},
10426 {5240, 48},
10427 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10428 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10429 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10430 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10431 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10432 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10433 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10434 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10435 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10436 },
10437
10438 { /* Custom Japan */
10439 "ZZC",
10440 .bg_channels = 11,
10441 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10442 {2427, 4}, {2432, 5}, {2437, 6},
10443 {2442, 7}, {2447, 8}, {2452, 9},
10444 {2457, 10}, {2462, 11}},
10445 .a_channels = 4,
10446 .a = {{5170, 34}, {5190, 38},
10447 {5210, 42}, {5230, 46}},
10448 },
10449
10450 { /* Custom */
10451 "ZZM",
10452 .bg_channels = 11,
10453 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10454 {2427, 4}, {2432, 5}, {2437, 6},
10455 {2442, 7}, {2447, 8}, {2452, 9},
10456 {2457, 10}, {2462, 11}},
10457 },
10458
10459 { /* Europe */
10460 "ZZE",
10461 .bg_channels = 13,
10462 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10463 {2427, 4}, {2432, 5}, {2437, 6},
10464 {2442, 7}, {2447, 8}, {2452, 9},
10465 {2457, 10}, {2462, 11}, {2467, 12},
10466 {2472, 13}},
10467 .a_channels = 19,
10468 .a = {{5180, 36},
10469 {5200, 40},
10470 {5220, 44},
10471 {5240, 48},
10472 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10473 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10474 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10475 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10476 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10477 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10478 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10479 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10480 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10481 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10482 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10483 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10484 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10485 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10486 {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
10487 },
10488
10489 { /* Custom Japan */
10490 "ZZJ",
10491 .bg_channels = 14,
10492 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10493 {2427, 4}, {2432, 5}, {2437, 6},
10494 {2442, 7}, {2447, 8}, {2452, 9},
10495 {2457, 10}, {2462, 11}, {2467, 12},
10496 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
10497 .a_channels = 4,
10498 .a = {{5170, 34}, {5190, 38},
10499 {5210, 42}, {5230, 46}},
10500 },
10501
10502 { /* Rest of World */
10503 "ZZR",
10504 .bg_channels = 14,
10505 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10506 {2427, 4}, {2432, 5}, {2437, 6},
10507 {2442, 7}, {2447, 8}, {2452, 9},
10508 {2457, 10}, {2462, 11}, {2467, 12},
10509 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY |
10510 IEEE80211_CH_PASSIVE_ONLY}},
10511 },
10512
10513 { /* High Band */
10514 "ZZH",
10515 .bg_channels = 13,
10516 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10517 {2427, 4}, {2432, 5}, {2437, 6},
10518 {2442, 7}, {2447, 8}, {2452, 9},
10519 {2457, 10}, {2462, 11},
10520 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10521 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10522 .a_channels = 4,
10523 .a = {{5745, 149}, {5765, 153},
10524 {5785, 157}, {5805, 161}},
10525 },
10526
10527 { /* Custom Europe */
10528 "ZZG",
10529 .bg_channels = 13,
10530 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10531 {2427, 4}, {2432, 5}, {2437, 6},
10532 {2442, 7}, {2447, 8}, {2452, 9},
10533 {2457, 10}, {2462, 11},
10534 {2467, 12}, {2472, 13}},
10535 .a_channels = 4,
10536 .a = {{5180, 36}, {5200, 40},
10537 {5220, 44}, {5240, 48}},
10538 },
10539
10540 { /* Europe */
10541 "ZZK",
10542 .bg_channels = 13,
10543 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10544 {2427, 4}, {2432, 5}, {2437, 6},
10545 {2442, 7}, {2447, 8}, {2452, 9},
10546 {2457, 10}, {2462, 11},
10547 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10548 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10549 .a_channels = 24,
10550 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10551 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10552 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10553 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10554 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10555 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10556 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10557 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10558 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10559 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10560 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10561 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10562 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10563 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10564 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10565 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10566 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10567 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10568 {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
10569 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10570 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10571 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10572 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10573 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10574 },
10575
10576 { /* Europe */
10577 "ZZL",
10578 .bg_channels = 11,
10579 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10580 {2427, 4}, {2432, 5}, {2437, 6},
10581 {2442, 7}, {2447, 8}, {2452, 9},
10582 {2457, 10}, {2462, 11}},
10583 .a_channels = 13,
10584 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10585 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10586 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10587 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10588 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10589 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10590 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10591 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10592 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10593 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10594 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10595 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10596 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10597 }
10598};
10599
10600/* GEO code borrowed from ieee80211_geo.c */
10601static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
10602{
10603 int i;
10604
10605 /* Driver needs to initialize the geography map before using
10606 * these helper functions */
10607 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10608
10609 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10610 for (i = 0; i < ieee->geo.bg_channels; i++)
10611 /* NOTE: If G mode is currently supported but
10612 * this is a B only channel, we don't see it
10613 * as valid. */
10614 if ((ieee->geo.bg[i].channel == channel) &&
10615 (!(ieee->mode & IEEE_G) ||
10616 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
10617 return IEEE80211_24GHZ_BAND;
10618
10619 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10620 for (i = 0; i < ieee->geo.a_channels; i++)
10621 if (ieee->geo.a[i].channel == channel)
10622 return IEEE80211_52GHZ_BAND;
10623
10624 return 0;
10625}
10626
10627static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
10628{
10629 int i;
10630
10631 /* Driver needs to initialize the geography map before using
10632 * these helper functions */
10633 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10634
10635 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10636 for (i = 0; i < ieee->geo.bg_channels; i++)
10637 if (ieee->geo.bg[i].channel == channel)
10638 return i;
10639
10640 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10641 for (i = 0; i < ieee->geo.a_channels; i++)
10642 if (ieee->geo.a[i].channel == channel)
10643 return i;
10644
10645 return -1;
10646}
10647
10648static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
10649{
10650 int i;
10651
10652 /* Driver needs to initialize the geography map before using
10653 * these helper functions */
10654 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10655
10656 freq /= 100000;
10657
10658 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10659 for (i = 0; i < ieee->geo.bg_channels; i++)
10660 if (ieee->geo.bg[i].freq == freq)
10661 return ieee->geo.bg[i].channel;
10662
10663 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10664 for (i = 0; i < ieee->geo.a_channels; i++)
10665 if (ieee->geo.a[i].freq == freq)
10666 return ieee->geo.a[i].channel;
10667
10668 return 0;
10669}
10670
10671static int ipw_set_geo(struct ieee80211_device *ieee,
10672 const struct ieee80211_geo *geo)
10673{
10674 memcpy(ieee->geo.name, geo->name, 3);
10675 ieee->geo.name[3] = '\0';
10676 ieee->geo.bg_channels = geo->bg_channels;
10677 ieee->geo.a_channels = geo->a_channels;
10678 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
10679 sizeof(struct ieee80211_channel));
10680 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
10681 sizeof(struct ieee80211_channel));
10682 return 0;
10683}
10684
10685static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
10686{
10687 return &ieee->geo;
10688}
10689
6852#define MAX_HW_RESTARTS 5 10690#define MAX_HW_RESTARTS 5
6853static int ipw_up(struct ipw_priv *priv) 10691static int ipw_up(struct ipw_priv *priv)
6854{ 10692{
6855 int rc, i; 10693 int rc, i, j;
6856 10694
6857 if (priv->status & STATUS_EXIT_PENDING) 10695 if (priv->status & STATUS_EXIT_PENDING)
6858 return -EIO; 10696 return -EIO;
6859 10697
10698 if (cmdlog && !priv->cmdlog) {
10699 priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
10700 GFP_KERNEL);
10701 if (priv->cmdlog == NULL) {
10702 IPW_ERROR("Error allocating %d command log entries.\n",
10703 cmdlog);
10704 } else {
10705 memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
10706 priv->cmdlog_len = cmdlog;
10707 }
10708 }
10709
6860 for (i = 0; i < MAX_HW_RESTARTS; i++) { 10710 for (i = 0; i < MAX_HW_RESTARTS; i++) {
6861 /* Load the microcode, firmware, and eeprom. 10711 /* Load the microcode, firmware, and eeprom.
6862 * Also start the clocks. */ 10712 * Also start the clocks. */
6863 rc = ipw_load(priv); 10713 rc = ipw_load(priv);
6864 if (rc) { 10714 if (rc) {
6865 IPW_ERROR("Unable to load firmware: 0x%08X\n", rc); 10715 IPW_ERROR("Unable to load firmware: %d\n", rc);
6866 return rc; 10716 return rc;
6867 } 10717 }
6868 10718
@@ -6871,20 +10721,50 @@ static int ipw_up(struct ipw_priv *priv)
6871 eeprom_parse_mac(priv, priv->mac_addr); 10721 eeprom_parse_mac(priv, priv->mac_addr);
6872 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 10722 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
6873 10723
6874 if (priv->status & STATUS_RF_KILL_MASK) 10724 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
10725 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
10726 ipw_geos[j].name, 3))
10727 break;
10728 }
10729 if (j == ARRAY_SIZE(ipw_geos)) {
10730 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
10731 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
10732 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
10733 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
10734 j = 0;
10735 }
10736 if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
10737 IPW_WARNING("Could not set geography.");
10738 return 0;
10739 }
10740
10741 IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
10742 j, priv->ieee->geo.name);
10743
10744 if (priv->status & STATUS_RF_KILL_SW) {
10745 IPW_WARNING("Radio disabled by module parameter.\n");
10746 return 0;
10747 } else if (rf_kill_active(priv)) {
10748 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
10749 "Kill switch must be turned off for "
10750 "wireless networking to work.\n");
10751 queue_delayed_work(priv->workqueue, &priv->rf_kill,
10752 2 * HZ);
6875 return 0; 10753 return 0;
10754 }
6876 10755
6877 rc = ipw_config(priv); 10756 rc = ipw_config(priv);
6878 if (!rc) { 10757 if (!rc) {
6879 IPW_DEBUG_INFO("Configured device on count %i\n", i); 10758 IPW_DEBUG_INFO("Configured device on count %i\n", i);
6880 priv->notif_missed_beacons = 0; 10759
6881 netif_start_queue(priv->net_dev); 10760 /* If configure to try and auto-associate, kick
10761 * off a scan. */
10762 queue_work(priv->workqueue, &priv->request_scan);
10763
6882 return 0; 10764 return 0;
6883 } else {
6884 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
6885 rc);
6886 } 10765 }
6887 10766
10767 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
6888 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n", 10768 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
6889 i, MAX_HW_RESTARTS); 10769 i, MAX_HW_RESTARTS);
6890 10770
@@ -6896,47 +10776,101 @@ static int ipw_up(struct ipw_priv *priv)
6896 /* tried to restart and config the device for as long as our 10776 /* tried to restart and config the device for as long as our
6897 * patience could withstand */ 10777 * patience could withstand */
6898 IPW_ERROR("Unable to initialize device after %d attempts.\n", i); 10778 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
10779
6899 return -EIO; 10780 return -EIO;
6900} 10781}
6901 10782
6902static void ipw_down(struct ipw_priv *priv) 10783static void ipw_bg_up(void *data)
10784{
10785 struct ipw_priv *priv = data;
10786 down(&priv->sem);
10787 ipw_up(data);
10788 up(&priv->sem);
10789}
10790
10791static void ipw_deinit(struct ipw_priv *priv)
6903{ 10792{
10793 int i;
10794
10795 if (priv->status & STATUS_SCANNING) {
10796 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
10797 ipw_abort_scan(priv);
10798 }
10799
10800 if (priv->status & STATUS_ASSOCIATED) {
10801 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
10802 ipw_disassociate(priv);
10803 }
10804
10805 ipw_led_shutdown(priv);
10806
10807 /* Wait up to 1s for status to change to not scanning and not
10808 * associated (disassociation can take a while for a ful 802.11
10809 * exchange */
10810 for (i = 1000; i && (priv->status &
10811 (STATUS_DISASSOCIATING |
10812 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
10813 udelay(10);
10814
10815 if (priv->status & (STATUS_DISASSOCIATING |
10816 STATUS_ASSOCIATED | STATUS_SCANNING))
10817 IPW_DEBUG_INFO("Still associated or scanning...\n");
10818 else
10819 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
10820
6904 /* Attempt to disable the card */ 10821 /* Attempt to disable the card */
6905#if 0
6906 ipw_send_card_disable(priv, 0); 10822 ipw_send_card_disable(priv, 0);
6907#endif 10823
10824 priv->status &= ~STATUS_INIT;
10825}
10826
10827static void ipw_down(struct ipw_priv *priv)
10828{
10829 int exit_pending = priv->status & STATUS_EXIT_PENDING;
10830
10831 priv->status |= STATUS_EXIT_PENDING;
10832
10833 if (ipw_is_init(priv))
10834 ipw_deinit(priv);
10835
10836 /* Wipe out the EXIT_PENDING status bit if we are not actually
10837 * exiting the module */
10838 if (!exit_pending)
10839 priv->status &= ~STATUS_EXIT_PENDING;
6908 10840
6909 /* tell the device to stop sending interrupts */ 10841 /* tell the device to stop sending interrupts */
6910 ipw_disable_interrupts(priv); 10842 ipw_disable_interrupts(priv);
6911 10843
6912 /* Clear all bits but the RF Kill */ 10844 /* Clear all bits but the RF Kill */
6913 priv->status &= STATUS_RF_KILL_MASK; 10845 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
6914
6915 netif_carrier_off(priv->net_dev); 10846 netif_carrier_off(priv->net_dev);
6916 netif_stop_queue(priv->net_dev); 10847 netif_stop_queue(priv->net_dev);
6917 10848
6918 ipw_stop_nic(priv); 10849 ipw_stop_nic(priv);
10850
10851 ipw_led_radio_off(priv);
10852}
10853
10854static void ipw_bg_down(void *data)
10855{
10856 struct ipw_priv *priv = data;
10857 down(&priv->sem);
10858 ipw_down(data);
10859 up(&priv->sem);
6919} 10860}
6920 10861
6921/* Called by register_netdev() */ 10862/* Called by register_netdev() */
6922static int ipw_net_init(struct net_device *dev) 10863static int ipw_net_init(struct net_device *dev)
6923{ 10864{
6924 struct ipw_priv *priv = ieee80211_priv(dev); 10865 struct ipw_priv *priv = ieee80211_priv(dev);
10866 down(&priv->sem);
6925 10867
6926 if (priv->status & STATUS_RF_KILL_SW) { 10868 if (ipw_up(priv)) {
6927 IPW_WARNING("Radio disabled by module parameter.\n"); 10869 up(&priv->sem);
6928 return 0;
6929 } else if (rf_kill_active(priv)) {
6930 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
6931 "Kill switch must be turned off for "
6932 "wireless networking to work.\n");
6933 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
6934 return 0;
6935 }
6936
6937 if (ipw_up(priv))
6938 return -EIO; 10870 return -EIO;
10871 }
6939 10872
10873 up(&priv->sem);
6940 return 0; 10874 return 0;
6941} 10875}
6942 10876
@@ -6961,7 +10895,7 @@ static struct pci_device_id card_ids[] = {
6961 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, 10895 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
6962 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 10896 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
6963 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */ 10897 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6964 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ 10898 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6965 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10899 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6966 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10900 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6967 10901
@@ -6981,11 +10915,16 @@ static struct attribute *ipw_sysfs_entries[] = {
6981 &dev_attr_nic_type.attr, 10915 &dev_attr_nic_type.attr,
6982 &dev_attr_status.attr, 10916 &dev_attr_status.attr,
6983 &dev_attr_cfg.attr, 10917 &dev_attr_cfg.attr,
6984 &dev_attr_dump_errors.attr, 10918 &dev_attr_error.attr,
6985 &dev_attr_dump_events.attr, 10919 &dev_attr_event_log.attr,
10920 &dev_attr_cmd_log.attr,
6986 &dev_attr_eeprom_delay.attr, 10921 &dev_attr_eeprom_delay.attr,
6987 &dev_attr_ucode_version.attr, 10922 &dev_attr_ucode_version.attr,
6988 &dev_attr_rtc.attr, 10923 &dev_attr_rtc.attr,
10924 &dev_attr_scan_age.attr,
10925 &dev_attr_led.attr,
10926 &dev_attr_speed_scan.attr,
10927 &dev_attr_net_stats.attr,
6989 NULL 10928 NULL
6990}; 10929};
6991 10930
@@ -7001,7 +10940,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7001 void __iomem *base; 10940 void __iomem *base;
7002 u32 length, val; 10941 u32 length, val;
7003 struct ipw_priv *priv; 10942 struct ipw_priv *priv;
7004 int band, modulation; 10943 int i;
7005 10944
7006 net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); 10945 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
7007 if (net_dev == NULL) { 10946 if (net_dev == NULL) {
@@ -7011,13 +10950,17 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7011 10950
7012 priv = ieee80211_priv(net_dev); 10951 priv = ieee80211_priv(net_dev);
7013 priv->ieee = netdev_priv(net_dev); 10952 priv->ieee = netdev_priv(net_dev);
10953
7014 priv->net_dev = net_dev; 10954 priv->net_dev = net_dev;
7015 priv->pci_dev = pdev; 10955 priv->pci_dev = pdev;
7016#ifdef CONFIG_IPW_DEBUG 10956#ifdef CONFIG_IPW_DEBUG
7017 ipw_debug_level = debug; 10957 ipw_debug_level = debug;
7018#endif 10958#endif
7019 spin_lock_init(&priv->lock); 10959 spin_lock_init(&priv->lock);
10960 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
10961 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
7020 10962
10963 init_MUTEX(&priv->sem);
7021 if (pci_enable_device(pdev)) { 10964 if (pci_enable_device(pdev)) {
7022 err = -ENODEV; 10965 err = -ENODEV;
7023 goto out_free_ieee80211; 10966 goto out_free_ieee80211;
@@ -7064,90 +11007,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7064 goto out_iounmap; 11007 goto out_iounmap;
7065 } 11008 }
7066 11009
7067 /* Initialize module parameter values here */ 11010 ipw_sw_reset(priv, 1);
7068 if (ifname)
7069 strncpy(net_dev->name, ifname, IFNAMSIZ);
7070
7071 if (associate)
7072 priv->config |= CFG_ASSOCIATE;
7073 else
7074 IPW_DEBUG_INFO("Auto associate disabled.\n");
7075
7076 if (auto_create)
7077 priv->config |= CFG_ADHOC_CREATE;
7078 else
7079 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
7080
7081 if (disable) {
7082 priv->status |= STATUS_RF_KILL_SW;
7083 IPW_DEBUG_INFO("Radio disabled.\n");
7084 }
7085
7086 if (channel != 0) {
7087 priv->config |= CFG_STATIC_CHANNEL;
7088 priv->channel = channel;
7089 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7090 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7091 /* TODO: Validate that provided channel is in range */
7092 }
7093
7094 switch (mode) {
7095 case 1:
7096 priv->ieee->iw_mode = IW_MODE_ADHOC;
7097 break;
7098#ifdef CONFIG_IPW_PROMISC
7099 case 2:
7100 priv->ieee->iw_mode = IW_MODE_MONITOR;
7101 break;
7102#endif
7103 default:
7104 case 0:
7105 priv->ieee->iw_mode = IW_MODE_INFRA;
7106 break;
7107 }
7108
7109 if ((priv->pci_dev->device == 0x4223) ||
7110 (priv->pci_dev->device == 0x4224)) {
7111 printk(KERN_INFO DRV_NAME
7112 ": Detected Intel PRO/Wireless 2915ABG Network "
7113 "Connection\n");
7114 priv->ieee->abg_true = 1;
7115 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
7116 modulation = IEEE80211_OFDM_MODULATION |
7117 IEEE80211_CCK_MODULATION;
7118 priv->adapter = IPW_2915ABG;
7119 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
7120 } else {
7121 if (priv->pci_dev->device == 0x4221)
7122 printk(KERN_INFO DRV_NAME
7123 ": Detected Intel PRO/Wireless 2225BG Network "
7124 "Connection\n");
7125 else
7126 printk(KERN_INFO DRV_NAME
7127 ": Detected Intel PRO/Wireless 2200BG Network "
7128 "Connection\n");
7129
7130 priv->ieee->abg_true = 0;
7131 band = IEEE80211_24GHZ_BAND;
7132 modulation = IEEE80211_OFDM_MODULATION |
7133 IEEE80211_CCK_MODULATION;
7134 priv->adapter = IPW_2200BG;
7135 priv->ieee->mode = IEEE_G | IEEE_B;
7136 }
7137
7138 priv->ieee->freq_band = band;
7139 priv->ieee->modulation = modulation;
7140
7141 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
7142
7143 priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
7144 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
7145
7146 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
7147
7148 /* If power management is turned on, default to AC mode */
7149 priv->power_mode = IPW_POWER_AC;
7150 priv->tx_power = IPW_DEFAULT_TX_POWER;
7151 11011
7152 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv); 11012 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
7153 if (err) { 11013 if (err) {
@@ -7158,8 +11018,20 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7158 SET_MODULE_OWNER(net_dev); 11018 SET_MODULE_OWNER(net_dev);
7159 SET_NETDEV_DEV(net_dev, &pdev->dev); 11019 SET_NETDEV_DEV(net_dev, &pdev->dev);
7160 11020
11021 down(&priv->sem);
11022
7161 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; 11023 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
7162 priv->ieee->set_security = shim__set_security; 11024 priv->ieee->set_security = shim__set_security;
11025 priv->ieee->is_queue_full = ipw_net_is_queue_full;
11026
11027#ifdef CONFIG_IPW_QOS
11028 priv->ieee->handle_probe_response = ipw_handle_beacon;
11029 priv->ieee->handle_beacon = ipw_handle_probe_response;
11030 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
11031#endif /* CONFIG_IPW_QOS */
11032
11033 priv->ieee->perfect_rssi = -20;
11034 priv->ieee->worst_rssi = -85;
7163 11035
7164 net_dev->open = ipw_net_open; 11036 net_dev->open = ipw_net_open;
7165 net_dev->stop = ipw_net_stop; 11037 net_dev->stop = ipw_net_stop;
@@ -7167,7 +11039,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7167 net_dev->get_stats = ipw_net_get_stats; 11039 net_dev->get_stats = ipw_net_get_stats;
7168 net_dev->set_multicast_list = ipw_net_set_multicast_list; 11040 net_dev->set_multicast_list = ipw_net_set_multicast_list;
7169 net_dev->set_mac_address = ipw_net_set_mac_address; 11041 net_dev->set_mac_address = ipw_net_set_mac_address;
7170 net_dev->get_wireless_stats = ipw_get_wireless_stats; 11042 priv->wireless_data.spy_data = &priv->ieee->spy_data;
11043 priv->wireless_data.ieee80211 = priv->ieee;
11044 net_dev->wireless_data = &priv->wireless_data;
7171 net_dev->wireless_handlers = &ipw_wx_handler_def; 11045 net_dev->wireless_handlers = &ipw_wx_handler_def;
7172 net_dev->ethtool_ops = &ipw_ethtool_ops; 11046 net_dev->ethtool_ops = &ipw_ethtool_ops;
7173 net_dev->irq = pdev->irq; 11047 net_dev->irq = pdev->irq;
@@ -7178,18 +11052,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7178 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); 11052 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
7179 if (err) { 11053 if (err) {
7180 IPW_ERROR("failed to create sysfs device attributes\n"); 11054 IPW_ERROR("failed to create sysfs device attributes\n");
11055 up(&priv->sem);
7181 goto out_release_irq; 11056 goto out_release_irq;
7182 } 11057 }
7183 11058
11059 up(&priv->sem);
7184 err = register_netdev(net_dev); 11060 err = register_netdev(net_dev);
7185 if (err) { 11061 if (err) {
7186 IPW_ERROR("failed to register network device\n"); 11062 IPW_ERROR("failed to register network device\n");
7187 goto out_remove_group; 11063 goto out_remove_sysfs;
7188 } 11064 }
7189
7190 return 0; 11065 return 0;
7191 11066
7192 out_remove_group: 11067 out_remove_sysfs:
7193 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11068 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7194 out_release_irq: 11069 out_release_irq:
7195 free_irq(pdev->irq, priv); 11070 free_irq(pdev->irq, priv);
@@ -7212,14 +11087,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7212static void ipw_pci_remove(struct pci_dev *pdev) 11087static void ipw_pci_remove(struct pci_dev *pdev)
7213{ 11088{
7214 struct ipw_priv *priv = pci_get_drvdata(pdev); 11089 struct ipw_priv *priv = pci_get_drvdata(pdev);
11090 struct list_head *p, *q;
11091 int i;
11092
7215 if (!priv) 11093 if (!priv)
7216 return; 11094 return;
7217 11095
7218 priv->status |= STATUS_EXIT_PENDING; 11096 down(&priv->sem);
7219 11097
11098 priv->status |= STATUS_EXIT_PENDING;
11099 ipw_down(priv);
7220 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11100 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7221 11101
7222 ipw_down(priv); 11102 up(&priv->sem);
7223 11103
7224 unregister_netdev(priv->net_dev); 11104 unregister_netdev(priv->net_dev);
7225 11105
@@ -7229,16 +11109,31 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7229 } 11109 }
7230 ipw_tx_queue_free(priv); 11110 ipw_tx_queue_free(priv);
7231 11111
11112 if (priv->cmdlog) {
11113 kfree(priv->cmdlog);
11114 priv->cmdlog = NULL;
11115 }
7232 /* ipw_down will ensure that there is no more pending work 11116 /* ipw_down will ensure that there is no more pending work
7233 * in the workqueue's, so we can safely remove them now. */ 11117 * in the workqueue's, so we can safely remove them now. */
7234 if (priv->workqueue) { 11118 cancel_delayed_work(&priv->adhoc_check);
7235 cancel_delayed_work(&priv->adhoc_check); 11119 cancel_delayed_work(&priv->gather_stats);
7236 cancel_delayed_work(&priv->gather_stats); 11120 cancel_delayed_work(&priv->request_scan);
7237 cancel_delayed_work(&priv->request_scan); 11121 cancel_delayed_work(&priv->rf_kill);
7238 cancel_delayed_work(&priv->rf_kill); 11122 cancel_delayed_work(&priv->scan_check);
7239 cancel_delayed_work(&priv->scan_check); 11123 destroy_workqueue(priv->workqueue);
7240 destroy_workqueue(priv->workqueue); 11124 priv->workqueue = NULL;
7241 priv->workqueue = NULL; 11125
11126 /* Free MAC hash list for ADHOC */
11127 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
11128 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
11129 kfree(list_entry(p, struct ipw_ibss_seq, list));
11130 list_del(p);
11131 }
11132 }
11133
11134 if (priv->error) {
11135 ipw_free_error_log(priv->error);
11136 priv->error = NULL;
7242 } 11137 }
7243 11138
7244 free_irq(pdev->irq, priv); 11139 free_irq(pdev->irq, priv);
@@ -7247,15 +11142,7 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7247 pci_disable_device(pdev); 11142 pci_disable_device(pdev);
7248 pci_set_drvdata(pdev, NULL); 11143 pci_set_drvdata(pdev, NULL);
7249 free_ieee80211(priv->net_dev); 11144 free_ieee80211(priv->net_dev);
7250 11145 free_firmware();
7251#ifdef CONFIG_PM
7252 if (fw_loaded) {
7253 release_firmware(bootfw);
7254 release_firmware(ucode);
7255 release_firmware(firmware);
7256 fw_loaded = 0;
7257 }
7258#endif
7259} 11146}
7260 11147
7261#ifdef CONFIG_PM 11148#ifdef CONFIG_PM
@@ -7287,13 +11174,10 @@ static int ipw_pci_resume(struct pci_dev *pdev)
7287 11174
7288 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); 11175 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
7289 11176
7290 pci_set_power_state(pdev, 0); 11177 pci_set_power_state(pdev, PCI_D0);
7291 pci_enable_device(pdev); 11178 pci_enable_device(pdev);
7292#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
7293 pci_restore_state(pdev, priv->pm_state);
7294#else
7295 pci_restore_state(pdev); 11179 pci_restore_state(pdev);
7296#endif 11180
7297 /* 11181 /*
7298 * Suspend/Resume resets the PCI configuration space, so we have to 11182 * Suspend/Resume resets the PCI configuration space, so we have to
7299 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries 11183 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -7365,16 +11249,33 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
7365module_param(auto_create, int, 0444); 11249module_param(auto_create, int, 0444);
7366MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); 11250MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
7367 11251
11252module_param(led, int, 0444);
11253MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
11254
7368module_param(debug, int, 0444); 11255module_param(debug, int, 0444);
7369MODULE_PARM_DESC(debug, "debug output mask"); 11256MODULE_PARM_DESC(debug, "debug output mask");
7370 11257
7371module_param(channel, int, 0444); 11258module_param(channel, int, 0444);
7372MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11259MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
7373 11260
7374module_param(ifname, charp, 0444); 11261#ifdef CONFIG_IPW_QOS
7375MODULE_PARM_DESC(ifname, "network device name (default eth%d)"); 11262module_param(qos_enable, int, 0444);
11263MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
11264
11265module_param(qos_burst_enable, int, 0444);
11266MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
11267
11268module_param(qos_no_ack_mask, int, 0444);
11269MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
7376 11270
7377#ifdef CONFIG_IPW_PROMISC 11271module_param(burst_duration_CCK, int, 0444);
11272MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
11273
11274module_param(burst_duration_OFDM, int, 0444);
11275MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
11276#endif /* CONFIG_IPW_QOS */
11277
11278#ifdef CONFIG_IPW2200_MONITOR
7378module_param(mode, int, 0444); 11279module_param(mode, int, 0444);
7379MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)"); 11280MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
7380#else 11281#else
@@ -7382,5 +11283,12 @@ module_param(mode, int, 0444);
7382MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); 11283MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
7383#endif 11284#endif
7384 11285
11286module_param(hwcrypto, int, 0444);
11287MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
11288
11289module_param(cmdlog, int, 0444);
11290MODULE_PARM_DESC(cmdlog,
11291 "allocate a ring buffer for logging firmware commands");
11292
7385module_exit(ipw_exit); 11293module_exit(ipw_exit);
7386module_init(ipw_init); 11294module_init(ipw_init);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index e9cf32bf3e31..1c98db0652c9 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,6 @@
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/init.h> 35#include <linux/init.h>
36 36
37#include <linux/version.h>
38#include <linux/pci.h> 37#include <linux/pci.h>
39#include <linux/netdevice.h> 38#include <linux/netdevice.h>
40#include <linux/ethtool.h> 39#include <linux/ethtool.h>
@@ -50,6 +49,7 @@
50#include <asm/io.h> 49#include <asm/io.h>
51 50
52#include <net/ieee80211.h> 51#include <net/ieee80211.h>
52#include <net/ieee80211_radiotap.h>
53 53
54#define DRV_NAME "ipw2200" 54#define DRV_NAME "ipw2200"
55 55
@@ -161,6 +161,16 @@ enum connection_manager_assoc_states {
161 * TX Queue Flag Definitions 161 * TX Queue Flag Definitions
162 */ 162 */
163 163
164/* tx wep key definition */
165#define DCT_WEP_KEY_NOT_IMMIDIATE 0x00
166#define DCT_WEP_KEY_64Bit 0x40
167#define DCT_WEP_KEY_128Bit 0x80
168#define DCT_WEP_KEY_128bitIV 0xC0
169#define DCT_WEP_KEY_SIZE_MASK 0xC0
170
171#define DCT_WEP_KEY_INDEX_MASK 0x0F
172#define DCT_WEP_INDEX_USE_IMMEDIATE 0x20
173
164/* abort attempt if mgmt frame is rx'd */ 174/* abort attempt if mgmt frame is rx'd */
165#define DCT_FLAG_ABORT_MGMT 0x01 175#define DCT_FLAG_ABORT_MGMT 0x01
166 176
@@ -168,7 +178,8 @@ enum connection_manager_assoc_states {
168#define DCT_FLAG_CTS_REQUIRED 0x02 178#define DCT_FLAG_CTS_REQUIRED 0x02
169 179
170/* use short preamble */ 180/* use short preamble */
171#define DCT_FLAG_SHORT_PREMBL 0x04 181#define DCT_FLAG_LONG_PREAMBLE 0x00
182#define DCT_FLAG_SHORT_PREAMBLE 0x04
172 183
173/* RTS/CTS first */ 184/* RTS/CTS first */
174#define DCT_FLAG_RTS_REQD 0x08 185#define DCT_FLAG_RTS_REQD 0x08
@@ -185,9 +196,23 @@ enum connection_manager_assoc_states {
185/* ACK rx is expected to follow */ 196/* ACK rx is expected to follow */
186#define DCT_FLAG_ACK_REQD 0x80 197#define DCT_FLAG_ACK_REQD 0x80
187 198
199/* TX flags extension */
188#define DCT_FLAG_EXT_MODE_CCK 0x01 200#define DCT_FLAG_EXT_MODE_CCK 0x01
189#define DCT_FLAG_EXT_MODE_OFDM 0x00 201#define DCT_FLAG_EXT_MODE_OFDM 0x00
190 202
203#define DCT_FLAG_EXT_SECURITY_WEP 0x00
204#define DCT_FLAG_EXT_SECURITY_NO DCT_FLAG_EXT_SECURITY_WEP
205#define DCT_FLAG_EXT_SECURITY_CKIP 0x04
206#define DCT_FLAG_EXT_SECURITY_CCM 0x08
207#define DCT_FLAG_EXT_SECURITY_TKIP 0x0C
208#define DCT_FLAG_EXT_SECURITY_MASK 0x0C
209
210#define DCT_FLAG_EXT_QOS_ENABLED 0x10
211
212#define DCT_FLAG_EXT_HC_NO_SIFS_PIFS 0x00
213#define DCT_FLAG_EXT_HC_SIFS 0x20
214#define DCT_FLAG_EXT_HC_PIFS 0x40
215
191#define TX_RX_TYPE_MASK 0xFF 216#define TX_RX_TYPE_MASK 0xFF
192#define TX_FRAME_TYPE 0x00 217#define TX_FRAME_TYPE 0x00
193#define TX_HOST_COMMAND_TYPE 0x01 218#define TX_HOST_COMMAND_TYPE 0x01
@@ -233,6 +258,117 @@ enum connection_manager_assoc_states {
233#define DCR_TYPE_SNIFFER 0x06 258#define DCR_TYPE_SNIFFER 0x06
234#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS 259#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS
235 260
261/* QoS definitions */
262
263#define CW_MIN_OFDM 15
264#define CW_MAX_OFDM 1023
265#define CW_MIN_CCK 31
266#define CW_MAX_CCK 1023
267
268#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM
269#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM
270#define QOS_TX2_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
271#define QOS_TX3_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 4 - 1 )
272
273#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK
274#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK
275#define QOS_TX2_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
276#define QOS_TX3_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 4 - 1 )
277
278#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM
279#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM
280#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM
281#define QOS_TX3_CW_MAX_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
282
283#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK
284#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK
285#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK
286#define QOS_TX3_CW_MAX_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
287
288#define QOS_TX0_AIFS (3 - QOS_AIFSN_MIN_VALUE)
289#define QOS_TX1_AIFS (7 - QOS_AIFSN_MIN_VALUE)
290#define QOS_TX2_AIFS (2 - QOS_AIFSN_MIN_VALUE)
291#define QOS_TX3_AIFS (2 - QOS_AIFSN_MIN_VALUE)
292
293#define QOS_TX0_ACM 0
294#define QOS_TX1_ACM 0
295#define QOS_TX2_ACM 0
296#define QOS_TX3_ACM 0
297
298#define QOS_TX0_TXOP_LIMIT_CCK 0
299#define QOS_TX1_TXOP_LIMIT_CCK 0
300#define QOS_TX2_TXOP_LIMIT_CCK 6016
301#define QOS_TX3_TXOP_LIMIT_CCK 3264
302
303#define QOS_TX0_TXOP_LIMIT_OFDM 0
304#define QOS_TX1_TXOP_LIMIT_OFDM 0
305#define QOS_TX2_TXOP_LIMIT_OFDM 3008
306#define QOS_TX3_TXOP_LIMIT_OFDM 1504
307
308#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM
309#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM
310#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM
311#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM
312
313#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK
314#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK
315#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK
316#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK
317
318#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM
319#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM
320#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM
321#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM
322
323#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK
324#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK
325#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK
326#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK
327
328#define DEF_TX0_AIFS 0
329#define DEF_TX1_AIFS 0
330#define DEF_TX2_AIFS 0
331#define DEF_TX3_AIFS 0
332
333#define DEF_TX0_ACM 0
334#define DEF_TX1_ACM 0
335#define DEF_TX2_ACM 0
336#define DEF_TX3_ACM 0
337
338#define DEF_TX0_TXOP_LIMIT_CCK 0
339#define DEF_TX1_TXOP_LIMIT_CCK 0
340#define DEF_TX2_TXOP_LIMIT_CCK 0
341#define DEF_TX3_TXOP_LIMIT_CCK 0
342
343#define DEF_TX0_TXOP_LIMIT_OFDM 0
344#define DEF_TX1_TXOP_LIMIT_OFDM 0
345#define DEF_TX2_TXOP_LIMIT_OFDM 0
346#define DEF_TX3_TXOP_LIMIT_OFDM 0
347
348#define QOS_QOS_SETS 3
349#define QOS_PARAM_SET_ACTIVE 0
350#define QOS_PARAM_SET_DEF_CCK 1
351#define QOS_PARAM_SET_DEF_OFDM 2
352
353#define CTRL_QOS_NO_ACK (0x0020)
354
355#define IPW_TX_QUEUE_1 1
356#define IPW_TX_QUEUE_2 2
357#define IPW_TX_QUEUE_3 3
358#define IPW_TX_QUEUE_4 4
359
360/* QoS sturctures */
361struct ipw_qos_info {
362 int qos_enable;
363 struct ieee80211_qos_parameters *def_qos_parm_OFDM;
364 struct ieee80211_qos_parameters *def_qos_parm_CCK;
365 u32 burst_duration_CCK;
366 u32 burst_duration_OFDM;
367 u16 qos_no_ack_mask;
368 int burst_enable;
369};
370
371/**************************************************************/
236/** 372/**
237 * Generic queue structure 373 * Generic queue structure
238 * 374 *
@@ -402,9 +538,9 @@ struct clx2_tx_queue {
402#define RX_FREE_BUFFERS 32 538#define RX_FREE_BUFFERS 32
403#define RX_LOW_WATERMARK 8 539#define RX_LOW_WATERMARK 8
404 540
405#define SUP_RATE_11A_MAX_NUM_CHANNELS (8) 541#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
406#define SUP_RATE_11B_MAX_NUM_CHANNELS (4) 542#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
407#define SUP_RATE_11G_MAX_NUM_CHANNELS (12) 543#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
408 544
409// Used for passing to driver number of successes and failures per rate 545// Used for passing to driver number of successes and failures per rate
410struct rate_histogram { 546struct rate_histogram {
@@ -453,6 +589,9 @@ struct notif_channel_result {
453 u8 uReserved; 589 u8 uReserved;
454} __attribute__ ((packed)); 590} __attribute__ ((packed));
455 591
592#define SCAN_COMPLETED_STATUS_COMPLETE 1
593#define SCAN_COMPLETED_STATUS_ABORTED 2
594
456struct notif_scan_complete { 595struct notif_scan_complete {
457 u8 scan_type; 596 u8 scan_type;
458 u8 num_channels; 597 u8 num_channels;
@@ -563,8 +702,8 @@ struct ipw_rx_packet {
563} __attribute__ ((packed)); 702} __attribute__ ((packed));
564 703
565#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12 704#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12
566#define IPW_RX_FRAME_SIZE sizeof(struct ipw_rx_header) + \ 705#define IPW_RX_FRAME_SIZE (unsigned int)(sizeof(struct ipw_rx_header) + \
567 sizeof(struct ipw_rx_frame) 706 sizeof(struct ipw_rx_frame))
568 707
569struct ipw_rx_mem_buffer { 708struct ipw_rx_mem_buffer {
570 dma_addr_t dma_addr; 709 dma_addr_t dma_addr;
@@ -657,6 +796,19 @@ struct ipw_multicast_addr {
657 u8 mac4[6]; 796 u8 mac4[6];
658} __attribute__ ((packed)); 797} __attribute__ ((packed));
659 798
799#define DCW_WEP_KEY_INDEX_MASK 0x03 /* bits [0:1] */
800#define DCW_WEP_KEY_SEC_TYPE_MASK 0x30 /* bits [4:5] */
801
802#define DCW_WEP_KEY_SEC_TYPE_WEP 0x00
803#define DCW_WEP_KEY_SEC_TYPE_CCM 0x20
804#define DCW_WEP_KEY_SEC_TYPE_TKIP 0x30
805
806#define DCW_WEP_KEY_INVALID_SIZE 0x00 /* 0 = Invalid key */
807#define DCW_WEP_KEY64Bit_SIZE 0x05 /* 64-bit encryption */
808#define DCW_WEP_KEY128Bit_SIZE 0x0D /* 128-bit encryption */
809#define DCW_CCM_KEY128Bit_SIZE 0x10 /* 128-bit key */
810//#define DCW_WEP_KEY128BitIV_SIZE 0x10 /* 128-bit key and 128-bit IV */
811
660struct ipw_wep_key { 812struct ipw_wep_key {
661 u8 cmd_id; 813 u8 cmd_id;
662 u8 seq_num; 814 u8 seq_num;
@@ -818,14 +970,6 @@ struct ipw_tx_power {
818 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS]; 970 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS];
819} __attribute__ ((packed)); 971} __attribute__ ((packed));
820 972
821struct ipw_qos_parameters {
822 u16 cw_min[4];
823 u16 cw_max[4];
824 u8 aifs[4];
825 u8 flag[4];
826 u16 tx_op_limit[4];
827} __attribute__ ((packed));
828
829struct ipw_rsn_capabilities { 973struct ipw_rsn_capabilities {
830 u8 id; 974 u8 id;
831 u8 length; 975 u8 length;
@@ -888,6 +1032,10 @@ struct ipw_cmd {
888#define STATUS_SCAN_PENDING (1<<20) 1032#define STATUS_SCAN_PENDING (1<<20)
889#define STATUS_SCANNING (1<<21) 1033#define STATUS_SCANNING (1<<21)
890#define STATUS_SCAN_ABORTING (1<<22) 1034#define STATUS_SCAN_ABORTING (1<<22)
1035#define STATUS_SCAN_FORCED (1<<23)
1036
1037#define STATUS_LED_LINK_ON (1<<24)
1038#define STATUS_LED_ACT_ON (1<<25)
891 1039
892#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ 1040#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */
893#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ 1041#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */
@@ -899,11 +1047,15 @@ struct ipw_cmd {
899#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */ 1047#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
900#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */ 1048#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
901#define CFG_CUSTOM_MAC (1<<3) 1049#define CFG_CUSTOM_MAC (1<<3)
902#define CFG_PREAMBLE (1<<4) 1050#define CFG_PREAMBLE_LONG (1<<4)
903#define CFG_ADHOC_PERSIST (1<<5) 1051#define CFG_ADHOC_PERSIST (1<<5)
904#define CFG_ASSOCIATE (1<<6) 1052#define CFG_ASSOCIATE (1<<6)
905#define CFG_FIXED_RATE (1<<7) 1053#define CFG_FIXED_RATE (1<<7)
906#define CFG_ADHOC_CREATE (1<<8) 1054#define CFG_ADHOC_CREATE (1<<8)
1055#define CFG_NO_LED (1<<9)
1056#define CFG_BACKGROUND_SCAN (1<<10)
1057#define CFG_SPEED_SCAN (1<<11)
1058#define CFG_NET_STATS (1<<12)
907 1059
908#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 1060#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
909#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 1061#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
@@ -925,13 +1077,50 @@ struct average {
925 s32 sum; 1077 s32 sum;
926}; 1078};
927 1079
1080#define MAX_SPEED_SCAN 100
1081#define IPW_IBSS_MAC_HASH_SIZE 31
1082
1083struct ipw_ibss_seq {
1084 u8 mac[ETH_ALEN];
1085 u16 seq_num;
1086 u16 frag_num;
1087 unsigned long packet_time;
1088 struct list_head list;
1089};
1090
1091struct ipw_error_elem {
1092 u32 desc;
1093 u32 time;
1094 u32 blink1;
1095 u32 blink2;
1096 u32 link1;
1097 u32 link2;
1098 u32 data;
1099};
1100
1101struct ipw_event {
1102 u32 event;
1103 u32 time;
1104 u32 data;
1105} __attribute__ ((packed));
1106
1107struct ipw_fw_error {
1108 unsigned long jiffies;
1109 u32 status;
1110 u32 config;
1111 u32 elem_len;
1112 u32 log_len;
1113 struct ipw_error_elem *elem;
1114 struct ipw_event *log;
1115 u8 payload[0];
1116} __attribute__ ((packed));
1117
928struct ipw_priv { 1118struct ipw_priv {
929 /* ieee device used by generic ieee processing code */ 1119 /* ieee device used by generic ieee processing code */
930 struct ieee80211_device *ieee; 1120 struct ieee80211_device *ieee;
931 struct ieee80211_security sec;
932 1121
933 /* spinlock */
934 spinlock_t lock; 1122 spinlock_t lock;
1123 struct semaphore sem;
935 1124
936 /* basic pci-network driver stuff */ 1125 /* basic pci-network driver stuff */
937 struct pci_dev *pci_dev; 1126 struct pci_dev *pci_dev;
@@ -966,7 +1155,7 @@ struct ipw_priv {
966 int rx_bufs_min; /**< minimum number of bufs in Rx queue */ 1155 int rx_bufs_min; /**< minimum number of bufs in Rx queue */
967 int rx_pend_max; /**< maximum pending buffers for one IRQ */ 1156 int rx_pend_max; /**< maximum pending buffers for one IRQ */
968 u32 hcmd_seq; /**< sequence number for hcmd */ 1157 u32 hcmd_seq; /**< sequence number for hcmd */
969 u32 missed_beacon_threshold; 1158 u32 disassociate_threshold;
970 u32 roaming_threshold; 1159 u32 roaming_threshold;
971 1160
972 struct ipw_associate assoc_request; 1161 struct ipw_associate assoc_request;
@@ -1007,6 +1196,8 @@ struct ipw_priv {
1007 u8 mac_addr[ETH_ALEN]; 1196 u8 mac_addr[ETH_ALEN];
1008 u8 num_stations; 1197 u8 num_stations;
1009 u8 stations[MAX_STATIONS][ETH_ALEN]; 1198 u8 stations[MAX_STATIONS][ETH_ALEN];
1199 u8 short_retry_limit;
1200 u8 long_retry_limit;
1010 1201
1011 u32 notif_missed_beacons; 1202 u32 notif_missed_beacons;
1012 1203
@@ -1024,17 +1215,29 @@ struct ipw_priv {
1024 u32 tx_packets; 1215 u32 tx_packets;
1025 u32 quality; 1216 u32 quality;
1026 1217
1218 u8 speed_scan[MAX_SPEED_SCAN];
1219 u8 speed_scan_pos;
1220
1221 u16 last_seq_num;
1222 u16 last_frag_num;
1223 unsigned long last_packet_time;
1224 struct list_head ibss_mac_hash[IPW_IBSS_MAC_HASH_SIZE];
1225
1027 /* eeprom */ 1226 /* eeprom */
1028 u8 eeprom[0x100]; /* 256 bytes of eeprom */ 1227 u8 eeprom[0x100]; /* 256 bytes of eeprom */
1228 u8 country[4];
1029 int eeprom_delay; 1229 int eeprom_delay;
1030 1230
1031 struct iw_statistics wstats; 1231 struct iw_statistics wstats;
1032 1232
1233 struct iw_public_data wireless_data;
1234
1033 struct workqueue_struct *workqueue; 1235 struct workqueue_struct *workqueue;
1034 1236
1035 struct work_struct adhoc_check; 1237 struct work_struct adhoc_check;
1036 struct work_struct associate; 1238 struct work_struct associate;
1037 struct work_struct disassociate; 1239 struct work_struct disassociate;
1240 struct work_struct system_config;
1038 struct work_struct rx_replenish; 1241 struct work_struct rx_replenish;
1039 struct work_struct request_scan; 1242 struct work_struct request_scan;
1040 struct work_struct adapter_restart; 1243 struct work_struct adapter_restart;
@@ -1045,25 +1248,51 @@ struct ipw_priv {
1045 struct work_struct abort_scan; 1248 struct work_struct abort_scan;
1046 struct work_struct roam; 1249 struct work_struct roam;
1047 struct work_struct scan_check; 1250 struct work_struct scan_check;
1251 struct work_struct link_up;
1252 struct work_struct link_down;
1048 1253
1049 struct tasklet_struct irq_tasklet; 1254 struct tasklet_struct irq_tasklet;
1050 1255
1256 /* LED related variables and work_struct */
1257 u8 nic_type;
1258 u32 led_activity_on;
1259 u32 led_activity_off;
1260 u32 led_association_on;
1261 u32 led_association_off;
1262 u32 led_ofdm_on;
1263 u32 led_ofdm_off;
1264
1265 struct work_struct led_link_on;
1266 struct work_struct led_link_off;
1267 struct work_struct led_act_off;
1268 struct work_struct merge_networks;
1269
1270 struct ipw_cmd_log *cmdlog;
1271 int cmdlog_len;
1272 int cmdlog_pos;
1273
1051#define IPW_2200BG 1 1274#define IPW_2200BG 1
1052#define IPW_2915ABG 2 1275#define IPW_2915ABG 2
1053 u8 adapter; 1276 u8 adapter;
1054 1277
1055#define IPW_DEFAULT_TX_POWER 0x14 1278 s8 tx_power;
1056 u8 tx_power;
1057 1279
1058#ifdef CONFIG_PM 1280#ifdef CONFIG_PM
1059 u32 pm_state[16]; 1281 u32 pm_state[16];
1060#endif 1282#endif
1061 1283
1284 struct ipw_fw_error *error;
1285
1062 /* network state */ 1286 /* network state */
1063 1287
1064 /* Used to pass the current INTA value from ISR to Tasklet */ 1288 /* Used to pass the current INTA value from ISR to Tasklet */
1065 u32 isr_inta; 1289 u32 isr_inta;
1066 1290
1291 /* QoS */
1292 struct ipw_qos_info qos_data;
1293 struct work_struct qos_activate;
1294 /*********************************/
1295
1067 /* debugging info */ 1296 /* debugging info */
1068 u32 indirect_dword; 1297 u32 indirect_dword;
1069 u32 direct_dword; 1298 u32 direct_dword;
@@ -1125,6 +1354,8 @@ do { if (ipw_debug_level & (level)) \
1125#define IPW_DL_RF_KILL (1<<17) 1354#define IPW_DL_RF_KILL (1<<17)
1126#define IPW_DL_FW_ERRORS (1<<18) 1355#define IPW_DL_FW_ERRORS (1<<18)
1127 1356
1357#define IPW_DL_LED (1<<19)
1358
1128#define IPW_DL_ORD (1<<20) 1359#define IPW_DL_ORD (1<<20)
1129 1360
1130#define IPW_DL_FRAG (1<<21) 1361#define IPW_DL_FRAG (1<<21)
@@ -1137,6 +1368,8 @@ do { if (ipw_debug_level & (level)) \
1137#define IPW_DL_TRACE (1<<28) 1368#define IPW_DL_TRACE (1<<28)
1138 1369
1139#define IPW_DL_STATS (1<<29) 1370#define IPW_DL_STATS (1<<29)
1371#define IPW_DL_MERGE (1<<30)
1372#define IPW_DL_QOS (1<<31)
1140 1373
1141#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) 1374#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
1142#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) 1375#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
@@ -1150,6 +1383,7 @@ do { if (ipw_debug_level & (level)) \
1150#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a) 1383#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a)
1151#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a) 1384#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
1152#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a) 1385#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
1386#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a)
1153#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a) 1387#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a)
1154#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) 1388#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
1155#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a) 1389#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
@@ -1163,6 +1397,8 @@ do { if (ipw_debug_level & (level)) \
1163#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1397#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1164#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1398#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1165#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a) 1399#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a)
1400#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a)
1401#define IPW_DEBUG_QOS(f, a...) IPW_DEBUG(IPW_DL_QOS, f, ## a)
1166 1402
1167#include <linux/ctype.h> 1403#include <linux/ctype.h>
1168 1404
@@ -1177,59 +1413,65 @@ do { if (ipw_debug_level & (level)) \
1177#define DINO_RXFIFO_DATA 0x01 1413#define DINO_RXFIFO_DATA 0x01
1178#define DINO_CONTROL_REG 0x00200000 1414#define DINO_CONTROL_REG 0x00200000
1179 1415
1180#define CX2_INTA_RW 0x00000008 1416#define IPW_INTA_RW 0x00000008
1181#define CX2_INTA_MASK_R 0x0000000C 1417#define IPW_INTA_MASK_R 0x0000000C
1182#define CX2_INDIRECT_ADDR 0x00000010 1418#define IPW_INDIRECT_ADDR 0x00000010
1183#define CX2_INDIRECT_DATA 0x00000014 1419#define IPW_INDIRECT_DATA 0x00000014
1184#define CX2_AUTOINC_ADDR 0x00000018 1420#define IPW_AUTOINC_ADDR 0x00000018
1185#define CX2_AUTOINC_DATA 0x0000001C 1421#define IPW_AUTOINC_DATA 0x0000001C
1186#define CX2_RESET_REG 0x00000020 1422#define IPW_RESET_REG 0x00000020
1187#define CX2_GP_CNTRL_RW 0x00000024 1423#define IPW_GP_CNTRL_RW 0x00000024
1188 1424
1189#define CX2_READ_INT_REGISTER 0xFF4 1425#define IPW_READ_INT_REGISTER 0xFF4
1190 1426
1191#define CX2_GP_CNTRL_BIT_INIT_DONE 0x00000004 1427#define IPW_GP_CNTRL_BIT_INIT_DONE 0x00000004
1192 1428
1193#define CX2_REGISTER_DOMAIN1_END 0x00001000 1429#define IPW_REGISTER_DOMAIN1_END 0x00001000
1194#define CX2_SRAM_READ_INT_REGISTER 0x00000ff4 1430#define IPW_SRAM_READ_INT_REGISTER 0x00000ff4
1195 1431
1196#define CX2_SHARED_LOWER_BOUND 0x00000200 1432#define IPW_SHARED_LOWER_BOUND 0x00000200
1197#define CX2_INTERRUPT_AREA_LOWER_BOUND 0x00000f80 1433#define IPW_INTERRUPT_AREA_LOWER_BOUND 0x00000f80
1198 1434
1199#define CX2_NIC_SRAM_LOWER_BOUND 0x00000000 1435#define IPW_NIC_SRAM_LOWER_BOUND 0x00000000
1200#define CX2_NIC_SRAM_UPPER_BOUND 0x00030000 1436#define IPW_NIC_SRAM_UPPER_BOUND 0x00030000
1201 1437
1202#define CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29) 1438#define IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29)
1203#define CX2_GP_CNTRL_BIT_CLOCK_READY 0x00000001 1439#define IPW_GP_CNTRL_BIT_CLOCK_READY 0x00000001
1204#define CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002 1440#define IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002
1205 1441
1206/* 1442/*
1207 * RESET Register Bit Indexes 1443 * RESET Register Bit Indexes
1208 */ 1444 */
1209#define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */ 1445#define CBD_RESET_REG_PRINCETON_RESET (1<<0)
1210#define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */ 1446#define IPW_START_STANDBY (1<<2)
1211#define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */ 1447#define IPW_ACTIVITY_LED (1<<4)
1212#define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */ 1448#define IPW_ASSOCIATED_LED (1<<5)
1213#define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */ 1449#define IPW_OFDM_LED (1<<6)
1214#define CX2_START_STANDBY 0x00000004 /* Bit 2 */ 1450#define IPW_RESET_REG_SW_RESET (1<<7)
1215 1451#define IPW_RESET_REG_MASTER_DISABLED (1<<8)
1216#define CX2_CSR_CIS_UPPER_BOUND 0x00000200 1452#define IPW_RESET_REG_STOP_MASTER (1<<9)
1217#define CX2_DOMAIN_0_END 0x1000 1453#define IPW_GATE_ODMA (1<<25)
1454#define IPW_GATE_IDMA (1<<26)
1455#define IPW_ARC_KESHET_CONFIG (1<<27)
1456#define IPW_GATE_ADMA (1<<29)
1457
1458#define IPW_CSR_CIS_UPPER_BOUND 0x00000200
1459#define IPW_DOMAIN_0_END 0x1000
1218#define CLX_MEM_BAR_SIZE 0x1000 1460#define CLX_MEM_BAR_SIZE 0x1000
1219 1461
1220#define CX2_BASEBAND_CONTROL_STATUS 0X00200000 1462#define IPW_BASEBAND_CONTROL_STATUS 0X00200000
1221#define CX2_BASEBAND_TX_FIFO_WRITE 0X00200004 1463#define IPW_BASEBAND_TX_FIFO_WRITE 0X00200004
1222#define CX2_BASEBAND_RX_FIFO_READ 0X00200004 1464#define IPW_BASEBAND_RX_FIFO_READ 0X00200004
1223#define CX2_BASEBAND_CONTROL_STORE 0X00200010 1465#define IPW_BASEBAND_CONTROL_STORE 0X00200010
1224 1466
1225#define CX2_INTERNAL_CMD_EVENT 0X00300004 1467#define IPW_INTERNAL_CMD_EVENT 0X00300004
1226#define CX2_BASEBAND_POWER_DOWN 0x00000001 1468#define IPW_BASEBAND_POWER_DOWN 0x00000001
1227 1469
1228#define CX2_MEM_HALT_AND_RESET 0x003000e0 1470#define IPW_MEM_HALT_AND_RESET 0x003000e0
1229 1471
1230/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */ 1472/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */
1231#define CX2_BIT_HALT_RESET_ON 0x80000000 1473#define IPW_BIT_HALT_RESET_ON 0x80000000
1232#define CX2_BIT_HALT_RESET_OFF 0x00000000 1474#define IPW_BIT_HALT_RESET_OFF 0x00000000
1233 1475
1234#define CB_LAST_VALID 0x20000000 1476#define CB_LAST_VALID 0x20000000
1235#define CB_INT_ENABLED 0x40000000 1477#define CB_INT_ENABLED 0x40000000
@@ -1248,63 +1490,63 @@ do { if (ipw_debug_level & (level)) \
1248#define DMA_CB_STOP_AND_ABORT 0x00000C00 1490#define DMA_CB_STOP_AND_ABORT 0x00000C00
1249#define DMA_CB_START 0x00000100 1491#define DMA_CB_START 0x00000100
1250 1492
1251#define CX2_SHARED_SRAM_SIZE 0x00030000 1493#define IPW_SHARED_SRAM_SIZE 0x00030000
1252#define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000 1494#define IPW_SHARED_SRAM_DMA_CONTROL 0x00027000
1253#define CB_MAX_LENGTH 0x1FFF 1495#define CB_MAX_LENGTH 0x1FFF
1254 1496
1255#define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18 1497#define IPW_HOST_EEPROM_DATA_SRAM_SIZE 0xA18
1256#define CX2_EEPROM_IMAGE_SIZE 0x100 1498#define IPW_EEPROM_IMAGE_SIZE 0x100
1257 1499
1258/* DMA defs */ 1500/* DMA defs */
1259#define CX2_DMA_I_CURRENT_CB 0x003000D0 1501#define IPW_DMA_I_CURRENT_CB 0x003000D0
1260#define CX2_DMA_O_CURRENT_CB 0x003000D4 1502#define IPW_DMA_O_CURRENT_CB 0x003000D4
1261#define CX2_DMA_I_DMA_CONTROL 0x003000A4 1503#define IPW_DMA_I_DMA_CONTROL 0x003000A4
1262#define CX2_DMA_I_CB_BASE 0x003000A0 1504#define IPW_DMA_I_CB_BASE 0x003000A0
1263 1505
1264#define CX2_TX_CMD_QUEUE_BD_BASE (0x00000200) 1506#define IPW_TX_CMD_QUEUE_BD_BASE 0x00000200
1265#define CX2_TX_CMD_QUEUE_BD_SIZE (0x00000204) 1507#define IPW_TX_CMD_QUEUE_BD_SIZE 0x00000204
1266#define CX2_TX_QUEUE_0_BD_BASE (0x00000208) 1508#define IPW_TX_QUEUE_0_BD_BASE 0x00000208
1267#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C) 1509#define IPW_TX_QUEUE_0_BD_SIZE (0x0000020C)
1268#define CX2_TX_QUEUE_1_BD_BASE (0x00000210) 1510#define IPW_TX_QUEUE_1_BD_BASE 0x00000210
1269#define CX2_TX_QUEUE_1_BD_SIZE (0x00000214) 1511#define IPW_TX_QUEUE_1_BD_SIZE 0x00000214
1270#define CX2_TX_QUEUE_2_BD_BASE (0x00000218) 1512#define IPW_TX_QUEUE_2_BD_BASE 0x00000218
1271#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C) 1513#define IPW_TX_QUEUE_2_BD_SIZE (0x0000021C)
1272#define CX2_TX_QUEUE_3_BD_BASE (0x00000220) 1514#define IPW_TX_QUEUE_3_BD_BASE 0x00000220
1273#define CX2_TX_QUEUE_3_BD_SIZE (0x00000224) 1515#define IPW_TX_QUEUE_3_BD_SIZE 0x00000224
1274#define CX2_RX_BD_BASE (0x00000240) 1516#define IPW_RX_BD_BASE 0x00000240
1275#define CX2_RX_BD_SIZE (0x00000244) 1517#define IPW_RX_BD_SIZE 0x00000244
1276#define CX2_RFDS_TABLE_LOWER (0x00000500) 1518#define IPW_RFDS_TABLE_LOWER 0x00000500
1277 1519
1278#define CX2_TX_CMD_QUEUE_READ_INDEX (0x00000280) 1520#define IPW_TX_CMD_QUEUE_READ_INDEX 0x00000280
1279#define CX2_TX_QUEUE_0_READ_INDEX (0x00000284) 1521#define IPW_TX_QUEUE_0_READ_INDEX 0x00000284
1280#define CX2_TX_QUEUE_1_READ_INDEX (0x00000288) 1522#define IPW_TX_QUEUE_1_READ_INDEX 0x00000288
1281#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C) 1523#define IPW_TX_QUEUE_2_READ_INDEX (0x0000028C)
1282#define CX2_TX_QUEUE_3_READ_INDEX (0x00000290) 1524#define IPW_TX_QUEUE_3_READ_INDEX 0x00000290
1283#define CX2_RX_READ_INDEX (0x000002A0) 1525#define IPW_RX_READ_INDEX (0x000002A0)
1284 1526
1285#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80) 1527#define IPW_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
1286#define CX2_TX_QUEUE_0_WRITE_INDEX (0x00000F84) 1528#define IPW_TX_QUEUE_0_WRITE_INDEX (0x00000F84)
1287#define CX2_TX_QUEUE_1_WRITE_INDEX (0x00000F88) 1529#define IPW_TX_QUEUE_1_WRITE_INDEX (0x00000F88)
1288#define CX2_TX_QUEUE_2_WRITE_INDEX (0x00000F8C) 1530#define IPW_TX_QUEUE_2_WRITE_INDEX (0x00000F8C)
1289#define CX2_TX_QUEUE_3_WRITE_INDEX (0x00000F90) 1531#define IPW_TX_QUEUE_3_WRITE_INDEX (0x00000F90)
1290#define CX2_RX_WRITE_INDEX (0x00000FA0) 1532#define IPW_RX_WRITE_INDEX (0x00000FA0)
1291 1533
1292/* 1534/*
1293 * EEPROM Related Definitions 1535 * EEPROM Related Definitions
1294 */ 1536 */
1295 1537
1296#define IPW_EEPROM_DATA_SRAM_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x814) 1538#define IPW_EEPROM_DATA_SRAM_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x814)
1297#define IPW_EEPROM_DATA_SRAM_SIZE (CX2_SHARED_LOWER_BOUND + 0x818) 1539#define IPW_EEPROM_DATA_SRAM_SIZE (IPW_SHARED_LOWER_BOUND + 0x818)
1298#define IPW_EEPROM_LOAD_DISABLE (CX2_SHARED_LOWER_BOUND + 0x81C) 1540#define IPW_EEPROM_LOAD_DISABLE (IPW_SHARED_LOWER_BOUND + 0x81C)
1299#define IPW_EEPROM_DATA (CX2_SHARED_LOWER_BOUND + 0x820) 1541#define IPW_EEPROM_DATA (IPW_SHARED_LOWER_BOUND + 0x820)
1300#define IPW_EEPROM_UPPER_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x9E0) 1542#define IPW_EEPROM_UPPER_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x9E0)
1301 1543
1302#define IPW_STATION_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0xA0C) 1544#define IPW_STATION_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0xA0C)
1303#define IPW_STATION_TABLE_UPPER (CX2_SHARED_LOWER_BOUND + 0xB0C) 1545#define IPW_STATION_TABLE_UPPER (IPW_SHARED_LOWER_BOUND + 0xB0C)
1304#define IPW_REQUEST_ATIM (CX2_SHARED_LOWER_BOUND + 0xB0C) 1546#define IPW_REQUEST_ATIM (IPW_SHARED_LOWER_BOUND + 0xB0C)
1305#define IPW_ATIM_SENT (CX2_SHARED_LOWER_BOUND + 0xB10) 1547#define IPW_ATIM_SENT (IPW_SHARED_LOWER_BOUND + 0xB10)
1306#define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14) 1548#define IPW_WHO_IS_AWAKE (IPW_SHARED_LOWER_BOUND + 0xB14)
1307#define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18) 1549#define IPW_DURING_ATIM_WINDOW (IPW_SHARED_LOWER_BOUND + 0xB18)
1308 1550
1309#define MSB 1 1551#define MSB 1
1310#define LSB 0 1552#define LSB 0
@@ -1326,15 +1568,15 @@ do { if (ipw_debug_level & (level)) \
1326#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ 1568#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */
1327 1569
1328/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ 1570/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/
1329#define EEPROM_NIC_TYPE_STANDARD 0 1571#define EEPROM_NIC_TYPE_0 0
1330#define EEPROM_NIC_TYPE_DELL 1 1572#define EEPROM_NIC_TYPE_1 1
1331#define EEPROM_NIC_TYPE_FUJITSU 2 1573#define EEPROM_NIC_TYPE_2 2
1332#define EEPROM_NIC_TYPE_IBM 3 1574#define EEPROM_NIC_TYPE_3 3
1333#define EEPROM_NIC_TYPE_HP 4 1575#define EEPROM_NIC_TYPE_4 4
1334 1576
1335#define FW_MEM_REG_LOWER_BOUND 0x00300000 1577#define FW_MEM_REG_LOWER_BOUND 0x00300000
1336#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) 1578#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40)
1337 1579#define IPW_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04)
1338#define EEPROM_BIT_SK (1<<0) 1580#define EEPROM_BIT_SK (1<<0)
1339#define EEPROM_BIT_CS (1<<1) 1581#define EEPROM_BIT_CS (1<<1)
1340#define EEPROM_BIT_DI (1<<2) 1582#define EEPROM_BIT_DI (1<<2)
@@ -1343,50 +1585,47 @@ do { if (ipw_debug_level & (level)) \
1343#define EEPROM_CMD_READ 0x2 1585#define EEPROM_CMD_READ 0x2
1344 1586
1345/* Interrupts masks */ 1587/* Interrupts masks */
1346#define CX2_INTA_NONE 0x00000000 1588#define IPW_INTA_NONE 0x00000000
1347 1589
1348#define CX2_INTA_BIT_RX_TRANSFER 0x00000002 1590#define IPW_INTA_BIT_RX_TRANSFER 0x00000002
1349#define CX2_INTA_BIT_STATUS_CHANGE 0x00000010 1591#define IPW_INTA_BIT_STATUS_CHANGE 0x00000010
1350#define CX2_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020 1592#define IPW_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020
1351 1593
1352//Inta Bits for CF 1594//Inta Bits for CF
1353#define CX2_INTA_BIT_TX_CMD_QUEUE 0x00000800 1595#define IPW_INTA_BIT_TX_CMD_QUEUE 0x00000800
1354#define CX2_INTA_BIT_TX_QUEUE_1 0x00001000 1596#define IPW_INTA_BIT_TX_QUEUE_1 0x00001000
1355#define CX2_INTA_BIT_TX_QUEUE_2 0x00002000 1597#define IPW_INTA_BIT_TX_QUEUE_2 0x00002000
1356#define CX2_INTA_BIT_TX_QUEUE_3 0x00004000 1598#define IPW_INTA_BIT_TX_QUEUE_3 0x00004000
1357#define CX2_INTA_BIT_TX_QUEUE_4 0x00008000 1599#define IPW_INTA_BIT_TX_QUEUE_4 0x00008000
1358 1600
1359#define CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000 1601#define IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000
1360 1602
1361#define CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000 1603#define IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000
1362#define CX2_INTA_BIT_POWER_DOWN 0x00200000 1604#define IPW_INTA_BIT_POWER_DOWN 0x00200000
1363 1605
1364#define CX2_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000 1606#define IPW_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000
1365#define CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000 1607#define IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000
1366#define CX2_INTA_BIT_RF_KILL_DONE 0x04000000 1608#define IPW_INTA_BIT_RF_KILL_DONE 0x04000000
1367#define CX2_INTA_BIT_FATAL_ERROR 0x40000000 1609#define IPW_INTA_BIT_FATAL_ERROR 0x40000000
1368#define CX2_INTA_BIT_PARITY_ERROR 0x80000000 1610#define IPW_INTA_BIT_PARITY_ERROR 0x80000000
1369 1611
1370/* Interrupts enabled at init time. */ 1612/* Interrupts enabled at init time. */
1371#define CX2_INTA_MASK_ALL \ 1613#define IPW_INTA_MASK_ALL \
1372 (CX2_INTA_BIT_TX_QUEUE_1 | \ 1614 (IPW_INTA_BIT_TX_QUEUE_1 | \
1373 CX2_INTA_BIT_TX_QUEUE_2 | \ 1615 IPW_INTA_BIT_TX_QUEUE_2 | \
1374 CX2_INTA_BIT_TX_QUEUE_3 | \ 1616 IPW_INTA_BIT_TX_QUEUE_3 | \
1375 CX2_INTA_BIT_TX_QUEUE_4 | \ 1617 IPW_INTA_BIT_TX_QUEUE_4 | \
1376 CX2_INTA_BIT_TX_CMD_QUEUE | \ 1618 IPW_INTA_BIT_TX_CMD_QUEUE | \
1377 CX2_INTA_BIT_RX_TRANSFER | \ 1619 IPW_INTA_BIT_RX_TRANSFER | \
1378 CX2_INTA_BIT_FATAL_ERROR | \ 1620 IPW_INTA_BIT_FATAL_ERROR | \
1379 CX2_INTA_BIT_PARITY_ERROR | \ 1621 IPW_INTA_BIT_PARITY_ERROR | \
1380 CX2_INTA_BIT_STATUS_CHANGE | \ 1622 IPW_INTA_BIT_STATUS_CHANGE | \
1381 CX2_INTA_BIT_FW_INITIALIZATION_DONE | \ 1623 IPW_INTA_BIT_FW_INITIALIZATION_DONE | \
1382 CX2_INTA_BIT_BEACON_PERIOD_EXPIRED | \ 1624 IPW_INTA_BIT_BEACON_PERIOD_EXPIRED | \
1383 CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \ 1625 IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
1384 CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN | \ 1626 IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN | \
1385 CX2_INTA_BIT_POWER_DOWN | \ 1627 IPW_INTA_BIT_POWER_DOWN | \
1386 CX2_INTA_BIT_RF_KILL_DONE ) 1628 IPW_INTA_BIT_RF_KILL_DONE )
1387
1388#define IPWSTATUS_ERROR_LOG (CX2_SHARED_LOWER_BOUND + 0x410)
1389#define IPW_EVENT_LOG (CX2_SHARED_LOWER_BOUND + 0x414)
1390 1629
1391/* FW event log definitions */ 1630/* FW event log definitions */
1392#define EVENT_ELEM_SIZE (3 * sizeof(u32)) 1631#define EVENT_ELEM_SIZE (3 * sizeof(u32))
@@ -1396,6 +1635,11 @@ do { if (ipw_debug_level & (level)) \
1396#define ERROR_ELEM_SIZE (7 * sizeof(u32)) 1635#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1397#define ERROR_START_OFFSET (1 * sizeof(u32)) 1636#define ERROR_START_OFFSET (1 * sizeof(u32))
1398 1637
1638/* TX power level (dbm) */
1639#define IPW_TX_POWER_MIN -12
1640#define IPW_TX_POWER_MAX 20
1641#define IPW_TX_POWER_DEFAULT IPW_TX_POWER_MAX
1642
1399enum { 1643enum {
1400 IPW_FW_ERROR_OK = 0, 1644 IPW_FW_ERROR_OK = 0,
1401 IPW_FW_ERROR_FAIL, 1645 IPW_FW_ERROR_FAIL,
@@ -1408,8 +1652,8 @@ enum {
1408 IPW_FW_ERROR_ALLOC_FAIL, 1652 IPW_FW_ERROR_ALLOC_FAIL,
1409 IPW_FW_ERROR_DMA_UNDERRUN, 1653 IPW_FW_ERROR_DMA_UNDERRUN,
1410 IPW_FW_ERROR_DMA_STATUS, 1654 IPW_FW_ERROR_DMA_STATUS,
1411 IPW_FW_ERROR_DINOSTATUS_ERROR, 1655 IPW_FW_ERROR_DINO_ERROR,
1412 IPW_FW_ERROR_EEPROMSTATUS_ERROR, 1656 IPW_FW_ERROR_EEPROM_ERROR,
1413 IPW_FW_ERROR_SYSASSERT, 1657 IPW_FW_ERROR_SYSASSERT,
1414 IPW_FW_ERROR_FATAL_ERROR 1658 IPW_FW_ERROR_FATAL_ERROR
1415}; 1659};
@@ -1425,6 +1669,8 @@ enum {
1425#define HC_IBSS_RECONF 4 1669#define HC_IBSS_RECONF 4
1426#define HC_DISASSOC_QUIET 5 1670#define HC_DISASSOC_QUIET 5
1427 1671
1672#define HC_QOS_SUPPORT_ASSOC 0x01
1673
1428#define IPW_RATE_CAPABILITIES 1 1674#define IPW_RATE_CAPABILITIES 1
1429#define IPW_RATE_CONNECT 0 1675#define IPW_RATE_CONNECT 0
1430 1676
@@ -1595,18 +1841,20 @@ enum {
1595 IPW_ORD_TABLE_7_LAST 1841 IPW_ORD_TABLE_7_LAST
1596}; 1842};
1597 1843
1598#define IPW_ORDINALS_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0x500) 1844#define IPW_ERROR_LOG (IPW_SHARED_LOWER_BOUND + 0x410)
1599#define IPW_ORDINALS_TABLE_0 (CX2_SHARED_LOWER_BOUND + 0x180) 1845#define IPW_EVENT_LOG (IPW_SHARED_LOWER_BOUND + 0x414)
1600#define IPW_ORDINALS_TABLE_1 (CX2_SHARED_LOWER_BOUND + 0x184) 1846#define IPW_ORDINALS_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0x500)
1601#define IPW_ORDINALS_TABLE_2 (CX2_SHARED_LOWER_BOUND + 0x188) 1847#define IPW_ORDINALS_TABLE_0 (IPW_SHARED_LOWER_BOUND + 0x180)
1602#define IPW_MEM_FIXED_OVERRIDE (CX2_SHARED_LOWER_BOUND + 0x41C) 1848#define IPW_ORDINALS_TABLE_1 (IPW_SHARED_LOWER_BOUND + 0x184)
1849#define IPW_ORDINALS_TABLE_2 (IPW_SHARED_LOWER_BOUND + 0x188)
1850#define IPW_MEM_FIXED_OVERRIDE (IPW_SHARED_LOWER_BOUND + 0x41C)
1603 1851
1604struct ipw_fixed_rate { 1852struct ipw_fixed_rate {
1605 u16 tx_rates; 1853 u16 tx_rates;
1606 u16 reserved; 1854 u16 reserved;
1607} __attribute__ ((packed)); 1855} __attribute__ ((packed));
1608 1856
1609#define CX2_INDIRECT_ADDR_MASK (~0x3ul) 1857#define IPW_INDIRECT_ADDR_MASK (~0x3ul)
1610 1858
1611struct host_cmd { 1859struct host_cmd {
1612 u8 cmd; 1860 u8 cmd;
@@ -1615,6 +1863,12 @@ struct host_cmd {
1615 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; 1863 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
1616} __attribute__ ((packed)); 1864} __attribute__ ((packed));
1617 1865
1866struct ipw_cmd_log {
1867 unsigned long jiffies;
1868 int retcode;
1869 struct host_cmd cmd;
1870};
1871
1618#define CFG_BT_COEXISTENCE_MIN 0x00 1872#define CFG_BT_COEXISTENCE_MIN 0x00
1619#define CFG_BT_COEXISTENCE_DEFER 0x02 1873#define CFG_BT_COEXISTENCE_DEFER 0x02
1620#define CFG_BT_COEXISTENCE_KILL 0x04 1874#define CFG_BT_COEXISTENCE_KILL 0x04
@@ -1643,15 +1897,6 @@ struct host_cmd {
1643#define REG_CHANNEL_MASK 0x00003FFF 1897#define REG_CHANNEL_MASK 0x00003FFF
1644#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff 1898#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
1645 1899
1646static const long ipw_frequencies[] = {
1647 2412, 2417, 2422, 2427,
1648 2432, 2437, 2442, 2447,
1649 2452, 2457, 2462, 2467,
1650 2472, 2484
1651};
1652
1653#define FREQ_COUNT ARRAY_SIZE(ipw_frequencies)
1654
1655#define IPW_MAX_CONFIG_RETRIES 10 1900#define IPW_MAX_CONFIG_RETRIES 10
1656 1901
1657static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr) 1902static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 7a17bb31fc89..f5d856db92a1 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -12,7 +12,6 @@
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <linux/wireless.h> 13#include <linux/wireless.h>
14#include <net/iw_handler.h> 14#include <net/iw_handler.h>
15#include <linux/version.h>
16 15
17#include "hermes.h" 16#include "hermes.h"
18 17
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index adc7499136dc..109a96d90007 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/types.h> 22#include <linux/types.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
@@ -112,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
112void 111void
113isl38xx_trigger_device(int asleep, void __iomem *device_base) 112isl38xx_trigger_device(int asleep, void __iomem *device_base)
114{ 113{
115 u32 reg, counter = 0; 114 u32 reg;
116 115
117#if VERBOSE > SHOW_ERROR_MESSAGES 116#if VERBOSE > SHOW_ERROR_MESSAGES
117 u32 counter = 0;
118 struct timeval current_time; 118 struct timeval current_time;
119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n"); 119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
120#endif 120#endif
@@ -131,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
131 current_time.tv_sec, (long)current_time.tv_usec, 131 current_time.tv_sec, (long)current_time.tv_usec,
132 readl(device_base + ISL38XX_CTRL_STAT_REG)); 132 readl(device_base + ISL38XX_CTRL_STAT_REG));
133#endif 133#endif
134 udelay(ISL38XX_WRITEIO_DELAY);
135 134
136 reg = readl(device_base + ISL38XX_INT_IDENT_REG); 135 reg = readl(device_base + ISL38XX_INT_IDENT_REG);
137 if (reg == 0xabadface) { 136 if (reg == 0xabadface) {
@@ -145,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
145 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG), 144 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
146 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) { 145 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
147 udelay(ISL38XX_WRITEIO_DELAY); 146 udelay(ISL38XX_WRITEIO_DELAY);
147#if VERBOSE > SHOW_ERROR_MESSAGES
148 counter++; 148 counter++;
149#endif
149 } 150 }
150 151
151#if VERBOSE > SHOW_ERROR_MESSAGES 152#if VERBOSE > SHOW_ERROR_MESSAGES
@@ -153,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
153 "%08li.%08li Device register read %08x\n", 154 "%08li.%08li Device register read %08x\n",
154 current_time.tv_sec, (long)current_time.tv_usec, 155 current_time.tv_sec, (long)current_time.tv_usec,
155 readl(device_base + ISL38XX_CTRL_STAT_REG)); 156 readl(device_base + ISL38XX_CTRL_STAT_REG));
156#endif
157 udelay(ISL38XX_WRITEIO_DELAY);
158
159#if VERBOSE > SHOW_ERROR_MESSAGES
160 do_gettimeofday(&current_time); 157 do_gettimeofday(&current_time);
161 DEBUG(SHOW_TRACING, 158 DEBUG(SHOW_TRACING,
162 "%08li.%08li Device asleep counter %i\n", 159 "%08li.%08li Device asleep counter %i\n",
@@ -171,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
171 168
172 /* perform another read on the Device Status Register */ 169 /* perform another read on the Device Status Register */
173 reg = readl(device_base + ISL38XX_CTRL_STAT_REG); 170 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
174 udelay(ISL38XX_WRITEIO_DELAY);
175 171
176#if VERBOSE > SHOW_ERROR_MESSAGES 172#if VERBOSE > SHOW_ERROR_MESSAGES
177 do_gettimeofday(&current_time); 173 do_gettimeofday(&current_time);
@@ -187,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
187 183
188 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE, 184 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
189 ISL38XX_DEV_INT_REG); 185 ISL38XX_DEV_INT_REG);
190 udelay(ISL38XX_WRITEIO_DELAY);
191 } 186 }
192} 187}
193 188
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index e83e4912ab66..8af20980af8d 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -20,7 +20,6 @@
20#ifndef _ISL_38XX_H 20#ifndef _ISL_38XX_H
21#define _ISL_38XX_H 21#define _ISL_38XX_H
22 22
23#include <linux/version.h>
24#include <asm/io.h> 23#include <asm/io.h>
25#include <asm/byteorder.h> 24#include <asm/byteorder.h>
26 25
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 5c1a1adf1ff8..135a156db25d 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
26#include <linux/if_arp.h> 25#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 78bdb359835e..5ddf29599032 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/version.h>
23#include <linux/module.h> 22#include <linux/module.h>
24 23
25#include <linux/netdevice.h> 24#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index efbed4397951..07053165e4c5 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -23,7 +23,6 @@
23#ifndef _ISLPCI_DEV_H 23#ifndef _ISLPCI_DEV_H
24#define _ISLPCI_DEV_H 24#define _ISLPCI_DEV_H
25 25
26#include <linux/version.h>
27#include <linux/netdevice.h> 26#include <linux/netdevice.h>
28#include <linux/wireless.h> 27#include <linux/wireless.h>
29#include <net/iw_handler.h> 28#include <net/iw_handler.h>
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index fc1eb3564832..33d64d2ee53f 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -17,7 +17,6 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/version.h>
21#include <linux/module.h> 20#include <linux/module.h>
22 21
23#include <linux/pci.h> 22#include <linux/pci.h>
@@ -227,17 +226,17 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
227 priv->data_low_tx_full = 1; 226 priv->data_low_tx_full = 1;
228 } 227 }
229 228
229 /* set the transmission time */
230 ndev->trans_start = jiffies;
231 priv->statistics.tx_packets++;
232 priv->statistics.tx_bytes += skb->len;
233
230 /* trigger the device */ 234 /* trigger the device */
231 islpci_trigger(priv); 235 islpci_trigger(priv);
232 236
233 /* unlock the driver code */ 237 /* unlock the driver code */
234 spin_unlock_irqrestore(&priv->slock, flags); 238 spin_unlock_irqrestore(&priv->slock, flags);
235 239
236 /* set the transmission time */
237 ndev->trans_start = jiffies;
238 priv->statistics.tx_packets++;
239 priv->statistics.tx_bytes += skb->len;
240
241 return 0; 240 return 0;
242 241
243 drop_free: 242 drop_free:
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index dc040caab7d7..b41d666fea3c 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 4b3c98f5c564..c822cad3333f 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4608,9 +4608,8 @@ wavelan_attach(void)
4608#endif 4608#endif
4609 4609
4610 /* Initialize the dev_link_t structure */ 4610 /* Initialize the dev_link_t structure */
4611 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 4611 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
4612 if (!link) return NULL; 4612 if (!link) return NULL;
4613 memset(link, 0, sizeof(struct dev_link_t));
4614 4613
4615 /* The io structure describes IO port mapping */ 4614 /* The io structure describes IO port mapping */
4616 link->io.NumPorts1 = 8; 4615 link->io.NumPorts1 = 8;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 3f8c27f0871b..978fdc606781 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void)
1965 int ret; 1965 int ret;
1966 1966
1967 /* Initialize the dev_link_t structure */ 1967 /* Initialize the dev_link_t structure */
1968 link = kmalloc(sizeof(*link), GFP_KERNEL); 1968 link = kzalloc(sizeof(*link), GFP_KERNEL);
1969 if (!link) 1969 if (!link)
1970 goto out; 1970 goto out;
1971 memset(link, 0, sizeof(struct dev_link_t));
1972 1971
1973 /* The io structure describes IO port mapping */ 1972 /* The io structure describes IO port mapping */
1974 link->io.NumPorts1 = 16; 1973 link->io.NumPorts1 = 16;
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 2a42add7f563..ea16805a153c 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -2,6 +2,8 @@
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/ioport.h> 3#include <linux/ioport.h>
4 4
5#include "pci.h"
6
5/* 7/*
6 * This interrupt-safe spinlock protects all accesses to PCI 8 * This interrupt-safe spinlock protects all accesses to PCI
7 * configuration space. 9 * configuration space.
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 061ead21ef14..c42b68d3aa24 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -32,8 +32,6 @@
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <asm/semaphore.h>
36#include <asm/io.h>
37#include <linux/pcieport_if.h> 35#include <linux/pcieport_if.h>
38#include "pci_hotplug.h" 36#include "pci_hotplug.h"
39 37
@@ -42,6 +40,7 @@
42extern int pciehp_poll_mode; 40extern int pciehp_poll_mode;
43extern int pciehp_poll_time; 41extern int pciehp_poll_time;
44extern int pciehp_debug; 42extern int pciehp_debug;
43extern int pciehp_force;
45 44
46/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ 45/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
47#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) 46#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
@@ -49,39 +48,20 @@ extern int pciehp_debug;
49#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) 48#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
50#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) 49#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
51 50
52struct pci_func { 51struct hotplug_params {
53 struct pci_func *next; 52 u8 cache_line_size;
54 u8 bus; 53 u8 latency_timer;
55 u8 device; 54 u8 enable_serr;
56 u8 function; 55 u8 enable_perr;
57 u8 is_a_board;
58 u16 status;
59 u8 configured;
60 u8 switch_save;
61 u8 presence_save;
62 u32 base_length[0x06];
63 u8 base_type[0x06];
64 u16 reserved2;
65 u32 config_space[0x20];
66 struct pci_resource *mem_head;
67 struct pci_resource *p_mem_head;
68 struct pci_resource *io_head;
69 struct pci_resource *bus_head;
70 struct pci_dev* pci_dev;
71}; 56};
72 57
73struct slot { 58struct slot {
74 struct slot *next; 59 struct slot *next;
75 u8 bus; 60 u8 bus;
76 u8 device; 61 u8 device;
62 u16 status;
77 u32 number; 63 u32 number;
78 u8 is_a_board;
79 u8 configured;
80 u8 state; 64 u8 state;
81 u8 switch_save;
82 u8 presence_save;
83 u32 capabilities;
84 u16 reserved2;
85 struct timer_list task_event; 65 struct timer_list task_event;
86 u8 hp_slot; 66 u8 hp_slot;
87 struct controller *ctrl; 67 struct controller *ctrl;
@@ -90,42 +70,47 @@ struct slot {
90 struct list_head slot_list; 70 struct list_head slot_list;
91}; 71};
92 72
93struct pci_resource {
94 struct pci_resource * next;
95 u32 base;
96 u32 length;
97};
98
99struct event_info { 73struct event_info {
100 u32 event_type; 74 u32 event_type;
101 u8 hp_slot; 75 u8 hp_slot;
102}; 76};
103 77
78typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
79
80struct php_ctlr_state_s {
81 struct php_ctlr_state_s *pnext;
82 struct pci_dev *pci_dev;
83 unsigned int irq;
84 unsigned long flags; /* spinlock's */
85 u32 slot_device_offset;
86 u32 num_slots;
87 struct timer_list int_poll_timer; /* Added for poll event */
88 php_intr_callback_t attention_button_callback;
89 php_intr_callback_t switch_change_callback;
90 php_intr_callback_t presence_change_callback;
91 php_intr_callback_t power_fault_callback;
92 void *callback_instance_id;
93 struct ctrl_reg *creg; /* Ptr to controller register space */
94};
95
96#define MAX_EVENTS 10
104struct controller { 97struct controller {
105 struct controller *next; 98 struct controller *next;
106 struct semaphore crit_sect; /* critical section semaphore */ 99 struct semaphore crit_sect; /* critical section semaphore */
107 void *hpc_ctlr_handle; /* HPC controller handle */ 100 struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
108 int num_slots; /* Number of slots on ctlr */ 101 int num_slots; /* Number of slots on ctlr */
109 int slot_num_inc; /* 1 or -1 */ 102 int slot_num_inc; /* 1 or -1 */
110 struct pci_resource *mem_head;
111 struct pci_resource *p_mem_head;
112 struct pci_resource *io_head;
113 struct pci_resource *bus_head;
114 struct pci_dev *pci_dev; 103 struct pci_dev *pci_dev;
115 struct pci_bus *pci_bus; 104 struct pci_bus *pci_bus;
116 struct event_info event_queue[10]; 105 struct event_info event_queue[MAX_EVENTS];
117 struct slot *slot; 106 struct slot *slot;
118 struct hpc_ops *hpc_ops; 107 struct hpc_ops *hpc_ops;
119 wait_queue_head_t queue; /* sleep & wake process */ 108 wait_queue_head_t queue; /* sleep & wake process */
120 u8 next_event; 109 u8 next_event;
121 u8 seg;
122 u8 bus; 110 u8 bus;
123 u8 device; 111 u8 device;
124 u8 function; 112 u8 function;
125 u8 rev;
126 u8 slot_device_offset; 113 u8 slot_device_offset;
127 u8 add_support;
128 enum pci_bus_speed speed;
129 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ 114 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
130 u8 slot_bus; /* Bus where the slots handled by this controller sit */ 115 u8 slot_bus; /* Bus where the slots handled by this controller sit */
131 u8 ctrlcap; 116 u8 ctrlcap;
@@ -133,20 +118,6 @@ struct controller {
133 u8 cap_base; 118 u8 cap_base;
134}; 119};
135 120
136struct irq_mapping {
137 u8 barber_pole;
138 u8 valid_INT;
139 u8 interrupt[4];
140};
141
142struct resource_lists {
143 struct pci_resource *mem_head;
144 struct pci_resource *p_mem_head;
145 struct pci_resource *io_head;
146 struct pci_resource *bus_head;
147 struct irq_mapping *irqs;
148};
149
150#define INT_BUTTON_IGNORE 0 121#define INT_BUTTON_IGNORE 0
151#define INT_PRESENCE_ON 1 122#define INT_PRESENCE_ON 1
152#define INT_PRESENCE_OFF 2 123#define INT_PRESENCE_OFF 2
@@ -200,21 +171,14 @@ struct resource_lists {
200 * error Messages 171 * error Messages
201 */ 172 */
202#define msg_initialization_err "Initialization failure, error=%d\n" 173#define msg_initialization_err "Initialization failure, error=%d\n"
203#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
204#define msg_HPC_non_pcie "The PCI hot plug controller is not supported by this driver.\n"
205#define msg_HPC_not_supported "This system is not supported by this version of pciephd module. Upgrade to a newer version of pciehpd\n"
206#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
207#define msg_button_on "PCI slot #%d - powering on due to button press.\n" 174#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
208#define msg_button_off "PCI slot #%d - powering off due to button press.\n" 175#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
209#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" 176#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
210#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" 177#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
211 178
212/* controller functions */ 179/* controller functions */
213extern int pciehprm_find_available_resources (struct controller *ctrl);
214extern int pciehp_event_start_thread (void); 180extern int pciehp_event_start_thread (void);
215extern void pciehp_event_stop_thread (void); 181extern void pciehp_event_stop_thread (void);
216extern struct pci_func *pciehp_slot_create (unsigned char busnumber);
217extern struct pci_func *pciehp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
218extern int pciehp_enable_slot (struct slot *slot); 182extern int pciehp_enable_slot (struct slot *slot);
219extern int pciehp_disable_slot (struct slot *slot); 183extern int pciehp_disable_slot (struct slot *slot);
220 184
@@ -224,25 +188,17 @@ extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
224extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); 188extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
225/* extern void long_delay (int delay); */ 189/* extern void long_delay (int delay); */
226 190
227/* resource functions */
228extern int pciehp_resource_sort_and_combine (struct pci_resource **head);
229
230/* pci functions */ 191/* pci functions */
231extern int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); 192extern int pciehp_configure_device (struct slot *p_slot);
232/*extern int pciehp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/ 193extern int pciehp_unconfigure_device (struct slot *p_slot);
233extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); 194extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
234extern int pciehp_save_used_resources (struct controller *ctrl, struct pci_func * func, int flag); 195extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
235extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot); 196 struct hotplug_params *hpp);
236extern void pciehp_destroy_board_resources (struct pci_func * func); 197
237extern int pciehp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
238extern void pciehp_destroy_resource_list (struct resource_lists * resources);
239extern int pciehp_configure_device (struct controller* ctrl, struct pci_func* func);
240extern int pciehp_unconfigure_device (struct pci_func* func);
241 198
242 199
243/* Global variables */ 200/* Global variables */
244extern struct controller *pciehp_ctrl_list; 201extern struct controller *pciehp_ctrl_list;
245extern struct pci_func *pciehp_slot_list[256];
246 202
247/* Inline functions */ 203/* Inline functions */
248 204
@@ -252,12 +208,9 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
252 208
253 p_slot = ctrl->slot; 209 p_slot = ctrl->slot;
254 210
255 dbg("p_slot = %p\n", p_slot);
256
257 while (p_slot && (p_slot->device != device)) { 211 while (p_slot && (p_slot->device != device)) {
258 tmp_slot = p_slot; 212 tmp_slot = p_slot;
259 p_slot = p_slot->next; 213 p_slot = p_slot->next;
260 dbg("In while loop, p_slot = %p\n", p_slot);
261 } 214 }
262 if (p_slot == NULL) { 215 if (p_slot == NULL) {
263 err("ERROR: pciehp_find_slot device=0x%x\n", device); 216 err("ERROR: pciehp_find_slot device=0x%x\n", device);
@@ -273,7 +226,6 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
273 226
274 DECLARE_WAITQUEUE(wait, current); 227 DECLARE_WAITQUEUE(wait, current);
275 228
276 dbg("%s : start\n", __FUNCTION__);
277 add_wait_queue(&ctrl->queue, &wait); 229 add_wait_queue(&ctrl->queue, &wait);
278 if (!pciehp_poll_mode) 230 if (!pciehp_poll_mode)
279 /* Sleep for up to 1 second */ 231 /* Sleep for up to 1 second */
@@ -285,19 +237,9 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
285 if (signal_pending(current)) 237 if (signal_pending(current))
286 retval = -EINTR; 238 retval = -EINTR;
287 239
288 dbg("%s : end\n", __FUNCTION__);
289 return retval; 240 return retval;
290} 241}
291 242
292/* Puts node back in the resource list pointed to by head */
293static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
294{
295 if (!node || !head)
296 return;
297 node->next = *head;
298 *head = node;
299}
300
301#define SLOT_NAME_SIZE 10 243#define SLOT_NAME_SIZE 10
302 244
303static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) 245static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
@@ -311,14 +253,7 @@ enum php_ctlr_type {
311 ACPI 253 ACPI
312}; 254};
313 255
314typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id); 256int pcie_init(struct controller *ctrl, struct pcie_device *dev);
315
316int pcie_init(struct controller *ctrl, struct pcie_device *dev,
317 php_intr_callback_t attention_button_callback,
318 php_intr_callback_t switch_change_callback,
319 php_intr_callback_t presence_change_callback,
320 php_intr_callback_t power_fault_callback);
321
322 257
323/* This has no meaning for PCI Express, as there is only 1 slot per port */ 258/* This has no meaning for PCI Express, as there is only 1 slot per port */
324int pcie_get_ctlr_slot_config(struct controller *ctrl, 259int pcie_get_ctlr_slot_config(struct controller *ctrl,
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index cafc7eadcf80..8df704860348 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -27,27 +27,20 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
34#include <linux/types.h> 33#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/slab.h>
37#include <linux/workqueue.h>
38#include <linux/pci.h> 34#include <linux/pci.h>
39#include <linux/init.h>
40#include <asm/uaccess.h>
41#include "pciehp.h" 35#include "pciehp.h"
42#include "pciehprm.h"
43#include <linux/interrupt.h> 36#include <linux/interrupt.h>
44 37
45/* Global variables */ 38/* Global variables */
46int pciehp_debug; 39int pciehp_debug;
47int pciehp_poll_mode; 40int pciehp_poll_mode;
48int pciehp_poll_time; 41int pciehp_poll_time;
42int pciehp_force;
49struct controller *pciehp_ctrl_list; 43struct controller *pciehp_ctrl_list;
50struct pci_func *pciehp_slot_list[256];
51 44
52#define DRIVER_VERSION "0.4" 45#define DRIVER_VERSION "0.4"
53#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" 46#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
@@ -60,9 +53,11 @@ MODULE_LICENSE("GPL");
60module_param(pciehp_debug, bool, 0644); 53module_param(pciehp_debug, bool, 0644);
61module_param(pciehp_poll_mode, bool, 0644); 54module_param(pciehp_poll_mode, bool, 0644);
62module_param(pciehp_poll_time, int, 0644); 55module_param(pciehp_poll_time, int, 0644);
56module_param(pciehp_force, bool, 0644);
63MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); 57MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
64MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 58MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
65MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 59MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
60MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
66 61
67#define PCIE_MODULE_NAME "pciehp" 62#define PCIE_MODULE_NAME "pciehp"
68 63
@@ -114,8 +109,6 @@ static int init_slots(struct controller *ctrl)
114 u32 slot_number; 109 u32 slot_number;
115 int result = -ENOMEM; 110 int result = -ENOMEM;
116 111
117 dbg("%s\n",__FUNCTION__);
118
119 number_of_slots = ctrl->num_slots; 112 number_of_slots = ctrl->num_slots;
120 slot_device = ctrl->slot_device_offset; 113 slot_device = ctrl->slot_device_offset;
121 slot_number = ctrl->first_slot; 114 slot_number = ctrl->first_slot;
@@ -370,7 +363,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
370 u8 value; 363 u8 value;
371 struct pci_dev *pdev; 364 struct pci_dev *pdev;
372 365
373 dbg("%s: Called by hp_drv\n", __FUNCTION__);
374 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL); 366 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
375 if (!ctrl) { 367 if (!ctrl) {
376 err("%s : out of memory\n", __FUNCTION__); 368 err("%s : out of memory\n", __FUNCTION__);
@@ -378,22 +370,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
378 } 370 }
379 memset(ctrl, 0, sizeof(struct controller)); 371 memset(ctrl, 0, sizeof(struct controller));
380 372
381 dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
382
383 pdev = dev->port; 373 pdev = dev->port;
374 ctrl->pci_dev = pdev;
384 375
385 rc = pcie_init(ctrl, dev, 376 rc = pcie_init(ctrl, dev);
386 (php_intr_callback_t) pciehp_handle_attention_button,
387 (php_intr_callback_t) pciehp_handle_switch_change,
388 (php_intr_callback_t) pciehp_handle_presence_change,
389 (php_intr_callback_t) pciehp_handle_power_fault);
390 if (rc) { 377 if (rc) {
391 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME); 378 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
392 goto err_out_free_ctrl; 379 goto err_out_free_ctrl;
393 } 380 }
394 381
395 ctrl->pci_dev = pdev;
396
397 pci_set_drvdata(pdev, ctrl); 382 pci_set_drvdata(pdev, ctrl);
398 383
399 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); 384 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
@@ -402,7 +387,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
402 rc = -ENOMEM; 387 rc = -ENOMEM;
403 goto err_out_unmap_mmio_region; 388 goto err_out_unmap_mmio_region;
404 } 389 }
405 dbg("%s: ctrl->pci_bus %p\n", __FUNCTION__, ctrl->pci_bus);
406 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); 390 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
407 ctrl->bus = pdev->bus->number; /* ctrl bus */ 391 ctrl->bus = pdev->bus->number; /* ctrl bus */
408 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ 392 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
@@ -424,25 +408,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
424 first_device_num = ctrl->slot_device_offset; 408 first_device_num = ctrl->slot_device_offset;
425 num_ctlr_slots = ctrl->num_slots; 409 num_ctlr_slots = ctrl->num_slots;
426 410
427 /* Store PCI Config Space for all devices on this bus */
428 dbg("%s: Before calling pciehp_save_config, ctrl->bus %x,ctrl->slot_bus %x\n",
429 __FUNCTION__,ctrl->bus, ctrl->slot_bus);
430 rc = pciehp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
431 if (rc) {
432 err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
433 goto err_out_free_ctrl_bus;
434 }
435
436 /* Get IO, memory, and IRQ resources for new devices */
437 rc = pciehprm_find_available_resources(ctrl);
438 ctrl->add_support = !rc;
439
440 if (rc) {
441 dbg("pciehprm_find_available_resources = %#x\n", rc);
442 err("unable to locate PCI configuration resources for hot plug add.\n");
443 goto err_out_free_ctrl_bus;
444 }
445
446 /* Setup the slot information structures */ 411 /* Setup the slot information structures */
447 rc = init_slots(ctrl); 412 rc = init_slots(ctrl);
448 if (rc) { 413 if (rc) {
@@ -451,7 +416,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
451 } 416 }
452 417
453 t_slot = pciehp_find_slot(ctrl, first_device_num); 418 t_slot = pciehp_find_slot(ctrl, first_device_num);
454 dbg("%s: t_slot %p\n", __FUNCTION__, t_slot);
455 419
456 /* Finish setting up the hot plug ctrl device */ 420 /* Finish setting up the hot plug ctrl device */
457 ctrl->next_event = 0; 421 ctrl->next_event = 0;
@@ -468,7 +432,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
468 down(&ctrl->crit_sect); 432 down(&ctrl->crit_sect);
469 433
470 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ 434 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
471 dbg("%s: adpater value %x\n", __FUNCTION__, value);
472 435
473 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { 436 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
474 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ 437 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
@@ -501,7 +464,6 @@ err_out_none:
501 464
502static int pcie_start_thread(void) 465static int pcie_start_thread(void)
503{ 466{
504 int loop;
505 int retval = 0; 467 int retval = 0;
506 468
507 dbg("Initialize + Start the notification/polling mechanism \n"); 469 dbg("Initialize + Start the notification/polling mechanism \n");
@@ -512,32 +474,11 @@ static int pcie_start_thread(void)
512 return retval; 474 return retval;
513 } 475 }
514 476
515 dbg("Initialize slot lists\n");
516 /* One slot list for each bus in the system */
517 for (loop = 0; loop < 256; loop++) {
518 pciehp_slot_list[loop] = NULL;
519 }
520
521 return retval; 477 return retval;
522} 478}
523 479
524static inline void __exit
525free_pciehp_res(struct pci_resource *res)
526{
527 struct pci_resource *tres;
528
529 while (res) {
530 tres = res;
531 res = res->next;
532 kfree(tres);
533 }
534}
535
536static void __exit unload_pciehpd(void) 480static void __exit unload_pciehpd(void)
537{ 481{
538 struct pci_func *next;
539 struct pci_func *TempSlot;
540 int loop;
541 struct controller *ctrl; 482 struct controller *ctrl;
542 struct controller *tctrl; 483 struct controller *tctrl;
543 484
@@ -546,11 +487,6 @@ static void __exit unload_pciehpd(void)
546 while (ctrl) { 487 while (ctrl) {
547 cleanup_slots(ctrl); 488 cleanup_slots(ctrl);
548 489
549 free_pciehp_res(ctrl->io_head);
550 free_pciehp_res(ctrl->mem_head);
551 free_pciehp_res(ctrl->p_mem_head);
552 free_pciehp_res(ctrl->bus_head);
553
554 kfree (ctrl->pci_bus); 490 kfree (ctrl->pci_bus);
555 491
556 ctrl->hpc_ops->release_ctlr(ctrl); 492 ctrl->hpc_ops->release_ctlr(ctrl);
@@ -561,20 +497,6 @@ static void __exit unload_pciehpd(void)
561 kfree(tctrl); 497 kfree(tctrl);
562 } 498 }
563 499
564 for (loop = 0; loop < 256; loop++) {
565 next = pciehp_slot_list[loop];
566 while (next != NULL) {
567 free_pciehp_res(next->io_head);
568 free_pciehp_res(next->mem_head);
569 free_pciehp_res(next->p_mem_head);
570 free_pciehp_res(next->bus_head);
571
572 TempSlot = next;
573 next = next->next;
574 kfree(TempSlot);
575 }
576 }
577
578 /* Stop the notification mechanism */ 500 /* Stop the notification mechanism */
579 pciehp_event_stop_thread(); 501 pciehp_event_stop_thread();
580 502
@@ -639,21 +561,16 @@ static int __init pcied_init(void)
639 if (retval) 561 if (retval)
640 goto error_hpc_init; 562 goto error_hpc_init;
641 563
642 retval = pciehprm_init(PCI); 564 retval = pcie_port_service_register(&hpdriver_portdrv);
643 if (!retval) { 565 dbg("pcie_port_service_register = %d\n", retval);
644 retval = pcie_port_service_register(&hpdriver_portdrv); 566 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
645 dbg("pcie_port_service_register = %d\n", retval); 567 if (retval)
646 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 568 dbg("%s: Failure to register service\n", __FUNCTION__);
647 if (retval)
648 dbg("%s: Failure to register service\n", __FUNCTION__);
649 }
650 569
651error_hpc_init: 570error_hpc_init:
652 if (retval) { 571 if (retval) {
653 pciehprm_cleanup();
654 pciehp_event_stop_thread(); 572 pciehp_event_stop_thread();
655 } else 573 };
656 pciehprm_print_pirt();
657 574
658 return retval; 575 return retval;
659} 576}
@@ -663,9 +580,6 @@ static void __exit pcied_cleanup(void)
663 dbg("unload_pciehpd()\n"); 580 dbg("unload_pciehpd()\n");
664 unload_pciehpd(); 581 unload_pciehpd();
665 582
666 pciehprm_cleanup();
667
668 dbg("pcie_port_service_unregister\n");
669 pcie_port_service_unregister(&hpdriver_portdrv); 583 pcie_port_service_unregister(&hpdriver_portdrv);
670 584
671 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); 585 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 898f6da6f0de..5e582eca21d8 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -27,25 +27,14 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/interrupt.h>
37#include <linux/delay.h>
38#include <linux/wait.h>
39#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
40#include <linux/pci.h> 34#include <linux/pci.h>
41#include "../pci.h" 35#include "../pci.h"
42#include "pciehp.h" 36#include "pciehp.h"
43#include "pciehprm.h"
44 37
45static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
46 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
47static int configure_new_function( struct controller *ctrl, struct pci_func *func,
48 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
49static void interrupt_event_handler(struct controller *ctrl); 38static void interrupt_event_handler(struct controller *ctrl);
50 39
51static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ 40static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
@@ -60,22 +49,18 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
60 struct slot *p_slot; 49 struct slot *p_slot;
61 u8 rc = 0; 50 u8 rc = 0;
62 u8 getstatus; 51 u8 getstatus;
63 struct pci_func *func;
64 struct event_info *taskInfo; 52 struct event_info *taskInfo;
65 53
66 /* Attention Button Change */ 54 /* Attention Button Change */
67 dbg("pciehp: Attention button interrupt received.\n"); 55 dbg("pciehp: Attention button interrupt received.\n");
68 56
69 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
70
71 /* This is the structure that tells the worker thread what to do */ 57 /* This is the structure that tells the worker thread what to do */
72 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 58 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
73 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 59 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
74 60
75 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
76 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 61 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
77 62
78 ctrl->next_event = (ctrl->next_event + 1) % 10; 63 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
79 taskInfo->hp_slot = hp_slot; 64 taskInfo->hp_slot = hp_slot;
80 65
81 rc++; 66 rc++;
@@ -117,24 +102,20 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
117 struct slot *p_slot; 102 struct slot *p_slot;
118 u8 rc = 0; 103 u8 rc = 0;
119 u8 getstatus; 104 u8 getstatus;
120 struct pci_func *func;
121 struct event_info *taskInfo; 105 struct event_info *taskInfo;
122 106
123 /* Switch Change */ 107 /* Switch Change */
124 dbg("pciehp: Switch interrupt received.\n"); 108 dbg("pciehp: Switch interrupt received.\n");
125 109
126 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
127
128 /* This is the structure that tells the worker thread 110 /* This is the structure that tells the worker thread
129 * what to do 111 * what to do
130 */ 112 */
131 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 113 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
132 ctrl->next_event = (ctrl->next_event + 1) % 10; 114 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
133 taskInfo->hp_slot = hp_slot; 115 taskInfo->hp_slot = hp_slot;
134 116
135 rc++; 117 rc++;
136 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 118 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
137 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
138 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 119 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
139 120
140 if (getstatus) { 121 if (getstatus) {
@@ -142,14 +123,12 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
142 * Switch opened 123 * Switch opened
143 */ 124 */
144 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); 125 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
145 func->switch_save = 0;
146 taskInfo->event_type = INT_SWITCH_OPEN; 126 taskInfo->event_type = INT_SWITCH_OPEN;
147 } else { 127 } else {
148 /* 128 /*
149 * Switch closed 129 * Switch closed
150 */ 130 */
151 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); 131 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
152 func->switch_save = 0x10;
153 taskInfo->event_type = INT_SWITCH_CLOSE; 132 taskInfo->event_type = INT_SWITCH_CLOSE;
154 } 133 }
155 134
@@ -163,20 +142,17 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
163{ 142{
164 struct controller *ctrl = (struct controller *) inst_id; 143 struct controller *ctrl = (struct controller *) inst_id;
165 struct slot *p_slot; 144 struct slot *p_slot;
166 u8 rc = 0; 145 u8 presence_save, rc = 0;
167 struct pci_func *func;
168 struct event_info *taskInfo; 146 struct event_info *taskInfo;
169 147
170 /* Presence Change */ 148 /* Presence Change */
171 dbg("pciehp: Presence/Notify input change.\n"); 149 dbg("pciehp: Presence/Notify input change.\n");
172 150
173 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
174
175 /* This is the structure that tells the worker thread 151 /* This is the structure that tells the worker thread
176 * what to do 152 * what to do
177 */ 153 */
178 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 154 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
179 ctrl->next_event = (ctrl->next_event + 1) % 10; 155 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
180 taskInfo->hp_slot = hp_slot; 156 taskInfo->hp_slot = hp_slot;
181 157
182 rc++; 158 rc++;
@@ -185,8 +161,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
185 /* Switch is open, assume a presence change 161 /* Switch is open, assume a presence change
186 * Save the presence state 162 * Save the presence state
187 */ 163 */
188 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); 164 p_slot->hpc_ops->get_adapter_status(p_slot, &presence_save);
189 if (func->presence_save) { 165 if (presence_save) {
190 /* 166 /*
191 * Card Present 167 * Card Present
192 */ 168 */
@@ -211,19 +187,16 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
211 struct controller *ctrl = (struct controller *) inst_id; 187 struct controller *ctrl = (struct controller *) inst_id;
212 struct slot *p_slot; 188 struct slot *p_slot;
213 u8 rc = 0; 189 u8 rc = 0;
214 struct pci_func *func;
215 struct event_info *taskInfo; 190 struct event_info *taskInfo;
216 191
217 /* power fault */ 192 /* power fault */
218 dbg("pciehp: Power fault interrupt received.\n"); 193 dbg("pciehp: Power fault interrupt received.\n");
219 194
220 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
221
222 /* this is the structure that tells the worker thread 195 /* this is the structure that tells the worker thread
223 * what to do 196 * what to do
224 */ 197 */
225 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 198 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
226 ctrl->next_event = (ctrl->next_event + 1) % 10; 199 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
227 taskInfo->hp_slot = hp_slot; 200 taskInfo->hp_slot = hp_slot;
228 201
229 rc++; 202 rc++;
@@ -234,7 +207,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
234 * power fault Cleared 207 * power fault Cleared
235 */ 208 */
236 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); 209 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
237 func->status = 0x00; 210 p_slot->status = 0x00;
238 taskInfo->event_type = INT_POWER_FAULT_CLEAR; 211 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
239 } else { 212 } else {
240 /* 213 /*
@@ -243,7 +216,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
243 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); 216 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
244 taskInfo->event_type = INT_POWER_FAULT; 217 taskInfo->event_type = INT_POWER_FAULT;
245 /* set power fault status for this board */ 218 /* set power fault status for this board */
246 func->status = 0xFF; 219 p_slot->status = 0xFF;
247 info("power fault bit %x set\n", hp_slot); 220 info("power fault bit %x set\n", hp_slot);
248 } 221 }
249 if (rc) 222 if (rc)
@@ -252,810 +225,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
252 return rc; 225 return rc;
253} 226}
254 227
255
256/**
257 * sort_by_size: sort nodes by their length, smallest first.
258 *
259 * @head: list to sort
260 */
261static int sort_by_size(struct pci_resource **head)
262{
263 struct pci_resource *current_res;
264 struct pci_resource *next_res;
265 int out_of_order = 1;
266
267 if (!(*head))
268 return 1;
269
270 if (!((*head)->next))
271 return 0;
272
273 while (out_of_order) {
274 out_of_order = 0;
275
276 /* Special case for swapping list head */
277 if (((*head)->next) &&
278 ((*head)->length > (*head)->next->length)) {
279 out_of_order++;
280 current_res = *head;
281 *head = (*head)->next;
282 current_res->next = (*head)->next;
283 (*head)->next = current_res;
284 }
285
286 current_res = *head;
287
288 while (current_res->next && current_res->next->next) {
289 if (current_res->next->length > current_res->next->next->length) {
290 out_of_order++;
291 next_res = current_res->next;
292 current_res->next = current_res->next->next;
293 current_res = current_res->next;
294 next_res->next = current_res->next;
295 current_res->next = next_res;
296 } else
297 current_res = current_res->next;
298 }
299 } /* End of out_of_order loop */
300
301 return 0;
302}
303
304
305/*
306 * sort_by_max_size
307 *
308 * Sorts nodes on the list by their length.
309 * Largest first.
310 *
311 */
312static int sort_by_max_size(struct pci_resource **head)
313{
314 struct pci_resource *current_res;
315 struct pci_resource *next_res;
316 int out_of_order = 1;
317
318 if (!(*head))
319 return 1;
320
321 if (!((*head)->next))
322 return 0;
323
324 while (out_of_order) {
325 out_of_order = 0;
326
327 /* Special case for swapping list head */
328 if (((*head)->next) &&
329 ((*head)->length < (*head)->next->length)) {
330 out_of_order++;
331 current_res = *head;
332 *head = (*head)->next;
333 current_res->next = (*head)->next;
334 (*head)->next = current_res;
335 }
336
337 current_res = *head;
338
339 while (current_res->next && current_res->next->next) {
340 if (current_res->next->length < current_res->next->next->length) {
341 out_of_order++;
342 next_res = current_res->next;
343 current_res->next = current_res->next->next;
344 current_res = current_res->next;
345 next_res->next = current_res->next;
346 current_res->next = next_res;
347 } else
348 current_res = current_res->next;
349 }
350 } /* End of out_of_order loop */
351
352 return 0;
353}
354
355
356/**
357 * do_pre_bridge_resource_split: return one unused resource node
358 * @head: list to scan
359 *
360 */
361static struct pci_resource *
362do_pre_bridge_resource_split(struct pci_resource **head,
363 struct pci_resource **orig_head, u32 alignment)
364{
365 struct pci_resource *prevnode = NULL;
366 struct pci_resource *node;
367 struct pci_resource *split_node;
368 u32 rc;
369 u32 temp_dword;
370 dbg("do_pre_bridge_resource_split\n");
371
372 if (!(*head) || !(*orig_head))
373 return NULL;
374
375 rc = pciehp_resource_sort_and_combine(head);
376
377 if (rc)
378 return NULL;
379
380 if ((*head)->base != (*orig_head)->base)
381 return NULL;
382
383 if ((*head)->length == (*orig_head)->length)
384 return NULL;
385
386
387 /* If we got here, there the bridge requires some of the resource, but
388 * we may be able to split some off of the front
389 */
390 node = *head;
391
392 if (node->length & (alignment -1)) {
393 /* this one isn't an aligned length, so we'll make a new entry
394 * and split it up.
395 */
396 split_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
397
398 if (!split_node)
399 return NULL;
400
401 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
402
403 split_node->base = node->base;
404 split_node->length = temp_dword;
405
406 node->length -= temp_dword;
407 node->base += split_node->length;
408
409 /* Put it in the list */
410 *head = split_node;
411 split_node->next = node;
412 }
413
414 if (node->length < alignment)
415 return NULL;
416
417 /* Now unlink it */
418 if (*head == node) {
419 *head = node->next;
420 } else {
421 prevnode = *head;
422 while (prevnode->next != node)
423 prevnode = prevnode->next;
424
425 prevnode->next = node->next;
426 }
427 node->next = NULL;
428
429 return node;
430}
431
432
433/**
434 * do_bridge_resource_split: return one unused resource node
435 * @head: list to scan
436 *
437 */
438static struct pci_resource *
439do_bridge_resource_split(struct pci_resource **head, u32 alignment)
440{
441 struct pci_resource *prevnode = NULL;
442 struct pci_resource *node;
443 u32 rc;
444 u32 temp_dword;
445
446 if (!(*head))
447 return NULL;
448
449 rc = pciehp_resource_sort_and_combine(head);
450
451 if (rc)
452 return NULL;
453
454 node = *head;
455
456 while (node->next) {
457 prevnode = node;
458 node = node->next;
459 kfree(prevnode);
460 }
461
462 if (node->length < alignment) {
463 kfree(node);
464 return NULL;
465 }
466
467 if (node->base & (alignment - 1)) {
468 /* Short circuit if adjusted size is too small */
469 temp_dword = (node->base | (alignment-1)) + 1;
470 if ((node->length - (temp_dword - node->base)) < alignment) {
471 kfree(node);
472 return NULL;
473 }
474
475 node->length -= (temp_dword - node->base);
476 node->base = temp_dword;
477 }
478
479 if (node->length & (alignment - 1)) {
480 /* There's stuff in use after this node */
481 kfree(node);
482 return NULL;
483 }
484
485 return node;
486}
487
488
489/*
490 * get_io_resource
491 *
492 * this function sorts the resource list by size and then
493 * returns the first node of "size" length that is not in the
494 * ISA aliasing window. If it finds a node larger than "size"
495 * it will split it up.
496 *
497 * size must be a power of two.
498 */
499static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
500{
501 struct pci_resource *prevnode;
502 struct pci_resource *node;
503 struct pci_resource *split_node = NULL;
504 u32 temp_dword;
505
506 if (!(*head))
507 return NULL;
508
509 if ( pciehp_resource_sort_and_combine(head) )
510 return NULL;
511
512 if ( sort_by_size(head) )
513 return NULL;
514
515 for (node = *head; node; node = node->next) {
516 if (node->length < size)
517 continue;
518
519 if (node->base & (size - 1)) {
520 /* this one isn't base aligned properly
521 so we'll make a new entry and split it up */
522 temp_dword = (node->base | (size-1)) + 1;
523
524 /*/ Short circuit if adjusted size is too small */
525 if ((node->length - (temp_dword - node->base)) < size)
526 continue;
527
528 split_node = kmalloc(sizeof(struct pci_resource),
529 GFP_KERNEL);
530
531 if (!split_node)
532 return NULL;
533
534 split_node->base = node->base;
535 split_node->length = temp_dword - node->base;
536 node->base = temp_dword;
537 node->length -= split_node->length;
538
539 /* Put it in the list */
540 split_node->next = node->next;
541 node->next = split_node;
542 } /* End of non-aligned base */
543
544 /* Don't need to check if too small since we already did */
545 if (node->length > size) {
546 /* this one is longer than we need
547 so we'll make a new entry and split it up */
548 split_node = kmalloc(sizeof(struct pci_resource),
549 GFP_KERNEL);
550
551 if (!split_node)
552 return NULL;
553
554 split_node->base = node->base + size;
555 split_node->length = node->length - size;
556 node->length = size;
557
558 /* Put it in the list */
559 split_node->next = node->next;
560 node->next = split_node;
561 } /* End of too big on top end */
562
563 /* For IO make sure it's not in the ISA aliasing space */
564 if (node->base & 0x300L)
565 continue;
566
567 /* If we got here, then it is the right size
568 Now take it out of the list */
569 if (*head == node) {
570 *head = node->next;
571 } else {
572 prevnode = *head;
573 while (prevnode->next != node)
574 prevnode = prevnode->next;
575
576 prevnode->next = node->next;
577 }
578 node->next = NULL;
579 /* Stop looping */
580 break;
581 }
582
583 return node;
584}
585
586
587/*
588 * get_max_resource
589 *
590 * Gets the largest node that is at least "size" big from the
591 * list pointed to by head. It aligns the node on top and bottom
592 * to "size" alignment before returning it.
593 * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
594 * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
595 */
596static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
597{
598 struct pci_resource *max;
599 struct pci_resource *temp;
600 struct pci_resource *split_node;
601 u32 temp_dword;
602 u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
603 int i;
604
605 if (!(*head))
606 return NULL;
607
608 if (pciehp_resource_sort_and_combine(head))
609 return NULL;
610
611 if (sort_by_max_size(head))
612 return NULL;
613
614 for (max = *head;max; max = max->next) {
615
616 /* If not big enough we could probably just bail,
617 instead we'll continue to the next. */
618 if (max->length < size)
619 continue;
620
621 if (max->base & (size - 1)) {
622 /* this one isn't base aligned properly
623 so we'll make a new entry and split it up */
624 temp_dword = (max->base | (size-1)) + 1;
625
626 /* Short circuit if adjusted size is too small */
627 if ((max->length - (temp_dword - max->base)) < size)
628 continue;
629
630 split_node = kmalloc(sizeof(struct pci_resource),
631 GFP_KERNEL);
632
633 if (!split_node)
634 return NULL;
635
636 split_node->base = max->base;
637 split_node->length = temp_dword - max->base;
638 max->base = temp_dword;
639 max->length -= split_node->length;
640
641 /* Put it next in the list */
642 split_node->next = max->next;
643 max->next = split_node;
644 }
645
646 if ((max->base + max->length) & (size - 1)) {
647 /* this one isn't end aligned properly at the top
648 so we'll make a new entry and split it up */
649 split_node = kmalloc(sizeof(struct pci_resource),
650 GFP_KERNEL);
651
652 if (!split_node)
653 return NULL;
654 temp_dword = ((max->base + max->length) & ~(size - 1));
655 split_node->base = temp_dword;
656 split_node->length = max->length + max->base
657 - split_node->base;
658 max->length -= split_node->length;
659
660 /* Put it in the list */
661 split_node->next = max->next;
662 max->next = split_node;
663 }
664
665 /* Make sure it didn't shrink too much when we aligned it */
666 if (max->length < size)
667 continue;
668
669 for ( i = 0; max_size[i] > size; i++) {
670 if (max->length > max_size[i]) {
671 split_node = kmalloc(sizeof(struct pci_resource),
672 GFP_KERNEL);
673 if (!split_node)
674 break; /* return NULL; */
675 split_node->base = max->base + max_size[i];
676 split_node->length = max->length - max_size[i];
677 max->length = max_size[i];
678 /* Put it next in the list */
679 split_node->next = max->next;
680 max->next = split_node;
681 break;
682 }
683 }
684
685 /* Now take it out of the list */
686 temp = (struct pci_resource*) *head;
687 if (temp == max) {
688 *head = max->next;
689 } else {
690 while (temp && temp->next != max) {
691 temp = temp->next;
692 }
693
694 temp->next = max->next;
695 }
696
697 max->next = NULL;
698 return max;
699 }
700
701 /* If we get here, we couldn't find one */
702 return NULL;
703}
704
705
706/*
707 * get_resource
708 *
709 * this function sorts the resource list by size and then
710 * returns the first node of "size" length. If it finds a node
711 * larger than "size" it will split it up.
712 *
713 * size must be a power of two.
714 */
715static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
716{
717 struct pci_resource *prevnode;
718 struct pci_resource *node;
719 struct pci_resource *split_node;
720 u32 temp_dword;
721
722 if (!(*head))
723 return NULL;
724
725 if ( pciehp_resource_sort_and_combine(head) )
726 return NULL;
727
728 if ( sort_by_size(head) )
729 return NULL;
730
731 for (node = *head; node; node = node->next) {
732 dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
733 __FUNCTION__, size, node, node->base, node->length);
734 if (node->length < size)
735 continue;
736
737 if (node->base & (size - 1)) {
738 dbg("%s: not aligned\n", __FUNCTION__);
739 /* this one isn't base aligned properly
740 so we'll make a new entry and split it up */
741 temp_dword = (node->base | (size-1)) + 1;
742
743 /* Short circuit if adjusted size is too small */
744 if ((node->length - (temp_dword - node->base)) < size)
745 continue;
746
747 split_node = kmalloc(sizeof(struct pci_resource),
748 GFP_KERNEL);
749
750 if (!split_node)
751 return NULL;
752
753 split_node->base = node->base;
754 split_node->length = temp_dword - node->base;
755 node->base = temp_dword;
756 node->length -= split_node->length;
757
758 /* Put it in the list */
759 split_node->next = node->next;
760 node->next = split_node;
761 } /* End of non-aligned base */
762
763 /* Don't need to check if too small since we already did */
764 if (node->length > size) {
765 dbg("%s: too big\n", __FUNCTION__);
766 /* this one is longer than we need
767 so we'll make a new entry and split it up */
768 split_node = kmalloc(sizeof(struct pci_resource),
769 GFP_KERNEL);
770
771 if (!split_node)
772 return NULL;
773
774 split_node->base = node->base + size;
775 split_node->length = node->length - size;
776 node->length = size;
777
778 /* Put it in the list */
779 split_node->next = node->next;
780 node->next = split_node;
781 } /* End of too big on top end */
782
783 dbg("%s: got one!!!\n", __FUNCTION__);
784 /* If we got here, then it is the right size
785 Now take it out of the list */
786 if (*head == node) {
787 *head = node->next;
788 } else {
789 prevnode = *head;
790 while (prevnode->next != node)
791 prevnode = prevnode->next;
792
793 prevnode->next = node->next;
794 }
795 node->next = NULL;
796 /* Stop looping */
797 break;
798 }
799 return node;
800}
801
802
803/*
804 * pciehp_resource_sort_and_combine
805 *
806 * Sorts all of the nodes in the list in ascending order by
807 * their base addresses. Also does garbage collection by
808 * combining adjacent nodes.
809 *
810 * returns 0 if success
811 */
812int pciehp_resource_sort_and_combine(struct pci_resource **head)
813{
814 struct pci_resource *node1;
815 struct pci_resource *node2;
816 int out_of_order = 1;
817
818 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
819
820 if (!(*head))
821 return 1;
822
823 dbg("*head->next = %p\n",(*head)->next);
824
825 if (!(*head)->next)
826 return 0; /* only one item on the list, already sorted! */
827
828 dbg("*head->base = 0x%x\n",(*head)->base);
829 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
830 while (out_of_order) {
831 out_of_order = 0;
832
833 /* Special case for swapping list head */
834 if (((*head)->next) &&
835 ((*head)->base > (*head)->next->base)) {
836 node1 = *head;
837 (*head) = (*head)->next;
838 node1->next = (*head)->next;
839 (*head)->next = node1;
840 out_of_order++;
841 }
842
843 node1 = (*head);
844
845 while (node1->next && node1->next->next) {
846 if (node1->next->base > node1->next->next->base) {
847 out_of_order++;
848 node2 = node1->next;
849 node1->next = node1->next->next;
850 node1 = node1->next;
851 node2->next = node1->next;
852 node1->next = node2;
853 } else
854 node1 = node1->next;
855 }
856 } /* End of out_of_order loop */
857
858 node1 = *head;
859
860 while (node1 && node1->next) {
861 if ((node1->base + node1->length) == node1->next->base) {
862 /* Combine */
863 dbg("8..\n");
864 node1->length += node1->next->length;
865 node2 = node1->next;
866 node1->next = node1->next->next;
867 kfree(node2);
868 } else
869 node1 = node1->next;
870 }
871
872 return 0;
873}
874
875
876/**
877 * pciehp_slot_create - Creates a node and adds it to the proper bus.
878 * @busnumber - bus where new node is to be located
879 *
880 * Returns pointer to the new node or NULL if unsuccessful
881 */
882struct pci_func *pciehp_slot_create(u8 busnumber)
883{
884 struct pci_func *new_slot;
885 struct pci_func *next;
886 dbg("%s: busnumber %x\n", __FUNCTION__, busnumber);
887 new_slot = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
888
889 if (new_slot == NULL)
890 return new_slot;
891
892 memset(new_slot, 0, sizeof(struct pci_func));
893
894 new_slot->next = NULL;
895 new_slot->configured = 1;
896
897 if (pciehp_slot_list[busnumber] == NULL) {
898 pciehp_slot_list[busnumber] = new_slot;
899 } else {
900 next = pciehp_slot_list[busnumber];
901 while (next->next != NULL)
902 next = next->next;
903 next->next = new_slot;
904 }
905 return new_slot;
906}
907
908
909/**
910 * slot_remove - Removes a node from the linked list of slots.
911 * @old_slot: slot to remove
912 *
913 * Returns 0 if successful, !0 otherwise.
914 */
915static int slot_remove(struct pci_func * old_slot)
916{
917 struct pci_func *next;
918
919 if (old_slot == NULL)
920 return 1;
921
922 next = pciehp_slot_list[old_slot->bus];
923
924 if (next == NULL)
925 return 1;
926
927 if (next == old_slot) {
928 pciehp_slot_list[old_slot->bus] = old_slot->next;
929 pciehp_destroy_board_resources(old_slot);
930 kfree(old_slot);
931 return 0;
932 }
933
934 while ((next->next != old_slot) && (next->next != NULL)) {
935 next = next->next;
936 }
937
938 if (next->next == old_slot) {
939 next->next = old_slot->next;
940 pciehp_destroy_board_resources(old_slot);
941 kfree(old_slot);
942 return 0;
943 } else
944 return 2;
945}
946
947
948/**
949 * bridge_slot_remove - Removes a node from the linked list of slots.
950 * @bridge: bridge to remove
951 *
952 * Returns 0 if successful, !0 otherwise.
953 */
954static int bridge_slot_remove(struct pci_func *bridge)
955{
956 u8 subordinateBus, secondaryBus;
957 u8 tempBus;
958 struct pci_func *next;
959
960 if (bridge == NULL)
961 return 1;
962
963 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
964 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
965
966 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
967 next = pciehp_slot_list[tempBus];
968
969 while (!slot_remove(next)) {
970 next = pciehp_slot_list[tempBus];
971 }
972 }
973
974 next = pciehp_slot_list[bridge->bus];
975
976 if (next == NULL) {
977 return 1;
978 }
979
980 if (next == bridge) {
981 pciehp_slot_list[bridge->bus] = bridge->next;
982 kfree(bridge);
983 return 0;
984 }
985
986 while ((next->next != bridge) && (next->next != NULL)) {
987 next = next->next;
988 }
989
990 if (next->next == bridge) {
991 next->next = bridge->next;
992 kfree(bridge);
993 return 0;
994 } else
995 return 2;
996}
997
998
999/**
1000 * pciehp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1001 * @bus: bus to find
1002 * @device: device to find
1003 * @index: is 0 for first function found, 1 for the second...
1004 *
1005 * Returns pointer to the node if successful, %NULL otherwise.
1006 */
1007struct pci_func *pciehp_slot_find(u8 bus, u8 device, u8 index)
1008{
1009 int found = -1;
1010 struct pci_func *func;
1011
1012 func = pciehp_slot_list[bus];
1013 dbg("%s: bus %x device %x index %x\n",
1014 __FUNCTION__, bus, device, index);
1015 if (func != NULL) {
1016 dbg("%s: func-> bus %x device %x function %x pci_dev %p\n",
1017 __FUNCTION__, func->bus, func->device, func->function,
1018 func->pci_dev);
1019 } else
1020 dbg("%s: func == NULL\n", __FUNCTION__);
1021
1022 if ((func == NULL) || ((func->device == device) && (index == 0)))
1023 return func;
1024
1025 if (func->device == device)
1026 found++;
1027
1028 while (func->next != NULL) {
1029 func = func->next;
1030
1031 dbg("%s: In while loop, func-> bus %x device %x function %x pci_dev %p\n",
1032 __FUNCTION__, func->bus, func->device, func->function,
1033 func->pci_dev);
1034 if (func->device == device)
1035 found++;
1036 dbg("%s: while loop, found %d, index %d\n", __FUNCTION__,
1037 found, index);
1038
1039 if ((found == index) || (func->function == index)) {
1040 dbg("%s: Found bus %x dev %x func %x\n", __FUNCTION__,
1041 func->bus, func->device, func->function);
1042 return func;
1043 }
1044 }
1045
1046 return NULL;
1047}
1048
1049static int is_bridge(struct pci_func * func)
1050{
1051 /* Check the header type */
1052 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1053 return 1;
1054 else
1055 return 0;
1056}
1057
1058
1059/* The following routines constitute the bulk of the 228/* The following routines constitute the bulk of the
1060 hotplug controller logic 229 hotplug controller logic
1061 */ 230 */
@@ -1100,20 +269,17 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
1100 * Configures board 269 * Configures board
1101 * 270 *
1102 */ 271 */
1103static u32 board_added(struct pci_func * func, struct controller * ctrl) 272static int board_added(struct slot *p_slot)
1104{ 273{
1105 u8 hp_slot; 274 u8 hp_slot;
1106 int index; 275 int rc = 0;
1107 u32 temp_register = 0xFFFFFFFF; 276 struct controller *ctrl = p_slot->ctrl;
1108 u32 rc = 0;
1109 struct pci_func *new_func = NULL;
1110 struct slot *p_slot;
1111 struct resource_lists res_lists;
1112 277
1113 p_slot = pciehp_find_slot(ctrl, func->device); 278 hp_slot = p_slot->device - ctrl->slot_device_offset;
1114 hp_slot = func->device - ctrl->slot_device_offset;
1115 279
1116 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot); 280 dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
281 __FUNCTION__, p_slot->device,
282 ctrl->slot_device_offset, hp_slot);
1117 283
1118 /* Wait for exclusive access to hardware */ 284 /* Wait for exclusive access to hardware */
1119 down(&ctrl->crit_sect); 285 down(&ctrl->crit_sect);
@@ -1141,9 +307,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
1141 up(&ctrl->crit_sect); 307 up(&ctrl->crit_sect);
1142 308
1143 /* Wait for ~1 second */ 309 /* Wait for ~1 second */
1144 dbg("%s: before long_delay\n", __FUNCTION__);
1145 wait_for_ctrl_irq (ctrl); 310 wait_for_ctrl_irq (ctrl);
1146 dbg("%s: afterlong_delay\n", __FUNCTION__);
1147 311
1148 /* Check link training status */ 312 /* Check link training status */
1149 rc = p_slot->hpc_ops->check_lnk_status(ctrl); 313 rc = p_slot->hpc_ops->check_lnk_status(ctrl);
@@ -1153,98 +317,47 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
1153 return rc; 317 return rc;
1154 } 318 }
1155 319
1156 dbg("%s: func status = %x\n", __FUNCTION__, func->status); 320 dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
1157 321
1158 /* Check for a power fault */ 322 /* Check for a power fault */
1159 if (func->status == 0xFF) { 323 if (p_slot->status == 0xFF) {
1160 /* power fault occurred, but it was benign */ 324 /* power fault occurred, but it was benign */
1161 temp_register = 0xFFFFFFFF;
1162 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1163 rc = POWER_FAILURE; 325 rc = POWER_FAILURE;
1164 func->status = 0; 326 p_slot->status = 0;
1165 } else { 327 goto err_exit;
1166 /* Get vendor/device ID u32 */
1167 rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
1168 PCI_VENDOR_ID, &temp_register);
1169 dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
1170 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1171
1172 if (rc != 0) {
1173 /* Something's wrong here */
1174 temp_register = 0xFFFFFFFF;
1175 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1176 }
1177 /* Preset return code. It will be changed later if things go okay. */
1178 rc = NO_ADAPTER_PRESENT;
1179 } 328 }
1180 329
1181 /* All F's is an empty slot or an invalid board */ 330 rc = pciehp_configure_device(p_slot);
1182 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */ 331 if (rc) {
1183 res_lists.io_head = ctrl->io_head; 332 err("Cannot add device 0x%x:%x\n", p_slot->bus,
1184 res_lists.mem_head = ctrl->mem_head; 333 p_slot->device);
1185 res_lists.p_mem_head = ctrl->p_mem_head; 334 goto err_exit;
1186 res_lists.bus_head = ctrl->bus_head; 335 }
1187 res_lists.irqs = NULL;
1188
1189 rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
1190 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1191
1192 ctrl->io_head = res_lists.io_head;
1193 ctrl->mem_head = res_lists.mem_head;
1194 ctrl->p_mem_head = res_lists.p_mem_head;
1195 ctrl->bus_head = res_lists.bus_head;
1196 336
1197 pciehp_resource_sort_and_combine(&(ctrl->mem_head)); 337 p_slot->status = 0;
1198 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1199 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1200 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1201 338
1202 if (rc) { 339 /*
1203 set_slot_off(ctrl, p_slot); 340 * Some PCI Express root ports require fixup after hot-plug operation.
1204 return rc; 341 */
1205 } 342 if (pcie_mch_quirk)
1206 pciehp_save_slot_config(ctrl, func); 343 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
1207 344 if (PWR_LED(ctrl->ctrlcap)) {
1208 func->status = 0; 345 /* Wait for exclusive access to hardware */
1209 func->switch_save = 0x10; 346 down(&ctrl->crit_sect);
1210 func->is_a_board = 0x01;
1211 347
1212 /* next, we will instantiate the linux pci_dev structures 348 p_slot->hpc_ops->green_led_on(p_slot);
1213 * (with appropriate driver notification, if already present)
1214 */
1215 index = 0;
1216 do {
1217 new_func = pciehp_slot_find(ctrl->slot_bus, func->device, index++);
1218 if (new_func && !new_func->pci_dev) {
1219 dbg("%s:call pci_hp_configure_dev, func %x\n",
1220 __FUNCTION__, index);
1221 pciehp_configure_device(ctrl, new_func);
1222 }
1223 } while (new_func);
1224
1225 /*
1226 * Some PCI Express root ports require fixup after hot-plug operation.
1227 */
1228 if (pcie_mch_quirk)
1229 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
1230
1231 if (PWR_LED(ctrl->ctrlcap)) {
1232 /* Wait for exclusive access to hardware */
1233 down(&ctrl->crit_sect);
1234
1235 p_slot->hpc_ops->green_led_on(p_slot);
1236 349
1237 /* Wait for the command to complete */ 350 /* Wait for the command to complete */
1238 wait_for_ctrl_irq (ctrl); 351 wait_for_ctrl_irq (ctrl);
1239 352
1240 /* Done with exclusive hardware access */ 353 /* Done with exclusive hardware access */
1241 up(&ctrl->crit_sect); 354 up(&ctrl->crit_sect);
1242 } 355 }
1243 } else {
1244 set_slot_off(ctrl, p_slot);
1245 return -1;
1246 }
1247 return 0; 356 return 0;
357
358err_exit:
359 set_slot_off(ctrl, p_slot);
360 return -1;
1248} 361}
1249 362
1250 363
@@ -1252,55 +365,25 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
1252 * remove_board - Turns off slot and LED's 365 * remove_board - Turns off slot and LED's
1253 * 366 *
1254 */ 367 */
1255static u32 remove_board(struct pci_func *func, struct controller *ctrl) 368static int remove_board(struct slot *p_slot)
1256{ 369{
1257 int index;
1258 u8 skip = 0;
1259 u8 device; 370 u8 device;
1260 u8 hp_slot; 371 u8 hp_slot;
1261 u32 rc; 372 int rc;
1262 struct resource_lists res_lists; 373 struct controller *ctrl = p_slot->ctrl;
1263 struct pci_func *temp_func;
1264 struct slot *p_slot;
1265
1266 if (func == NULL)
1267 return 1;
1268 374
1269 if (pciehp_unconfigure_device(func)) 375 if (pciehp_unconfigure_device(p_slot))
1270 return 1; 376 return 1;
1271 377
1272 device = func->device; 378 device = p_slot->device;
1273 379
1274 hp_slot = func->device - ctrl->slot_device_offset; 380 hp_slot = p_slot->device - ctrl->slot_device_offset;
1275 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 381 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1276 382
1277 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); 383 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1278 384
1279 if ((ctrl->add_support) &&
1280 !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
1281 /* Here we check to see if we've saved any of the board's
1282 * resources already. If so, we'll skip the attempt to
1283 * determine what's being used.
1284 */
1285 index = 0;
1286
1287 temp_func = func;
1288
1289 while ((temp_func = pciehp_slot_find(temp_func->bus, temp_func->device, index++))) {
1290 if (temp_func->bus_head || temp_func->mem_head
1291 || temp_func->p_mem_head || temp_func->io_head) {
1292 skip = 1;
1293 break;
1294 }
1295 }
1296
1297 if (!skip)
1298 rc = pciehp_save_used_resources(ctrl, func, DISABLE_CARD);
1299 }
1300 /* Change status to shutdown */ 385 /* Change status to shutdown */
1301 if (func->is_a_board) 386 p_slot->status = 0x01;
1302 func->status = 0x01;
1303 func->configured = 0;
1304 387
1305 /* Wait for exclusive access to hardware */ 388 /* Wait for exclusive access to hardware */
1306 down(&ctrl->crit_sect); 389 down(&ctrl->crit_sect);
@@ -1328,56 +411,6 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
1328 /* Done with exclusive hardware access */ 411 /* Done with exclusive hardware access */
1329 up(&ctrl->crit_sect); 412 up(&ctrl->crit_sect);
1330 413
1331 if (ctrl->add_support) {
1332 while (func) {
1333 res_lists.io_head = ctrl->io_head;
1334 res_lists.mem_head = ctrl->mem_head;
1335 res_lists.p_mem_head = ctrl->p_mem_head;
1336 res_lists.bus_head = ctrl->bus_head;
1337
1338 dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n",
1339 func->bus, func->device, func->function);
1340
1341 pciehp_return_board_resources(func, &res_lists);
1342
1343 ctrl->io_head = res_lists.io_head;
1344 ctrl->mem_head = res_lists.mem_head;
1345 ctrl->p_mem_head = res_lists.p_mem_head;
1346 ctrl->bus_head = res_lists.bus_head;
1347
1348 pciehp_resource_sort_and_combine(&(ctrl->mem_head));
1349 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1350 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1351 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1352
1353 if (is_bridge(func)) {
1354 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1355 ctrl->seg, func->bus, func->device, func->function);
1356 bridge_slot_remove(func);
1357 } else {
1358 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1359 ctrl->seg, func->bus, func->device, func->function);
1360 slot_remove(func);
1361 }
1362
1363 func = pciehp_slot_find(ctrl->slot_bus, device, 0);
1364 }
1365
1366 /* Setup slot structure with entry for empty slot */
1367 func = pciehp_slot_create(ctrl->slot_bus);
1368
1369 if (func == NULL) {
1370 return 1;
1371 }
1372
1373 func->bus = ctrl->slot_bus;
1374 func->device = device;
1375 func->function = 0;
1376 func->configured = 0;
1377 func->switch_save = 0x10;
1378 func->is_a_board = 0;
1379 }
1380
1381 return 0; 414 return 0;
1382} 415}
1383 416
@@ -1411,13 +444,15 @@ static void pciehp_pushbutton_thread(unsigned long slot)
1411 p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 444 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1412 if (getstatus) { 445 if (getstatus) {
1413 p_slot->state = POWEROFF_STATE; 446 p_slot->state = POWEROFF_STATE;
1414 dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 447 dbg("%s: disabling bus:device(%x:%x)\n", __FUNCTION__,
448 p_slot->bus, p_slot->device);
1415 449
1416 pciehp_disable_slot(p_slot); 450 pciehp_disable_slot(p_slot);
1417 p_slot->state = STATIC_STATE; 451 p_slot->state = STATIC_STATE;
1418 } else { 452 } else {
1419 p_slot->state = POWERON_STATE; 453 p_slot->state = POWERON_STATE;
1420 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 454 dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
455 p_slot->bus, p_slot->device);
1421 456
1422 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 457 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1423 /* Wait for exclusive access to hardware */ 458 /* Wait for exclusive access to hardware */
@@ -1459,13 +494,15 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
1459 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 494 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1460 if (!getstatus) { 495 if (!getstatus) {
1461 p_slot->state = POWEROFF_STATE; 496 p_slot->state = POWEROFF_STATE;
1462 dbg("In removing board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 497 dbg("%s: removing bus:device(%x:%x)\n",
498 __FUNCTION__, p_slot->bus, p_slot->device);
1463 499
1464 pciehp_disable_slot(p_slot); 500 pciehp_disable_slot(p_slot);
1465 p_slot->state = STATIC_STATE; 501 p_slot->state = STATIC_STATE;
1466 } else { 502 } else {
1467 p_slot->state = POWERON_STATE; 503 p_slot->state = POWERON_STATE;
1468 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 504 dbg("%s: adding bus:device(%x:%x)\n",
505 __FUNCTION__, p_slot->bus, p_slot->device);
1469 506
1470 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 507 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1471 /* Wait for exclusive access to hardware */ 508 /* Wait for exclusive access to hardware */
@@ -1531,7 +568,6 @@ int pciehp_event_start_thread(void)
1531 err ("Can't start up our event thread\n"); 568 err ("Can't start up our event thread\n");
1532 return -1; 569 return -1;
1533 } 570 }
1534 dbg("Our event thread pid = %d\n", pid);
1535 return 0; 571 return 0;
1536} 572}
1537 573
@@ -1539,9 +575,7 @@ int pciehp_event_start_thread(void)
1539void pciehp_event_stop_thread(void) 575void pciehp_event_stop_thread(void)
1540{ 576{
1541 event_finished = 1; 577 event_finished = 1;
1542 dbg("event_thread finish command given\n");
1543 up(&event_semaphore); 578 up(&event_semaphore);
1544 dbg("wait for event_thread to exit\n");
1545 down(&event_exit); 579 down(&event_exit);
1546} 580}
1547 581
@@ -1573,7 +607,6 @@ static void interrupt_event_handler(struct controller *ctrl)
1573{ 607{
1574 int loop = 0; 608 int loop = 0;
1575 int change = 1; 609 int change = 1;
1576 struct pci_func *func;
1577 u8 hp_slot; 610 u8 hp_slot;
1578 u8 getstatus; 611 u8 getstatus;
1579 struct slot *p_slot; 612 struct slot *p_slot;
@@ -1581,16 +614,12 @@ static void interrupt_event_handler(struct controller *ctrl)
1581 while (change) { 614 while (change) {
1582 change = 0; 615 change = 0;
1583 616
1584 for (loop = 0; loop < 10; loop++) { 617 for (loop = 0; loop < MAX_EVENTS; loop++) {
1585 if (ctrl->event_queue[loop].event_type != 0) { 618 if (ctrl->event_queue[loop].event_type != 0) {
1586 hp_slot = ctrl->event_queue[loop].hp_slot; 619 hp_slot = ctrl->event_queue[loop].hp_slot;
1587 620
1588 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
1589
1590 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 621 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1591 622
1592 dbg("hp_slot %d, func %p, p_slot %p\n", hp_slot, func, p_slot);
1593
1594 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { 623 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
1595 dbg("button cancel\n"); 624 dbg("button cancel\n");
1596 del_timer(&p_slot->task_event); 625 del_timer(&p_slot->task_event);
@@ -1682,7 +711,6 @@ static void interrupt_event_handler(struct controller *ctrl)
1682 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; 711 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
1683 p_slot->task_event.data = (unsigned long) p_slot; 712 p_slot->task_event.data = (unsigned long) p_slot;
1684 713
1685 dbg("add_timer p_slot = %p\n", (void *) p_slot);
1686 add_timer(&p_slot->task_event); 714 add_timer(&p_slot->task_event);
1687 } 715 }
1688 } 716 }
@@ -1737,13 +765,6 @@ int pciehp_enable_slot(struct slot *p_slot)
1737{ 765{
1738 u8 getstatus = 0; 766 u8 getstatus = 0;
1739 int rc; 767 int rc;
1740 struct pci_func *func;
1741
1742 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1743 if (!func) {
1744 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1745 return 1;
1746 }
1747 768
1748 /* Check to see if (latch closed, card present, power off) */ 769 /* Check to see if (latch closed, card present, power off) */
1749 down(&p_slot->ctrl->crit_sect); 770 down(&p_slot->ctrl->crit_sect);
@@ -1773,45 +794,11 @@ int pciehp_enable_slot(struct slot *p_slot)
1773 } 794 }
1774 up(&p_slot->ctrl->crit_sect); 795 up(&p_slot->ctrl->crit_sect);
1775 796
1776 slot_remove(func);
1777
1778 func = pciehp_slot_create(p_slot->bus);
1779 if (func == NULL)
1780 return 1;
1781
1782 func->bus = p_slot->bus;
1783 func->device = p_slot->device;
1784 func->function = 0;
1785 func->configured = 0;
1786 func->is_a_board = 1;
1787
1788 /* We have to save the presence info for these slots */
1789 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1790 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 797 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1791 func->switch_save = !getstatus? 0x10:0;
1792 798
1793 rc = board_added(func, p_slot->ctrl); 799 rc = board_added(p_slot);
1794 if (rc) { 800 if (rc) {
1795 if (is_bridge(func))
1796 bridge_slot_remove(func);
1797 else
1798 slot_remove(func);
1799
1800 /* Setup slot structure with entry for empty slot */
1801 func = pciehp_slot_create(p_slot->bus);
1802 if (func == NULL)
1803 return 1; /* Out of memory */
1804
1805 func->bus = p_slot->bus;
1806 func->device = p_slot->device;
1807 func->function = 0;
1808 func->configured = 0;
1809 func->is_a_board = 1;
1810
1811 /* We have to save the presence info for these slots */
1812 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1813 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 801 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1814 func->switch_save = !getstatus? 0x10:0;
1815 } 802 }
1816 803
1817 if (p_slot) 804 if (p_slot)
@@ -1823,14 +810,8 @@ int pciehp_enable_slot(struct slot *p_slot)
1823 810
1824int pciehp_disable_slot(struct slot *p_slot) 811int pciehp_disable_slot(struct slot *p_slot)
1825{ 812{
1826 u8 class_code, header_type, BCR;
1827 u8 index = 0;
1828 u8 getstatus = 0; 813 u8 getstatus = 0;
1829 u32 rc = 0;
1830 int ret = 0; 814 int ret = 0;
1831 unsigned int devfn;
1832 struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
1833 struct pci_func *func;
1834 815
1835 if (!p_slot->ctrl) 816 if (!p_slot->ctrl)
1836 return 1; 817 return 1;
@@ -1867,838 +848,8 @@ int pciehp_disable_slot(struct slot *p_slot)
1867 848
1868 up(&p_slot->ctrl->crit_sect); 849 up(&p_slot->ctrl->crit_sect);
1869 850
1870 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++); 851 ret = remove_board(p_slot);
1871 852 update_slot_info(p_slot);
1872 /* Make sure there are no video controllers here 853 return ret;
1873 * for all func of p_slot
1874 */
1875 while (func && !rc) {
1876 pci_bus->number = func->bus;
1877 devfn = PCI_DEVFN(func->device, func->function);
1878
1879 /* Check the Class Code */
1880 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
1881 if (rc)
1882 return rc;
1883
1884 if (class_code == PCI_BASE_CLASS_DISPLAY) {
1885 /* Display/Video adapter (not supported) */
1886 rc = REMOVE_NOT_SUPPORTED;
1887 } else {
1888 /* See if it's a bridge */
1889 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
1890 if (rc)
1891 return rc;
1892
1893 /* If it's a bridge, check the VGA Enable bit */
1894 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
1895 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
1896 if (rc)
1897 return rc;
1898
1899 /* If the VGA Enable bit is set, remove isn't supported */
1900 if (BCR & PCI_BRIDGE_CTL_VGA) {
1901 rc = REMOVE_NOT_SUPPORTED;
1902 }
1903 }
1904 }
1905
1906 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
1907 }
1908
1909 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1910 if ((func != NULL) && !rc) {
1911 rc = remove_board(func, p_slot->ctrl);
1912 } else if (!rc)
1913 rc = 1;
1914
1915 if (p_slot)
1916 update_slot_info(p_slot);
1917
1918 return rc;
1919}
1920
1921
1922/**
1923 * configure_new_device - Configures the PCI header information of one board.
1924 *
1925 * @ctrl: pointer to controller structure
1926 * @func: pointer to function structure
1927 * @behind_bridge: 1 if this is a recursive call, 0 if not
1928 * @resources: pointer to set of resource lists
1929 *
1930 * Returns 0 if success
1931 *
1932 */
1933static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
1934 u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
1935{
1936 u8 temp_byte, function, max_functions, stop_it;
1937 int rc;
1938 u32 ID;
1939 struct pci_func *new_slot;
1940 struct pci_bus lpci_bus, *pci_bus;
1941 int index;
1942
1943 new_slot = func;
1944
1945 dbg("%s\n", __FUNCTION__);
1946 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
1947 pci_bus = &lpci_bus;
1948 pci_bus->number = func->bus;
1949
1950 /* Check for Multi-function device */
1951 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
1952 if (rc) {
1953 dbg("%s: rc = %d\n", __FUNCTION__, rc);
1954 return rc;
1955 }
1956
1957 if (temp_byte & 0x80) /* Multi-function device */
1958 max_functions = 8;
1959 else
1960 max_functions = 1;
1961
1962 function = 0;
1963
1964 do {
1965 rc = configure_new_function(ctrl, new_slot, behind_bridge,
1966 resources, bridge_bus, bridge_dev);
1967
1968 if (rc) {
1969 dbg("configure_new_function failed: %d\n", rc);
1970 index = 0;
1971
1972 while (new_slot) {
1973 new_slot = pciehp_slot_find(new_slot->bus,
1974 new_slot->device, index++);
1975
1976 if (new_slot)
1977 pciehp_return_board_resources(new_slot,
1978 resources);
1979 }
1980
1981 return rc;
1982 }
1983
1984 function++;
1985
1986 stop_it = 0;
1987
1988 /* The following loop skips to the next present function
1989 * and creates a board structure
1990 */
1991
1992 while ((function < max_functions) && (!stop_it)) {
1993 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
1994
1995 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
1996 function++;
1997 } else { /* There's something there */
1998 /* Setup slot structure. */
1999 new_slot = pciehp_slot_create(func->bus);
2000
2001 if (new_slot == NULL) {
2002 /* Out of memory */
2003 return 1;
2004 }
2005
2006 new_slot->bus = func->bus;
2007 new_slot->device = func->device;
2008 new_slot->function = function;
2009 new_slot->is_a_board = 1;
2010 new_slot->status = 0;
2011
2012 stop_it++;
2013 }
2014 }
2015
2016 } while (function < max_functions);
2017 dbg("returning from %s\n", __FUNCTION__);
2018
2019 return 0;
2020}
2021
2022/*
2023 * Configuration logic that involves the hotplug data structures and
2024 * their bookkeeping
2025 */
2026
2027/**
2028 * configure_bridge: fill bridge's registers, either configure or disable it.
2029 */
2030static int
2031configure_bridge(struct pci_bus *pci_bus, unsigned int devfn,
2032 struct pci_resource *mem_node,
2033 struct pci_resource **hold_mem_node,
2034 int base_addr, int limit_addr)
2035{
2036 u16 temp_word;
2037 u32 rc;
2038
2039 if (mem_node) {
2040 memcpy(*hold_mem_node, mem_node, sizeof(struct pci_resource));
2041 mem_node->next = NULL;
2042
2043 /* set Mem base and Limit registers */
2044 RES_CHECK(mem_node->base, 16);
2045 temp_word = (u16)(mem_node->base >> 16);
2046 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2047
2048 RES_CHECK(mem_node->base + mem_node->length - 1, 16);
2049 temp_word = (u16)((mem_node->base + mem_node->length - 1) >> 16);
2050 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2051 } else {
2052 temp_word = 0xFFFF;
2053 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2054
2055 temp_word = 0x0000;
2056 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2057
2058 kfree(*hold_mem_node);
2059 *hold_mem_node = NULL;
2060 }
2061 return rc;
2062}
2063
2064static int
2065configure_new_bridge(struct controller *ctrl, struct pci_func *func,
2066 u8 behind_bridge, struct resource_lists *resources,
2067 struct pci_bus *pci_bus)
2068{
2069 int cloop;
2070 u8 temp_byte;
2071 u8 device;
2072 u16 temp_word;
2073 u32 rc;
2074 u32 ID;
2075 unsigned int devfn;
2076 struct pci_resource *mem_node;
2077 struct pci_resource *p_mem_node;
2078 struct pci_resource *io_node;
2079 struct pci_resource *bus_node;
2080 struct pci_resource *hold_mem_node;
2081 struct pci_resource *hold_p_mem_node;
2082 struct pci_resource *hold_IO_node;
2083 struct pci_resource *hold_bus_node;
2084 struct irq_mapping irqs;
2085 struct pci_func *new_slot;
2086 struct resource_lists temp_resources;
2087
2088 devfn = PCI_DEVFN(func->device, func->function);
2089
2090 /* set Primary bus */
2091 dbg("set Primary bus = 0x%x\n", func->bus);
2092 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2093 if (rc)
2094 return rc;
2095
2096 /* find range of busses to use */
2097 bus_node = get_max_resource(&resources->bus_head, 1L);
2098
2099 /* If we don't have any busses to allocate, we can't continue */
2100 if (!bus_node) {
2101 err("Got NO bus resource to use\n");
2102 return -ENOMEM;
2103 }
2104 dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
2105
2106 /* set Secondary bus */
2107 temp_byte = (u8)bus_node->base;
2108 dbg("set Secondary bus = 0x%x\n", temp_byte);
2109 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2110 if (rc)
2111 return rc;
2112
2113 /* set subordinate bus */
2114 temp_byte = (u8)(bus_node->base + bus_node->length - 1);
2115 dbg("set subordinate bus = 0x%x\n", temp_byte);
2116 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2117 if (rc)
2118 return rc;
2119
2120 /* Set HP parameters (Cache Line Size, Latency Timer) */
2121 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2122 if (rc)
2123 return rc;
2124
2125 /* Setup the IO, memory, and prefetchable windows */
2126
2127 io_node = get_max_resource(&(resources->io_head), 0x1000L);
2128 if (io_node) {
2129 dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base,
2130 io_node->length, io_node->next);
2131 }
2132
2133 mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2134 if (mem_node) {
2135 dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base,
2136 mem_node->length, mem_node->next);
2137 }
2138
2139 if (resources->p_mem_head)
2140 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
2141 else {
2142 /*
2143 * In some platform implementation, MEM and PMEM are not
2144 * distinguished, and hence ACPI _CRS has only MEM entries
2145 * for both MEM and PMEM.
2146 */
2147 dbg("using MEM for PMEM\n");
2148 p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2149 }
2150 if (p_mem_node) {
2151 dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
2152 p_mem_node->length, p_mem_node->next);
2153 }
2154
2155 /* set up the IRQ info */
2156 if (!resources->irqs) {
2157 irqs.barber_pole = 0;
2158 irqs.interrupt[0] = 0;
2159 irqs.interrupt[1] = 0;
2160 irqs.interrupt[2] = 0;
2161 irqs.interrupt[3] = 0;
2162 irqs.valid_INT = 0;
2163 } else {
2164 irqs.barber_pole = resources->irqs->barber_pole;
2165 irqs.interrupt[0] = resources->irqs->interrupt[0];
2166 irqs.interrupt[1] = resources->irqs->interrupt[1];
2167 irqs.interrupt[2] = resources->irqs->interrupt[2];
2168 irqs.interrupt[3] = resources->irqs->interrupt[3];
2169 irqs.valid_INT = resources->irqs->valid_INT;
2170 }
2171
2172 /* set up resource lists that are now aligned on top and bottom
2173 * for anything behind the bridge.
2174 */
2175 temp_resources.bus_head = bus_node;
2176 temp_resources.io_head = io_node;
2177 temp_resources.mem_head = mem_node;
2178 temp_resources.p_mem_head = p_mem_node;
2179 temp_resources.irqs = &irqs;
2180
2181 /* Make copies of the nodes we are going to pass down so that
2182 * if there is a problem,we can just use these to free resources
2183 */
2184 hold_bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2185 hold_IO_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2186 hold_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2187 hold_p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2188
2189 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2190 kfree(hold_bus_node);
2191 kfree(hold_IO_node);
2192 kfree(hold_mem_node);
2193 kfree(hold_p_mem_node);
2194
2195 return 1;
2196 }
2197
2198 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2199
2200 bus_node->base += 1;
2201 bus_node->length -= 1;
2202 bus_node->next = NULL;
2203
2204 /* If we have IO resources copy them and fill in the bridge's
2205 * IO range registers
2206 */
2207 if (io_node) {
2208 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2209 io_node->next = NULL;
2210
2211 /* set IO base and Limit registers */
2212 RES_CHECK(io_node->base, 8);
2213 temp_byte = (u8)(io_node->base >> 8);
2214 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2215
2216 RES_CHECK(io_node->base + io_node->length - 1, 8);
2217 temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
2218 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2219 } else {
2220 kfree(hold_IO_node);
2221 hold_IO_node = NULL;
2222 }
2223
2224 /* If we have memory resources copy them and fill in the bridge's
2225 * memory range registers. Otherwise, fill in the range
2226 * registers with values that disable them.
2227 */
2228 rc = configure_bridge(pci_bus, devfn, mem_node, &hold_mem_node,
2229 PCI_MEMORY_BASE, PCI_MEMORY_LIMIT);
2230
2231 /* If we have prefetchable memory resources copy them and
2232 * fill in the bridge's memory range registers. Otherwise,
2233 * fill in the range registers with values that disable them.
2234 */
2235 rc = configure_bridge(pci_bus, devfn, p_mem_node, &hold_p_mem_node,
2236 PCI_PREF_MEMORY_BASE, PCI_PREF_MEMORY_LIMIT);
2237
2238 /* Adjust this to compensate for extra adjustment in first loop */
2239 irqs.barber_pole--;
2240
2241 rc = 0;
2242
2243 /* Here we actually find the devices and configure them */
2244 for (device = 0; (device <= 0x1F) && !rc; device++) {
2245 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2246
2247 ID = 0xFFFFFFFF;
2248 pci_bus->number = hold_bus_node->base;
2249 pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
2250 pci_bus->number = func->bus;
2251
2252 if (ID != 0xFFFFFFFF) { /* device Present */
2253 /* Setup slot structure. */
2254 new_slot = pciehp_slot_create(hold_bus_node->base);
2255
2256 if (new_slot == NULL) {
2257 /* Out of memory */
2258 rc = -ENOMEM;
2259 continue;
2260 }
2261
2262 new_slot->bus = hold_bus_node->base;
2263 new_slot->device = device;
2264 new_slot->function = 0;
2265 new_slot->is_a_board = 1;
2266 new_slot->status = 0;
2267
2268 rc = configure_new_device(ctrl, new_slot, 1,
2269 &temp_resources, func->bus,
2270 func->device);
2271 dbg("configure_new_device rc=0x%x\n",rc);
2272 } /* End of IF (device in slot?) */
2273 } /* End of FOR loop */
2274
2275 if (rc) {
2276 pciehp_destroy_resource_list(&temp_resources);
2277
2278 return_resource(&(resources->bus_head), hold_bus_node);
2279 return_resource(&(resources->io_head), hold_IO_node);
2280 return_resource(&(resources->mem_head), hold_mem_node);
2281 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2282 return(rc);
2283 }
2284
2285 /* save the interrupt routing information */
2286 if (resources->irqs) {
2287 resources->irqs->interrupt[0] = irqs.interrupt[0];
2288 resources->irqs->interrupt[1] = irqs.interrupt[1];
2289 resources->irqs->interrupt[2] = irqs.interrupt[2];
2290 resources->irqs->interrupt[3] = irqs.interrupt[3];
2291 resources->irqs->valid_INT = irqs.valid_INT;
2292 } else if (!behind_bridge) {
2293 /* We need to hook up the interrupts here */
2294 for (cloop = 0; cloop < 4; cloop++) {
2295 if (irqs.valid_INT & (0x01 << cloop)) {
2296 rc = pciehp_set_irq(func->bus, func->device,
2297 0x0A + cloop, irqs.interrupt[cloop]);
2298 if (rc) {
2299 pciehp_destroy_resource_list (&temp_resources);
2300 return_resource(&(resources->bus_head), hold_bus_node);
2301 return_resource(&(resources->io_head), hold_IO_node);
2302 return_resource(&(resources->mem_head), hold_mem_node);
2303 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2304 return rc;
2305 }
2306 }
2307 } /* end of for loop */
2308 }
2309
2310 /* Return unused bus resources
2311 * First use the temporary node to store information for the board
2312 */
2313 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2314 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2315
2316 hold_bus_node->next = func->bus_head;
2317 func->bus_head = hold_bus_node;
2318
2319 temp_byte = (u8)(temp_resources.bus_head->base - 1);
2320
2321 /* set subordinate bus */
2322 dbg("re-set subordinate bus = 0x%x\n", temp_byte);
2323 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2324
2325 if (temp_resources.bus_head->length == 0) {
2326 kfree(temp_resources.bus_head);
2327 temp_resources.bus_head = NULL;
2328 } else {
2329 dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
2330 func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
2331 return_resource(&(resources->bus_head), temp_resources.bus_head);
2332 }
2333 }
2334
2335 /* If we have IO space available and there is some left,
2336 * return the unused portion
2337 */
2338 if (hold_IO_node && temp_resources.io_head) {
2339 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2340 &hold_IO_node, 0x1000);
2341
2342 /* Check if we were able to split something off */
2343 if (io_node) {
2344 hold_IO_node->base = io_node->base + io_node->length;
2345
2346 RES_CHECK(hold_IO_node->base, 8);
2347 temp_byte = (u8)((hold_IO_node->base) >> 8);
2348 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2349
2350 return_resource(&(resources->io_head), io_node);
2351 }
2352
2353 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2354
2355 /* Check if we were able to split something off */
2356 if (io_node) {
2357 /* First use the temporary node to store information for the board */
2358 hold_IO_node->length = io_node->base - hold_IO_node->base;
2359
2360 /* If we used any, add it to the board's list */
2361 if (hold_IO_node->length) {
2362 hold_IO_node->next = func->io_head;
2363 func->io_head = hold_IO_node;
2364
2365 RES_CHECK(io_node->base - 1, 8);
2366 temp_byte = (u8)((io_node->base - 1) >> 8);
2367 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2368
2369 return_resource(&(resources->io_head), io_node);
2370 } else {
2371 /* it doesn't need any IO */
2372 temp_byte = 0x00;
2373 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2374
2375 return_resource(&(resources->io_head), io_node);
2376 kfree(hold_IO_node);
2377 }
2378 } else {
2379 /* it used most of the range */
2380 hold_IO_node->next = func->io_head;
2381 func->io_head = hold_IO_node;
2382 }
2383 } else if (hold_IO_node) {
2384 /* it used the whole range */
2385 hold_IO_node->next = func->io_head;
2386 func->io_head = hold_IO_node;
2387 }
2388
2389 /* If we have memory space available and there is some left,
2390 * return the unused portion
2391 */
2392 if (hold_mem_node && temp_resources.mem_head) {
2393 mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
2394
2395 /* Check if we were able to split something off */
2396 if (mem_node) {
2397 hold_mem_node->base = mem_node->base + mem_node->length;
2398
2399 RES_CHECK(hold_mem_node->base, 16);
2400 temp_word = (u16)((hold_mem_node->base) >> 16);
2401 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2402
2403 return_resource(&(resources->mem_head), mem_node);
2404 }
2405
2406 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
2407
2408 /* Check if we were able to split something off */
2409 if (mem_node) {
2410 /* First use the temporary node to store information for the board */
2411 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2412
2413 if (hold_mem_node->length) {
2414 hold_mem_node->next = func->mem_head;
2415 func->mem_head = hold_mem_node;
2416
2417 /* configure end address */
2418 RES_CHECK(mem_node->base - 1, 16);
2419 temp_word = (u16)((mem_node->base - 1) >> 16);
2420 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2421
2422 /* Return unused resources to the pool */
2423 return_resource(&(resources->mem_head), mem_node);
2424 } else {
2425 /* it doesn't need any Mem */
2426 temp_word = 0x0000;
2427 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2428
2429 return_resource(&(resources->mem_head), mem_node);
2430 kfree(hold_mem_node);
2431 }
2432 } else {
2433 /* it used most of the range */
2434 hold_mem_node->next = func->mem_head;
2435 func->mem_head = hold_mem_node;
2436 }
2437 } else if (hold_mem_node) {
2438 /* it used the whole range */
2439 hold_mem_node->next = func->mem_head;
2440 func->mem_head = hold_mem_node;
2441 }
2442
2443 /* If we have prefetchable memory space available and there is some
2444 * left at the end, return the unused portion
2445 */
2446 if (hold_p_mem_node && temp_resources.p_mem_head) {
2447 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2448 &hold_p_mem_node, 0x100000L);
2449
2450 /* Check if we were able to split something off */
2451 if (p_mem_node) {
2452 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2453
2454 RES_CHECK(hold_p_mem_node->base, 16);
2455 temp_word = (u16)((hold_p_mem_node->base) >> 16);
2456 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2457
2458 return_resource(&(resources->p_mem_head), p_mem_node);
2459 }
2460
2461 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
2462
2463 /* Check if we were able to split something off */
2464 if (p_mem_node) {
2465 /* First use the temporary node to store information for the board */
2466 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2467
2468 /* If we used any, add it to the board's list */
2469 if (hold_p_mem_node->length) {
2470 hold_p_mem_node->next = func->p_mem_head;
2471 func->p_mem_head = hold_p_mem_node;
2472
2473 RES_CHECK(p_mem_node->base - 1, 16);
2474 temp_word = (u16)((p_mem_node->base - 1) >> 16);
2475 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2476
2477 return_resource(&(resources->p_mem_head), p_mem_node);
2478 } else {
2479 /* it doesn't need any PMem */
2480 temp_word = 0x0000;
2481 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2482
2483 return_resource(&(resources->p_mem_head), p_mem_node);
2484 kfree(hold_p_mem_node);
2485 }
2486 } else {
2487 /* it used the most of the range */
2488 hold_p_mem_node->next = func->p_mem_head;
2489 func->p_mem_head = hold_p_mem_node;
2490 }
2491 } else if (hold_p_mem_node) {
2492 /* it used the whole range */
2493 hold_p_mem_node->next = func->p_mem_head;
2494 func->p_mem_head = hold_p_mem_node;
2495 }
2496
2497 /* We should be configuring an IRQ and the bridge's base address
2498 * registers if it needs them. Although we have never seen such
2499 * a device
2500 */
2501
2502 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2503
2504 dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2505
2506 return rc;
2507} 854}
2508 855
2509/**
2510 * configure_new_function - Configures the PCI header information of one device
2511 *
2512 * @ctrl: pointer to controller structure
2513 * @func: pointer to function structure
2514 * @behind_bridge: 1 if this is a recursive call, 0 if not
2515 * @resources: pointer to set of resource lists
2516 *
2517 * Calls itself recursively for bridged devices.
2518 * Returns 0 if success
2519 *
2520 */
2521static int
2522configure_new_function(struct controller *ctrl, struct pci_func *func,
2523 u8 behind_bridge, struct resource_lists *resources,
2524 u8 bridge_bus, u8 bridge_dev)
2525{
2526 int cloop;
2527 u8 temp_byte;
2528 u8 class_code;
2529 u32 rc;
2530 u32 temp_register;
2531 u32 base;
2532 unsigned int devfn;
2533 struct pci_resource *mem_node;
2534 struct pci_resource *io_node;
2535 struct pci_bus lpci_bus, *pci_bus;
2536
2537 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2538 pci_bus = &lpci_bus;
2539 pci_bus->number = func->bus;
2540 devfn = PCI_DEVFN(func->device, func->function);
2541
2542 /* Check for Bridge */
2543 rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2544 if (rc)
2545 return rc;
2546 dbg("%s: bus %x dev %x func %x temp_byte = %x\n", __FUNCTION__,
2547 func->bus, func->device, func->function, temp_byte);
2548
2549 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2550 rc = configure_new_bridge(ctrl, func, behind_bridge, resources,
2551 pci_bus);
2552
2553 if (rc)
2554 return rc;
2555 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2556 /* Standard device */
2557 u64 base64;
2558 rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
2559
2560 if (class_code == PCI_BASE_CLASS_DISPLAY)
2561 return DEVICE_TYPE_NOT_SUPPORTED;
2562
2563 /* Figure out IO and memory needs */
2564 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
2565 temp_register = 0xFFFFFFFF;
2566
2567 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2568 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
2569 dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register,
2570 func->bus, func->device, func->function);
2571
2572 if (!temp_register)
2573 continue;
2574
2575 base64 = 0L;
2576 if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
2577 /* Map IO */
2578
2579 /* set base = amount of IO space */
2580 base = temp_register & 0xFFFFFFFC;
2581 base = ~base + 1;
2582
2583 dbg("NEED IO length(0x%x)\n", base);
2584 io_node = get_io_resource(&(resources->io_head),(ulong)base);
2585
2586 /* allocate the resource to the board */
2587 if (io_node) {
2588 dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
2589 base = (u32)io_node->base;
2590 io_node->next = func->io_head;
2591 func->io_head = io_node;
2592 } else {
2593 err("Got NO IO resource(length=0x%x)\n", base);
2594 return -ENOMEM;
2595 }
2596 } else { /* map MEM */
2597 int prefetchable = 1;
2598 struct pci_resource **res_node = &func->p_mem_head;
2599 char *res_type_str = "PMEM";
2600 u32 temp_register2;
2601
2602 if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
2603 prefetchable = 0;
2604 res_node = &func->mem_head;
2605 res_type_str++;
2606 }
2607
2608 base = temp_register & 0xFFFFFFF0;
2609 base = ~base + 1;
2610
2611 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
2612 case PCI_BASE_ADDRESS_MEM_TYPE_32:
2613 dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
2614
2615 if (prefetchable && resources->p_mem_head)
2616 mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
2617 else {
2618 if (prefetchable)
2619 dbg("using MEM for PMEM\n");
2620 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2621 }
2622
2623 /* allocate the resource to the board */
2624 if (mem_node) {
2625 base = (u32)mem_node->base;
2626 mem_node->next = *res_node;
2627 *res_node = mem_node;
2628 dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
2629 mem_node->length);
2630 } else {
2631 err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
2632 return -ENOMEM;
2633 }
2634 break;
2635 case PCI_BASE_ADDRESS_MEM_TYPE_64:
2636 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
2637 dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
2638 temp_register, base);
2639
2640 if (prefetchable && resources->p_mem_head)
2641 mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
2642 else {
2643 if (prefetchable)
2644 dbg("using MEM for PMEM\n");
2645 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2646 }
2647
2648 /* allocate the resource to the board */
2649 if (mem_node) {
2650 base64 = mem_node->base;
2651 mem_node->next = *res_node;
2652 *res_node = mem_node;
2653 dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
2654 (u32)base64, mem_node->length);
2655 } else {
2656 err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
2657 return -ENOMEM;
2658 }
2659 break;
2660 default:
2661 dbg("reserved BAR type=0x%x\n", temp_register);
2662 break;
2663 }
2664
2665 }
2666
2667 if (base64) {
2668 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2669 cloop += 4;
2670 base64 >>= 32;
2671
2672 if (base64) {
2673 dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
2674 base64 = 0x0L;
2675 }
2676
2677 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2678 } else {
2679 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
2680 }
2681 } /* End of base register loop */
2682
2683 /* disable ROM base Address */
2684 rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
2685
2686 /* Set HP parameters (Cache Line Size, Latency Timer) */
2687 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2688 if (rc)
2689 return rc;
2690
2691 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2692
2693 dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device,
2694 func->function);
2695 } /* End of Not-A-Bridge else */
2696 else {
2697 /* It's some strange type of PCI adapter (Cardbus?) */
2698 return DEVICE_TYPE_NOT_SUPPORTED;
2699 }
2700
2701 func->configured = 1;
2702
2703 return 0;
2704}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a0e27f0e063..4a3cecca012c 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -27,16 +27,10 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <linux/pci.h> 33#include <linux/pci.h>
39#include <asm/system.h>
40#include "../pci.h" 34#include "../pci.h"
41#include "pciehp.h" 35#include "pciehp.h"
42 36
@@ -217,23 +211,6 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct
217#define MRL_STATE 0x0020 211#define MRL_STATE 0x0020
218#define PRSN_STATE 0x0040 212#define PRSN_STATE 0x0040
219 213
220struct php_ctlr_state_s {
221 struct php_ctlr_state_s *pnext;
222 struct pci_dev *pci_dev;
223 unsigned int irq;
224 unsigned long flags; /* spinlock's */
225 u32 slot_device_offset;
226 u32 num_slots;
227 struct timer_list int_poll_timer; /* Added for poll event */
228 php_intr_callback_t attention_button_callback;
229 php_intr_callback_t switch_change_callback;
230 php_intr_callback_t presence_change_callback;
231 php_intr_callback_t power_fault_callback;
232 void *callback_instance_id;
233 struct ctrl_reg *creg; /* Ptr to controller register space */
234};
235
236
237static spinlock_t hpc_event_lock; 214static spinlock_t hpc_event_lock;
238 215
239DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ 216DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
@@ -297,7 +274,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
297 274
298 DBG_ENTER_ROUTINE 275 DBG_ENTER_ROUTINE
299 276
300 dbg("%s : Enter\n", __FUNCTION__);
301 if (!php_ctlr) { 277 if (!php_ctlr) {
302 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 278 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
303 return -1; 279 return -1;
@@ -308,7 +284,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
308 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 284 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
309 return retval; 285 return retval;
310 } 286 }
311 dbg("%s : hp_register_read_word SLOT_STATUS %x\n", __FUNCTION__, slot_status);
312 287
313 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { 288 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
314 /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue 289 /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
@@ -316,14 +291,11 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
316 dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); 291 dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
317 } 292 }
318 293
319 dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
320 retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); 294 retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
321 if (retval) { 295 if (retval) {
322 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 296 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
323 return retval; 297 return retval;
324 } 298 }
325 dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
326 dbg("%s : Exit\n", __FUNCTION__);
327 299
328 DBG_LEAVE_ROUTINE 300 DBG_LEAVE_ROUTINE
329 return retval; 301 return retval;
@@ -509,7 +481,6 @@ static int hpc_query_power_fault(struct slot * slot)
509 u16 slot_status; 481 u16 slot_status;
510 u8 pwr_fault; 482 u8 pwr_fault;
511 int retval = 0; 483 int retval = 0;
512 u8 status;
513 484
514 DBG_ENTER_ROUTINE 485 DBG_ENTER_ROUTINE
515 486
@@ -521,15 +492,13 @@ static int hpc_query_power_fault(struct slot * slot)
521 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); 492 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
522 493
523 if (retval) { 494 if (retval) {
524 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 495 err("%s : Cannot check for power fault\n", __FUNCTION__);
525 return retval; 496 return retval;
526 } 497 }
527 pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); 498 pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
528 status = (pwr_fault != 1) ? 1 : 0;
529 499
530 DBG_LEAVE_ROUTINE 500 DBG_LEAVE_ROUTINE
531 /* Note: Logic 0 => fault */ 501 return pwr_fault;
532 return status;
533} 502}
534 503
535static int hpc_set_attention_status(struct slot *slot, u8 value) 504static int hpc_set_attention_status(struct slot *slot, u8 value)
@@ -539,7 +508,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
539 u16 slot_ctrl; 508 u16 slot_ctrl;
540 int rc = 0; 509 int rc = 0;
541 510
542 dbg("%s: \n", __FUNCTION__); 511 DBG_ENTER_ROUTINE
512
543 if (!php_ctlr) { 513 if (!php_ctlr) {
544 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 514 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
545 return -1; 515 return -1;
@@ -555,7 +525,6 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
555 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 525 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
556 return rc; 526 return rc;
557 } 527 }
558 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
559 528
560 switch (value) { 529 switch (value) {
561 case 0 : /* turn off */ 530 case 0 : /* turn off */
@@ -576,6 +545,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
576 pcie_write_cmd(slot, slot_cmd); 545 pcie_write_cmd(slot, slot_cmd);
577 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 546 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
578 547
548 DBG_LEAVE_ROUTINE
579 return rc; 549 return rc;
580} 550}
581 551
@@ -587,7 +557,8 @@ static void hpc_set_green_led_on(struct slot *slot)
587 u16 slot_ctrl; 557 u16 slot_ctrl;
588 int rc = 0; 558 int rc = 0;
589 559
590 dbg("%s: \n", __FUNCTION__); 560 DBG_ENTER_ROUTINE
561
591 if (!php_ctlr) { 562 if (!php_ctlr) {
592 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 563 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
593 return ; 564 return ;
@@ -604,7 +575,6 @@ static void hpc_set_green_led_on(struct slot *slot)
604 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 575 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
605 return; 576 return;
606 } 577 }
607 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
608 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; 578 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
609 if (!pciehp_poll_mode) 579 if (!pciehp_poll_mode)
610 slot_cmd = slot_cmd | HP_INTR_ENABLE; 580 slot_cmd = slot_cmd | HP_INTR_ENABLE;
@@ -612,6 +582,7 @@ static void hpc_set_green_led_on(struct slot *slot)
612 pcie_write_cmd(slot, slot_cmd); 582 pcie_write_cmd(slot, slot_cmd);
613 583
614 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 584 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
585 DBG_LEAVE_ROUTINE
615 return; 586 return;
616} 587}
617 588
@@ -622,7 +593,8 @@ static void hpc_set_green_led_off(struct slot *slot)
622 u16 slot_ctrl; 593 u16 slot_ctrl;
623 int rc = 0; 594 int rc = 0;
624 595
625 dbg("%s: \n", __FUNCTION__); 596 DBG_ENTER_ROUTINE
597
626 if (!php_ctlr) { 598 if (!php_ctlr) {
627 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 599 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
628 return ; 600 return ;
@@ -639,7 +611,6 @@ static void hpc_set_green_led_off(struct slot *slot)
639 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 611 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
640 return; 612 return;
641 } 613 }
642 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
643 614
644 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300; 615 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
645 616
@@ -648,6 +619,7 @@ static void hpc_set_green_led_off(struct slot *slot)
648 pcie_write_cmd(slot, slot_cmd); 619 pcie_write_cmd(slot, slot_cmd);
649 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 620 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
650 621
622 DBG_LEAVE_ROUTINE
651 return; 623 return;
652} 624}
653 625
@@ -658,7 +630,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
658 u16 slot_ctrl; 630 u16 slot_ctrl;
659 int rc = 0; 631 int rc = 0;
660 632
661 dbg("%s: \n", __FUNCTION__); 633 DBG_ENTER_ROUTINE
634
662 if (!php_ctlr) { 635 if (!php_ctlr) {
663 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 636 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
664 return ; 637 return ;
@@ -675,7 +648,6 @@ static void hpc_set_green_led_blink(struct slot *slot)
675 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 648 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
676 return; 649 return;
677 } 650 }
678 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
679 651
680 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200; 652 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
681 653
@@ -684,6 +656,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
684 pcie_write_cmd(slot, slot_cmd); 656 pcie_write_cmd(slot, slot_cmd);
685 657
686 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 658 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
659 DBG_LEAVE_ROUTINE
687 return; 660 return;
688} 661}
689 662
@@ -780,7 +753,6 @@ static int hpc_power_on_slot(struct slot * slot)
780 int retval = 0; 753 int retval = 0;
781 754
782 DBG_ENTER_ROUTINE 755 DBG_ENTER_ROUTINE
783 dbg("%s: \n", __FUNCTION__);
784 756
785 if (!php_ctlr) { 757 if (!php_ctlr) {
786 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 758 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -799,8 +771,6 @@ static int hpc_power_on_slot(struct slot * slot)
799 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 771 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
800 return retval; 772 return retval;
801 } 773 }
802 dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
803 slot_ctrl);
804 774
805 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; 775 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
806 776
@@ -829,7 +799,6 @@ static int hpc_power_off_slot(struct slot * slot)
829 int retval = 0; 799 int retval = 0;
830 800
831 DBG_ENTER_ROUTINE 801 DBG_ENTER_ROUTINE
832 dbg("%s: \n", __FUNCTION__);
833 802
834 if (!php_ctlr) { 803 if (!php_ctlr) {
835 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 804 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -848,8 +817,6 @@ static int hpc_power_off_slot(struct slot * slot)
848 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 817 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
849 return retval; 818 return retval;
850 } 819 }
851 dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
852 slot_ctrl);
853 820
854 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; 821 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
855 822
@@ -924,7 +891,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
924 return IRQ_NONE; 891 return IRQ_NONE;
925 } 892 }
926 893
927 dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
928 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); 894 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
929 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; 895 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
930 896
@@ -933,7 +899,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
933 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 899 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
934 return IRQ_NONE; 900 return IRQ_NONE;
935 } 901 }
936 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
937 902
938 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 903 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
939 if (rc) { 904 if (rc) {
@@ -949,14 +914,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
949 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 914 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
950 return IRQ_NONE; 915 return IRQ_NONE;
951 } 916 }
952 dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
953 } 917 }
954 918
955 if (intr_loc & CMD_COMPLETED) { 919 if (intr_loc & CMD_COMPLETED) {
956 /* 920 /*
957 * Command Complete Interrupt Pending 921 * Command Complete Interrupt Pending
958 */ 922 */
959 dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);
960 wake_up_interruptible(&ctrl->queue); 923 wake_up_interruptible(&ctrl->queue);
961 } 924 }
962 925
@@ -989,7 +952,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
989 } 952 }
990 953
991 dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); 954 dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
992 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
993 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; 955 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
994 956
995 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); 957 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -997,14 +959,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
997 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 959 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
998 return IRQ_NONE; 960 return IRQ_NONE;
999 } 961 }
1000 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
1001 962
1002 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 963 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1003 if (rc) { 964 if (rc) {
1004 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 965 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1005 return IRQ_NONE; 966 return IRQ_NONE;
1006 } 967 }
1007 dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
1008 968
1009 /* Clear command complete interrupt caused by this write */ 969 /* Clear command complete interrupt caused by this write */
1010 temp_word = 0x1F; 970 temp_word = 0x1F;
@@ -1248,12 +1208,7 @@ static struct hpc_ops pciehp_hpc_ops = {
1248 .check_lnk_status = hpc_check_lnk_status, 1208 .check_lnk_status = hpc_check_lnk_status,
1249}; 1209};
1250 1210
1251int pcie_init(struct controller * ctrl, 1211int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1252 struct pcie_device *dev,
1253 php_intr_callback_t attention_button_callback,
1254 php_intr_callback_t switch_change_callback,
1255 php_intr_callback_t presence_change_callback,
1256 php_intr_callback_t power_fault_callback)
1257{ 1212{
1258 struct php_ctlr_state_s *php_ctlr, *p; 1213 struct php_ctlr_state_s *php_ctlr, *p;
1259 void *instance_id = ctrl; 1214 void *instance_id = ctrl;
@@ -1282,8 +1237,8 @@ int pcie_init(struct controller * ctrl,
1282 pdev = dev->port; 1237 pdev = dev->port;
1283 php_ctlr->pci_dev = pdev; /* save pci_dev in context */ 1238 php_ctlr->pci_dev = pdev; /* save pci_dev in context */
1284 1239
1285 dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__, 1240 dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
1286 pdev->vendor, pdev->device); 1241 __FUNCTION__, pdev->vendor, pdev->device);
1287 1242
1288 saved_cap_base = pcie_cap_base; 1243 saved_cap_base = pcie_cap_base;
1289 1244
@@ -1340,8 +1295,6 @@ int pcie_init(struct controller * ctrl,
1340 first = 0; 1295 first = 0;
1341 } 1296 }
1342 1297
1343 dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
1344 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1345 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) 1298 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1346 if (pci_resource_len(pdev, rc) > 0) 1299 if (pci_resource_len(pdev, rc) > 0)
1347 dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc, 1300 dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
@@ -1359,13 +1312,12 @@ int pcie_init(struct controller * ctrl,
1359 1312
1360 /* find the IRQ */ 1313 /* find the IRQ */
1361 php_ctlr->irq = dev->irq; 1314 php_ctlr->irq = dev->irq;
1362 dbg("HPC interrupt = %d\n", php_ctlr->irq);
1363 1315
1364 /* Save interrupt callback info */ 1316 /* Save interrupt callback info */
1365 php_ctlr->attention_button_callback = attention_button_callback; 1317 php_ctlr->attention_button_callback = pciehp_handle_attention_button;
1366 php_ctlr->switch_change_callback = switch_change_callback; 1318 php_ctlr->switch_change_callback = pciehp_handle_switch_change;
1367 php_ctlr->presence_change_callback = presence_change_callback; 1319 php_ctlr->presence_change_callback = pciehp_handle_presence_change;
1368 php_ctlr->power_fault_callback = power_fault_callback; 1320 php_ctlr->power_fault_callback = pciehp_handle_power_fault;
1369 php_ctlr->callback_instance_id = instance_id; 1321 php_ctlr->callback_instance_id = instance_id;
1370 1322
1371 /* return PCI Controller Info */ 1323 /* return PCI Controller Info */
@@ -1387,15 +1339,12 @@ int pcie_init(struct controller * ctrl,
1387 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 1339 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1388 goto abort_free_ctlr; 1340 goto abort_free_ctlr;
1389 } 1341 }
1390 dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
1391 1342
1392 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 1343 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1393 if (rc) { 1344 if (rc) {
1394 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 1345 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1395 goto abort_free_ctlr; 1346 goto abort_free_ctlr;
1396 } 1347 }
1397 dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
1398 , slot_status);
1399 1348
1400 temp_word = 0x1F; /* Clear all events */ 1349 temp_word = 0x1F; /* Clear all events */
1401 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); 1350 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1403,7 +1352,6 @@ int pcie_init(struct controller * ctrl,
1403 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 1352 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1404 goto abort_free_ctlr; 1353 goto abort_free_ctlr;
1405 } 1354 }
1406 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
1407 1355
1408 if (pciehp_poll_mode) {/* Install interrupt polling code */ 1356 if (pciehp_poll_mode) {/* Install interrupt polling code */
1409 /* Install and start the interrupt polling timer */ 1357 /* Install and start the interrupt polling timer */
@@ -1419,13 +1367,14 @@ int pcie_init(struct controller * ctrl,
1419 } 1367 }
1420 } 1368 }
1421 1369
1370 dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
1371 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1372
1422 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1373 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1423 if (rc) { 1374 if (rc) {
1424 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 1375 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1425 goto abort_free_ctlr; 1376 goto abort_free_ctlr;
1426 } 1377 }
1427 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
1428 dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
1429 1378
1430 intr_enable = intr_enable | PRSN_DETECT_ENABLE; 1379 intr_enable = intr_enable | PRSN_DETECT_ENABLE;
1431 1380
@@ -1445,7 +1394,6 @@ int pcie_init(struct controller * ctrl,
1445 } else { 1394 } else {
1446 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; 1395 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
1447 } 1396 }
1448 dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
1449 1397
1450 /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ 1398 /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
1451 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1399 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -1453,14 +1401,11 @@ int pcie_init(struct controller * ctrl,
1453 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 1401 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1454 goto abort_free_ctlr; 1402 goto abort_free_ctlr;
1455 } 1403 }
1456 dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
1457 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 1404 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1458 if (rc) { 1405 if (rc) {
1459 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 1406 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1460 goto abort_free_ctlr; 1407 goto abort_free_ctlr;
1461 } 1408 }
1462 dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
1463 SLOT_STATUS(ctrl->cap_base), slot_status);
1464 1409
1465 temp_word = 0x1F; /* Clear all events */ 1410 temp_word = 0x1F; /* Clear all events */
1466 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); 1411 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1468,8 +1413,16 @@ int pcie_init(struct controller * ctrl,
1468 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 1413 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1469 goto abort_free_ctlr; 1414 goto abort_free_ctlr;
1470 } 1415 }
1471 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
1472 1416
1417 if (pciehp_force) {
1418 dbg("Bypassing BIOS check for pciehp use on %s\n",
1419 pci_name(ctrl->pci_dev));
1420 } else {
1421 rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
1422 if (rc)
1423 goto abort_free_ctlr;
1424 }
1425
1473 /* Add this HPC instance into the HPC list */ 1426 /* Add this HPC instance into the HPC list */
1474 spin_lock(&list_lock); 1427 spin_lock(&list_lock);
1475 if (php_ctlr_list_head == 0) { 1428 if (php_ctlr_list_head == 0) {
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index ff17d8e07e94..647673a7d224 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -27,801 +27,111 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/proc_fs.h>
37#include <linux/pci.h> 33#include <linux/pci.h>
38#include "../pci.h" 34#include "../pci.h"
39#include "pciehp.h" 35#include "pciehp.h"
40#ifndef CONFIG_IA64
41#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
42#endif
43 36
44 37
45int pciehp_configure_device (struct controller* ctrl, struct pci_func* func) 38int pciehp_configure_device(struct slot *p_slot)
46{ 39{
47 unsigned char bus; 40 struct pci_dev *dev;
48 struct pci_bus *child; 41 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
49 int num; 42 int num, fn;
50 43
51 if (func->pci_dev == NULL) 44 dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
52 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); 45 if (dev) {
53 46 err("Device %s already exists at %x:%x, cannot hot-add\n",
54 /* Still NULL ? Well then scan for it ! */ 47 pci_name(dev), p_slot->bus, p_slot->device);
55 if (func->pci_dev == NULL) { 48 return -EINVAL;
56 dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
57
58 num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
59
60 if (num)
61 pci_bus_add_devices(ctrl->pci_dev->subordinate);
62
63 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
64 if (func->pci_dev == NULL) {
65 dbg("ERROR: pci_dev still null\n");
66 return 0;
67 }
68 } 49 }
69 50
70 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 51 num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
71 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); 52 if (num == 0) {
72 child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); 53 err("No new device found\n");
73 pci_do_scan_bus(child); 54 return -ENODEV;
55 }
74 56
57 for (fn = 0; fn < 8; fn++) {
58 if (!(dev = pci_find_slot(p_slot->bus,
59 PCI_DEVFN(p_slot->device, fn))))
60 continue;
61 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
62 err("Cannot hot-add display device %s\n",
63 pci_name(dev));
64 continue;
65 }
66 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
67 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
68 /* Find an unused bus number for the new bridge */
69 struct pci_bus *child;
70 unsigned char busnr, start = parent->secondary;
71 unsigned char end = parent->subordinate;
72 for (busnr = start; busnr <= end; busnr++) {
73 if (!pci_find_bus(pci_domain_nr(parent),
74 busnr))
75 break;
76 }
77 if (busnr >= end) {
78 err("No free bus for hot-added bridge\n");
79 continue;
80 }
81 child = pci_add_new_bus(parent, dev, busnr);
82 if (!child) {
83 err("Cannot add new bus for %s\n",
84 pci_name(dev));
85 continue;
86 }
87 child->subordinate = pci_do_scan_bus(child);
88 pci_bus_size_bridges(child);
89 }
90 /* TBD: program firmware provided _HPP values */
91 /* program_fw_provided_values(dev); */
75 } 92 }
76 93
94 pci_bus_assign_resources(parent);
95 pci_bus_add_devices(parent);
96 pci_enable_bridges(parent);
77 return 0; 97 return 0;
78} 98}
79 99
80 100int pciehp_unconfigure_device(struct slot *p_slot)
81int pciehp_unconfigure_device(struct pci_func* func)
82{ 101{
83 int rc = 0; 102 int rc = 0;
84 int j; 103 int j;
85 struct pci_bus *pbus; 104 u8 bctl = 0;
86 105
87 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, 106 dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
88 func->device, func->function); 107 p_slot->device);
89 pbus = func->pci_dev->bus;
90 108
91 for (j=0; j<8 ; j++) { 109 for (j=0; j<8 ; j++) {
92 struct pci_dev* temp = pci_find_slot(func->bus, 110 struct pci_dev* temp = pci_find_slot(p_slot->bus,
93 (func->device << 3) | j); 111 (p_slot->device << 3) | j);
94 if (temp) { 112 if (!temp)
95 pci_remove_bus_device(temp); 113 continue;
114 if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
115 err("Cannot remove display device %s\n",
116 pci_name(temp));
117 continue;
96 } 118 }
119 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
120 pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
121 if (bctl & PCI_BRIDGE_CTL_VGA) {
122 err("Cannot remove display device %s\n",
123 pci_name(temp));
124 continue;
125 }
126 }
127 pci_remove_bus_device(temp);
97 } 128 }
98 /* 129 /*
99 * Some PCI Express root ports require fixup after hot-plug operation. 130 * Some PCI Express root ports require fixup after hot-plug operation.
100 */ 131 */
101 if (pcie_mch_quirk) 132 if (pcie_mch_quirk)
102 pci_fixup_device(pci_fixup_final, pbus->self); 133 pci_fixup_device(pci_fixup_final, p_slot->ctrl->pci_dev);
103 134
104 return rc; 135 return rc;
105} 136}
106 137
107/*
108 * pciehp_set_irq
109 *
110 * @bus_num: bus number of PCI device
111 * @dev_num: device number of PCI device
112 * @slot: pointer to u8 where slot number will be returned
113 */
114int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
115{
116#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_IO_APIC)
117 int rc;
118 u16 temp_word;
119 struct pci_dev fakedev;
120 struct pci_bus fakebus;
121
122 fakedev.devfn = dev_num << 3;
123 fakedev.bus = &fakebus;
124 fakebus.number = bus_num;
125 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
126 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
127 rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
128 dbg("%s: rc %d\n", __FUNCTION__, rc);
129 if (!rc)
130 return !rc;
131
132 /* set the Edge Level Control Register (ELCR) */
133 temp_word = inb(0x4d0);
134 temp_word |= inb(0x4d1) << 8;
135
136 temp_word |= 0x01 << irq_num;
137
138 /* This should only be for x86 as it sets the Edge Level Control Register */
139 outb((u8) (temp_word & 0xFF), 0x4d0);
140 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
141#endif
142 return 0;
143}
144
145/* More PCI configuration routines; this time centered around hotplug controller */
146
147
148/*
149 * pciehp_save_config
150 *
151 * Reads configuration for all slots in a PCI bus and saves info.
152 *
153 * Note: For non-hot plug busses, the slot # saved is the device #
154 *
155 * returns 0 if success
156 */
157int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
158{
159 int rc;
160 u8 class_code;
161 u8 header_type;
162 u32 ID;
163 u8 secondary_bus;
164 struct pci_func *new_slot;
165 int sub_bus;
166 int max_functions;
167 int function;
168 u8 DevError;
169 int device = 0;
170 int cloop = 0;
171 int stop_it;
172 int index;
173 int is_hot_plug = num_ctlr_slots || first_device_num;
174 struct pci_bus lpci_bus, *pci_bus;
175 int FirstSupported, LastSupported;
176
177 dbg("%s: Enter\n", __FUNCTION__);
178
179 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
180 pci_bus = &lpci_bus;
181
182 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
183 num_ctlr_slots, first_device_num);
184
185 /* Decide which slots are supported */
186 if (is_hot_plug) {
187 /*********************************
188 * is_hot_plug is the slot mask
189 *********************************/
190 FirstSupported = first_device_num;
191 LastSupported = FirstSupported + num_ctlr_slots - 1;
192 } else {
193 FirstSupported = 0;
194 LastSupported = 0x1F;
195 }
196
197 dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
198 LastSupported);
199
200 /* Save PCI configuration space for all devices in supported slots */
201 dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
202 pci_bus->number = busnumber;
203 dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
204 for (device = FirstSupported; device <= LastSupported; device++) {
205 ID = 0xFFFFFFFF;
206 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
207 PCI_VENDOR_ID, &ID);
208
209 if (ID != 0xFFFFFFFF) { /* device in slot */
210 dbg("%s: ID = %x\n", __FUNCTION__, ID);
211 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
212 0x0B, &class_code);
213 if (rc)
214 return rc;
215
216 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
217 PCI_HEADER_TYPE, &header_type);
218 if (rc)
219 return rc;
220
221 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
222
223 /* If multi-function device, set max_functions to 8 */
224 if (header_type & 0x80)
225 max_functions = 8;
226 else
227 max_functions = 1;
228
229 function = 0;
230
231 do {
232 DevError = 0;
233 dbg("%s: In do loop\n", __FUNCTION__);
234
235 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
236 /* Recurse the subordinate bus
237 * get the subordinate bus number
238 */
239 rc = pci_bus_read_config_byte(pci_bus,
240 PCI_DEVFN(device, function),
241 PCI_SECONDARY_BUS, &secondary_bus);
242 if (rc) {
243 return rc;
244 } else {
245 sub_bus = (int) secondary_bus;
246
247 /* Save secondary bus cfg spc with this recursive call. */
248 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
249 if (rc)
250 return rc;
251 }
252 }
253
254 index = 0;
255 new_slot = pciehp_slot_find(busnumber, device, index++);
256
257 dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
258 __FUNCTION__, new_slot, busnumber, device, index-1);
259
260 while (new_slot && (new_slot->function != (u8) function)) {
261 new_slot = pciehp_slot_find(busnumber, device, index++);
262 dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
263 __FUNCTION__, new_slot, busnumber, device, index-1);
264 }
265 if (!new_slot) {
266 /* Setup slot structure. */
267 new_slot = pciehp_slot_create(busnumber);
268 dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
269 __FUNCTION__, new_slot, busnumber, device, function);
270
271 if (new_slot == NULL)
272 return(1);
273 }
274
275 new_slot->bus = (u8) busnumber;
276 new_slot->device = (u8) device;
277 new_slot->function = (u8) function;
278 new_slot->is_a_board = 1;
279 new_slot->switch_save = 0x10;
280 /* In case of unsupported board */
281 new_slot->status = DevError;
282 new_slot->pci_dev = pci_find_slot(new_slot->bus,
283 (new_slot->device << 3) | new_slot->function);
284 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
285
286 for (cloop = 0; cloop < 0x20; cloop++) {
287 rc = pci_bus_read_config_dword(pci_bus,
288 PCI_DEVFN(device, function),
289 cloop << 2,
290 (u32 *) &(new_slot->config_space [cloop]));
291 /* dbg("new_slot->config_space[%x] = %x\n",
292 cloop, new_slot->config_space[cloop]); */
293 if (rc)
294 return rc;
295 }
296
297 function++;
298
299 stop_it = 0;
300
301 /* this loop skips to the next present function
302 * reading in Class Code and Header type.
303 */
304
305 while ((function < max_functions)&&(!stop_it)) {
306 dbg("%s: In while loop \n", __FUNCTION__);
307 rc = pci_bus_read_config_dword(pci_bus,
308 PCI_DEVFN(device, function),
309 PCI_VENDOR_ID, &ID);
310
311 if (ID == 0xFFFFFFFF) { /* nothing there. */
312 function++;
313 dbg("Nothing there\n");
314 } else { /* Something there */
315 rc = pci_bus_read_config_byte(pci_bus,
316 PCI_DEVFN(device, function),
317 0x0B, &class_code);
318 if (rc)
319 return rc;
320
321 rc = pci_bus_read_config_byte(pci_bus,
322 PCI_DEVFN(device, function),
323 PCI_HEADER_TYPE, &header_type);
324 if (rc)
325 return rc;
326
327 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
328 stop_it++;
329 }
330 }
331
332 } while (function < max_functions);
333 /* End of IF (device in slot?) */
334 } else if (is_hot_plug) {
335 /* Setup slot structure with entry for empty slot */
336 new_slot = pciehp_slot_create(busnumber);
337
338 if (new_slot == NULL) {
339 return(1);
340 }
341 dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
342 new_slot->bus, new_slot->device, new_slot->function);
343
344 new_slot->bus = (u8) busnumber;
345 new_slot->device = (u8) device;
346 new_slot->function = 0;
347 new_slot->is_a_board = 0;
348 new_slot->presence_save = 0;
349 new_slot->switch_save = 0;
350 }
351 } /* End of FOR loop */
352
353 dbg("%s: Exit\n", __FUNCTION__);
354 return(0);
355}
356
357
358/*
359 * pciehp_save_slot_config
360 *
361 * Saves configuration info for all PCI devices in a given slot
362 * including subordinate busses.
363 *
364 * returns 0 if success
365 */
366int pciehp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
367{
368 int rc;
369 u8 class_code;
370 u8 header_type;
371 u32 ID;
372 u8 secondary_bus;
373 int sub_bus;
374 int max_functions;
375 int function;
376 int cloop = 0;
377 int stop_it;
378 struct pci_bus lpci_bus, *pci_bus;
379 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
380 pci_bus = &lpci_bus;
381 pci_bus->number = new_slot->bus;
382
383 ID = 0xFFFFFFFF;
384
385 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
386 PCI_VENDOR_ID, &ID);
387
388 if (ID != 0xFFFFFFFF) { /* device in slot */
389 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
390 0x0B, &class_code);
391
392 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
393 PCI_HEADER_TYPE, &header_type);
394
395 if (header_type & 0x80) /* Multi-function device */
396 max_functions = 8;
397 else
398 max_functions = 1;
399
400 function = 0;
401
402 do {
403 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
404 /* Recurse the subordinate bus */
405 pci_bus_read_config_byte(pci_bus,
406 PCI_DEVFN(new_slot->device, function),
407 PCI_SECONDARY_BUS, &secondary_bus);
408
409 sub_bus = (int) secondary_bus;
410
411 /* Save the config headers for the secondary bus. */
412 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
413
414 if (rc)
415 return rc;
416
417 } /* End of IF */
418
419 new_slot->status = 0;
420
421 for (cloop = 0; cloop < 0x20; cloop++) {
422 pci_bus_read_config_dword(pci_bus,
423 PCI_DEVFN(new_slot->device, function),
424 cloop << 2,
425 (u32 *) &(new_slot->config_space [cloop]));
426 }
427
428 function++;
429
430 stop_it = 0;
431
432 /* this loop skips to the next present function
433 * reading in the Class Code and the Header type.
434 */
435
436 while ((function < max_functions) && (!stop_it)) {
437 pci_bus_read_config_dword(pci_bus,
438 PCI_DEVFN(new_slot->device, function),
439 PCI_VENDOR_ID, &ID);
440
441 if (ID == 0xFFFFFFFF) { /* nothing there. */
442 function++;
443 } else { /* Something there */
444 pci_bus_read_config_byte(pci_bus,
445 PCI_DEVFN(new_slot->device, function),
446 0x0B, &class_code);
447
448 pci_bus_read_config_byte(pci_bus,
449 PCI_DEVFN(new_slot->device, function),
450 PCI_HEADER_TYPE, &header_type);
451
452 stop_it++;
453 }
454 }
455
456 } while (function < max_functions);
457 } /* End of IF (device in slot?) */
458 else {
459 return 2;
460 }
461
462 return 0;
463}
464
465
466/*
467 * pciehp_save_used_resources
468 *
469 * Stores used resource information for existing boards. this is
470 * for boards that were in the system when this driver was loaded.
471 * this function is for hot plug ADD
472 *
473 * returns 0 if success
474 * if disable == 1(DISABLE_CARD),
475 * it loops for all functions of the slot and disables them.
476 * else, it just get resources of the function and return.
477 */
478int pciehp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
479{
480 u8 cloop;
481 u8 header_type;
482 u8 secondary_bus;
483 u8 temp_byte;
484 u16 command;
485 u16 save_command;
486 u16 w_base, w_length;
487 u32 temp_register;
488 u32 save_base;
489 u32 base, length;
490 u64 base64 = 0;
491 int index = 0;
492 unsigned int devfn;
493 struct pci_resource *mem_node = NULL;
494 struct pci_resource *p_mem_node = NULL;
495 struct pci_resource *t_mem_node;
496 struct pci_resource *io_node;
497 struct pci_resource *bus_node;
498 struct pci_bus lpci_bus, *pci_bus;
499 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
500 pci_bus = &lpci_bus;
501
502 if (disable)
503 func = pciehp_slot_find(func->bus, func->device, index++);
504
505 while ((func != NULL) && func->is_a_board) {
506 pci_bus->number = func->bus;
507 devfn = PCI_DEVFN(func->device, func->function);
508
509 /* Save the command register */
510 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
511
512 if (disable) {
513 /* disable card */
514 command = 0x00;
515 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
516 }
517
518 /* Check for Bridge */
519 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
520
521 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
522 dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
523 func->bus, func->device, save_command);
524 if (disable) {
525 /* Clear Bridge Control Register */
526 command = 0x00;
527 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
528 }
529
530 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
531 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
532
533 bus_node = kmalloc(sizeof(struct pci_resource),
534 GFP_KERNEL);
535 if (!bus_node)
536 return -ENOMEM;
537
538 bus_node->base = (ulong)secondary_bus;
539 bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
540
541 bus_node->next = func->bus_head;
542 func->bus_head = bus_node;
543
544 /* Save IO base and Limit registers */
545 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
546 base = temp_byte;
547 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
548 length = temp_byte;
549
550 if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
551 io_node = kmalloc(sizeof(struct pci_resource),
552 GFP_KERNEL);
553 if (!io_node)
554 return -ENOMEM;
555
556 io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
557 io_node->length = (ulong)(length - base + 0x10) << 8;
558
559 io_node->next = func->io_head;
560 func->io_head = io_node;
561 }
562
563 /* Save memory base and Limit registers */
564 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
565 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
566
567 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
568 mem_node = kmalloc(sizeof(struct pci_resource),
569 GFP_KERNEL);
570 if (!mem_node)
571 return -ENOMEM;
572
573 mem_node->base = (ulong)w_base << 16;
574 mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
575
576 mem_node->next = func->mem_head;
577 func->mem_head = mem_node;
578 }
579 /* Save prefetchable memory base and Limit registers */
580 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
581 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
582
583 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
584 p_mem_node = kmalloc(sizeof(struct pci_resource),
585 GFP_KERNEL);
586 if (!p_mem_node)
587 return -ENOMEM;
588
589 p_mem_node->base = (ulong)w_base << 16;
590 p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
591
592 p_mem_node->next = func->p_mem_head;
593 func->p_mem_head = p_mem_node;
594 }
595 } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
596 dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
597 func->bus, func->device, save_command);
598
599 /* Figure out IO and memory base lengths */
600 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
601 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
602
603 temp_register = 0xFFFFFFFF;
604 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
605 pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
606
607 if (!disable)
608 pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
609
610 if (!temp_register)
611 continue;
612
613 base = temp_register;
614
615 if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
616 (!disable || (save_command & PCI_COMMAND_IO))) {
617 /* IO base */
618 /* set temp_register = amount of IO space requested */
619 base = base & 0xFFFFFFFCL;
620 base = (~base) + 1;
621
622 io_node = kmalloc(sizeof (struct pci_resource),
623 GFP_KERNEL);
624 if (!io_node)
625 return -ENOMEM;
626
627 io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
628 io_node->length = (ulong)base;
629 dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
630 io_node->base, io_node->length);
631
632 io_node->next = func->io_head;
633 func->io_head = io_node;
634 } else { /* map Memory */
635 int prefetchable = 1;
636 /* struct pci_resources **res_node; */
637 char *res_type_str = "PMEM";
638 u32 temp_register2;
639
640 t_mem_node = kmalloc(sizeof (struct pci_resource),
641 GFP_KERNEL);
642 if (!t_mem_node)
643 return -ENOMEM;
644
645 if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
646 (!disable || (save_command & PCI_COMMAND_MEMORY))) {
647 prefetchable = 0;
648 mem_node = t_mem_node;
649 res_type_str++;
650 } else
651 p_mem_node = t_mem_node;
652
653 base = base & 0xFFFFFFF0L;
654 base = (~base) + 1;
655
656 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
657 case PCI_BASE_ADDRESS_MEM_TYPE_32:
658 if (prefetchable) {
659 p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
660 p_mem_node->length = (ulong)base;
661 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
662 res_type_str,
663 p_mem_node->base,
664 p_mem_node->length);
665
666 p_mem_node->next = func->p_mem_head;
667 func->p_mem_head = p_mem_node;
668 } else {
669 mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
670 mem_node->length = (ulong)base;
671 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
672 res_type_str,
673 mem_node->base,
674 mem_node->length);
675
676 mem_node->next = func->mem_head;
677 func->mem_head = mem_node;
678 }
679 break;
680 case PCI_BASE_ADDRESS_MEM_TYPE_64:
681 pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
682 base64 = temp_register2;
683 base64 = (base64 << 32) | save_base;
684
685 if (temp_register2) {
686 dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
687 res_type_str, temp_register2, (u32)base64);
688 base64 &= 0x00000000FFFFFFFFL;
689 }
690
691 if (prefetchable) {
692 p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
693 p_mem_node->length = base;
694 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
695 res_type_str,
696 p_mem_node->base,
697 p_mem_node->length);
698
699 p_mem_node->next = func->p_mem_head;
700 func->p_mem_head = p_mem_node;
701 } else {
702 mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
703 mem_node->length = base;
704 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
705 res_type_str,
706 mem_node->base,
707 mem_node->length);
708
709 mem_node->next = func->mem_head;
710 func->mem_head = mem_node;
711 }
712 cloop += 4;
713 break;
714 default:
715 dbg("asur: reserved BAR type=0x%x\n",
716 temp_register);
717 break;
718 }
719 }
720 } /* End of base register loop */
721 } else { /* Some other unknown header type */
722 dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
723 func->bus, func->device);
724 }
725
726 /* find the next device in this slot */
727 if (!disable)
728 break;
729 func = pciehp_slot_find(func->bus, func->device, index++);
730 }
731
732 return 0;
733}
734
735
736/**
737 * kfree_resource_list: release memory of all list members
738 * @res: resource list to free
739 */
740static inline void
741return_resource_list(struct pci_resource **func, struct pci_resource **res)
742{
743 struct pci_resource *node;
744 struct pci_resource *t_node;
745
746 node = *func;
747 *func = NULL;
748 while (node) {
749 t_node = node->next;
750 return_resource(res, node);
751 node = t_node;
752 }
753}
754
755/*
756 * pciehp_return_board_resources
757 *
758 * this routine returns all resources allocated to a board to
759 * the available pool.
760 *
761 * returns 0 if success
762 */
763int pciehp_return_board_resources(struct pci_func * func,
764 struct resource_lists * resources)
765{
766 int rc;
767
768 dbg("%s\n", __FUNCTION__);
769
770 if (!func)
771 return 1;
772
773 return_resource_list(&(func->io_head),&(resources->io_head));
774 return_resource_list(&(func->mem_head),&(resources->mem_head));
775 return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
776 return_resource_list(&(func->bus_head),&(resources->bus_head));
777
778 rc = pciehp_resource_sort_and_combine(&(resources->mem_head));
779 rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
780 rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
781 rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
782
783 return rc;
784}
785
786/**
787 * kfree_resource_list: release memory of all list members
788 * @res: resource list to free
789 */
790static inline void
791kfree_resource_list(struct pci_resource **r)
792{
793 struct pci_resource *res, *tres;
794
795 res = *r;
796 *r = NULL;
797
798 while (res) {
799 tres = res;
800 res = res->next;
801 kfree(tres);
802 }
803}
804
805/**
806 * pciehp_destroy_resource_list: put node back in the resource list
807 * @resources: list to put nodes back
808 */
809void pciehp_destroy_resource_list(struct resource_lists * resources)
810{
811 kfree_resource_list(&(resources->io_head));
812 kfree_resource_list(&(resources->mem_head));
813 kfree_resource_list(&(resources->p_mem_head));
814 kfree_resource_list(&(resources->bus_head));
815}
816
817/**
818 * pciehp_destroy_board_resources: put node back in the resource list
819 * @resources: list to put nodes back
820 */
821void pciehp_destroy_board_resources(struct pci_func * func)
822{
823 kfree_resource_list(&(func->io_head));
824 kfree_resource_list(&(func->mem_head));
825 kfree_resource_list(&(func->p_mem_head));
826 kfree_resource_list(&(func->bus_head));
827}
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
deleted file mode 100644
index 05f20fbc5f50..000000000000
--- a/drivers/pci/hotplug/pciehprm.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * PCIEHPRM : PCIEHP Resource Manager for ACPI/non-ACPI platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_H_
31#define _PCIEHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI
34#include "pciehprm_nonacpi.h"
35#endif
36
37int pciehprm_init(enum php_ctlr_type ct);
38void pciehprm_cleanup(void);
39int pciehprm_print_pirt(void);
40int pciehprm_find_available_resources(struct controller *ctrl);
41int pciehprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
42void pciehprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
43
44#ifdef DEBUG
45#define RES_CHECK(this, bits) \
46 { if (((this) & (bits - 1))) \
47 printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
48#else
49#define RES_CHECK(this, bits)
50#endif
51
52#endif /* _PCIEHPRM_H_ */
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 1406db35b089..ae244e218620 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -24,100 +24,20 @@
24 * 24 *
25 */ 25 */
26 26
27#include <linux/config.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/kernel.h> 28#include <linux/kernel.h>
30#include <linux/types.h> 29#include <linux/types.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
32#include <linux/init.h>
33#include <linux/acpi.h> 31#include <linux/acpi.h>
34#include <linux/efi.h>
35#include <linux/pci-acpi.h> 32#include <linux/pci-acpi.h>
36#include <asm/uaccess.h>
37#include <asm/system.h>
38#ifdef CONFIG_IA64
39#include <asm/iosapic.h>
40#endif
41#include <acpi/acpi.h>
42#include <acpi/acpi_bus.h> 33#include <acpi/acpi_bus.h>
43#include <acpi/actypes.h> 34#include <acpi/actypes.h>
44#include "pciehp.h" 35#include "pciehp.h"
45#include "pciehprm.h"
46
47#define PCI_MAX_BUS 0x100
48#define ACPI_STA_DEVICE_PRESENT 0x01
49 36
50#define METHOD_NAME__SUN "_SUN" 37#define METHOD_NAME__SUN "_SUN"
51#define METHOD_NAME__HPP "_HPP" 38#define METHOD_NAME__HPP "_HPP"
52#define METHOD_NAME_OSHP "OSHP" 39#define METHOD_NAME_OSHP "OSHP"
53 40
54/* Status code for running acpi method to gain native control */
55#define NC_NOT_RUN 0
56#define OSC_NOT_EXIST 1
57#define OSC_RUN_FAILED 2
58#define OSHP_NOT_EXIST 3
59#define OSHP_RUN_FAILED 4
60#define NC_RUN_SUCCESS 5
61
62#define PHP_RES_BUS 0xA0
63#define PHP_RES_IO 0xA1
64#define PHP_RES_MEM 0xA2
65#define PHP_RES_PMEM 0xA3
66
67#define BRIDGE_TYPE_P2P 0x00
68#define BRIDGE_TYPE_HOST 0x01
69
70/* this should go to drivers/acpi/include/ */
71struct acpi__hpp {
72 u8 cache_line_size;
73 u8 latency_timer;
74 u8 enable_serr;
75 u8 enable_perr;
76};
77
78struct acpi_php_slot {
79 struct acpi_php_slot *next;
80 struct acpi_bridge *bridge;
81 acpi_handle handle;
82 int seg;
83 int bus;
84 int dev;
85 int fun;
86 u32 sun;
87 struct pci_resource *mem_head;
88 struct pci_resource *p_mem_head;
89 struct pci_resource *io_head;
90 struct pci_resource *bus_head;
91 void *slot_ops; /* _STA, _EJx, etc */
92 struct slot *slot;
93}; /* per func */
94
95struct acpi_bridge {
96 struct acpi_bridge *parent;
97 struct acpi_bridge *next;
98 struct acpi_bridge *child;
99 acpi_handle handle;
100 int seg;
101 int pbus; /* pdev->bus->number */
102 int pdevice; /* PCI_SLOT(pdev->devfn) */
103 int pfunction; /* PCI_DEVFN(pdev->devfn) */
104 int bus; /* pdev->subordinate->number */
105 struct acpi__hpp *_hpp;
106 struct acpi_php_slot *slots;
107 struct pci_resource *tmem_head; /* total from crs */
108 struct pci_resource *tp_mem_head; /* total from crs */
109 struct pci_resource *tio_head; /* total from crs */
110 struct pci_resource *tbus_head; /* total from crs */
111 struct pci_resource *mem_head; /* available */
112 struct pci_resource *p_mem_head; /* available */
113 struct pci_resource *io_head; /* available */
114 struct pci_resource *bus_head; /* available */
115 int scanned;
116 int type;
117};
118
119static struct acpi_bridge *acpi_bridges_head;
120
121static u8 * acpi_path_name( acpi_handle handle) 41static u8 * acpi_path_name( acpi_handle handle)
122{ 42{
123 acpi_status status; 43 acpi_status status;
@@ -133,85 +53,43 @@ static u8 * acpi_path_name( acpi_handle handle)
133 return path_name; 53 return path_name;
134} 54}
135 55
136static void acpi_get__hpp ( struct acpi_bridge *ab); 56static acpi_status
137static int acpi_run_oshp ( struct acpi_bridge *ab); 57acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
138static int osc_run_status = NC_NOT_RUN;
139static int oshp_run_status = NC_NOT_RUN;
140
141static int acpi_add_slot_to_php_slots(
142 struct acpi_bridge *ab,
143 int bus_num,
144 acpi_handle handle,
145 u32 adr,
146 u32 sun
147 )
148{
149 struct acpi_php_slot *aps;
150 static long samesun = -1;
151
152 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
153 if (!aps) {
154 err ("acpi_pciehprm: alloc for aps fail\n");
155 return -1;
156 }
157 memset(aps, 0, sizeof(struct acpi_php_slot));
158
159 aps->handle = handle;
160 aps->bus = bus_num;
161 aps->dev = (adr >> 16) & 0xffff;
162 aps->fun = adr & 0xffff;
163 aps->sun = sun;
164
165 aps->next = ab->slots; /* cling to the bridge */
166 aps->bridge = ab;
167 ab->slots = aps;
168
169 ab->scanned += 1;
170 if (!ab->_hpp)
171 acpi_get__hpp(ab);
172
173 if (osc_run_status == OSC_NOT_EXIST)
174 oshp_run_status = acpi_run_oshp(ab);
175
176 if (sun != samesun) {
177 info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
178 aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
179 samesun = sun;
180 }
181 return 0;
182}
183
184static void acpi_get__hpp ( struct acpi_bridge *ab)
185{ 58{
186 acpi_status status; 59 acpi_status status;
187 u8 nui[4]; 60 u8 nui[4];
188 struct acpi_buffer ret_buf = { 0, NULL}; 61 struct acpi_buffer ret_buf = { 0, NULL};
189 union acpi_object *ext_obj, *package; 62 union acpi_object *ext_obj, *package;
190 u8 *path_name = acpi_path_name(ab->handle); 63 u8 *path_name = acpi_path_name(handle);
191 int i, len = 0; 64 int i, len = 0;
192 65
193 /* get _hpp */ 66 /* get _hpp */
194 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 67 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
195 switch (status) { 68 switch (status) {
196 case AE_BUFFER_OVERFLOW: 69 case AE_BUFFER_OVERFLOW:
197 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 70 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
198 if (!ret_buf.pointer) { 71 if (!ret_buf.pointer) {
199 err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name); 72 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
200 return; 73 path_name);
74 return AE_NO_MEMORY;
201 } 75 }
202 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 76 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
77 NULL, &ret_buf);
203 if (ACPI_SUCCESS(status)) 78 if (ACPI_SUCCESS(status))
204 break; 79 break;
205 default: 80 default:
206 if (ACPI_FAILURE(status)) { 81 if (ACPI_FAILURE(status)) {
207 err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status); 82 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
208 return; 83 path_name, status);
84 return status;
209 } 85 }
210 } 86 }
211 87
212 ext_obj = (union acpi_object *) ret_buf.pointer; 88 ext_obj = (union acpi_object *) ret_buf.pointer;
213 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 89 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
214 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name); 90 err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
91 path_name);
92 status = AE_ERROR;
215 goto free_and_return; 93 goto free_and_return;
216 } 94 }
217 95
@@ -224,1514 +102,153 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
224 nui[i] = (u8)ext_obj->integer.value; 102 nui[i] = (u8)ext_obj->integer.value;
225 break; 103 break;
226 default: 104 default:
227 err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name); 105 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
106 path_name);
107 status = AE_ERROR;
228 goto free_and_return; 108 goto free_and_return;
229 } 109 }
230 } 110 }
231 111
232 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); 112 hpp->cache_line_size = nui[0];
233 if (!ab->_hpp) { 113 hpp->latency_timer = nui[1];
234 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name); 114 hpp->enable_serr = nui[2];
235 goto free_and_return; 115 hpp->enable_perr = nui[3];
236 }
237 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
238 116
239 ab->_hpp->cache_line_size = nui[0]; 117 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
240 ab->_hpp->latency_timer = nui[1]; 118 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
241 ab->_hpp->enable_serr = nui[2]; 119 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
242 ab->_hpp->enable_perr = nui[3]; 120 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
243
244 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
245 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
246 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
247 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
248 121
249free_and_return: 122free_and_return:
250 kfree(ret_buf.pointer); 123 kfree(ret_buf.pointer);
124 return status;
251} 125}
252 126
253static int acpi_run_oshp ( struct acpi_bridge *ab) 127static acpi_status acpi_run_oshp(acpi_handle handle)
254{ 128{
255 acpi_status status; 129 acpi_status status;
256 u8 *path_name = acpi_path_name(ab->handle); 130 u8 *path_name = acpi_path_name(handle);
257 131
258 /* run OSHP */ 132 /* run OSHP */
259 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL); 133 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
260 if (ACPI_FAILURE(status)) { 134 if (ACPI_FAILURE(status)) {
261 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status); 135 dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
262 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED; 136 status);
263 } else { 137 } else {
264 oshp_run_status = NC_RUN_SUCCESS; 138 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
265 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
266 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
267 }
268 return oshp_run_status;
269}
270
271static acpi_status acpi_evaluate_crs(
272 acpi_handle handle,
273 struct acpi_resource **retbuf
274 )
275{
276 acpi_status status;
277 struct acpi_buffer crsbuf;
278 u8 *path_name = acpi_path_name(handle);
279
280 crsbuf.length = 0;
281 crsbuf.pointer = NULL;
282
283 status = acpi_get_current_resources (handle, &crsbuf);
284
285 switch (status) {
286 case AE_BUFFER_OVERFLOW:
287 break; /* found */
288 case AE_NOT_FOUND:
289 dbg("acpi_pciehprm:%s _CRS not found\n", path_name);
290 return status;
291 default:
292 err ("acpi_pciehprm:%s _CRS fail=0x%x\n", path_name, status);
293 return status;
294 } 139 }
295
296 crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
297 if (!crsbuf.pointer) {
298 err ("acpi_pciehprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
299 return AE_NO_MEMORY;
300 }
301
302 status = acpi_get_current_resources (handle, &crsbuf);
303 if (ACPI_FAILURE(status)) {
304 err("acpi_pciehprm: %s _CRS fail=0x%x.\n", path_name, status);
305 kfree(crsbuf.pointer);
306 return status;
307 }
308
309 *retbuf = crsbuf.pointer;
310
311 return status; 140 return status;
312} 141}
313 142
314static void free_pci_resource ( struct pci_resource *aprh) 143static int is_root_bridge(acpi_handle handle)
315{ 144{
316 struct pci_resource *res, *next; 145 acpi_status status;
146 struct acpi_device_info *info;
147 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
148 int i;
317 149
318 for (res = aprh; res; res = next) { 150 status = acpi_get_object_info(handle, &buffer);
319 next = res->next; 151 if (ACPI_SUCCESS(status)) {
320 kfree(res); 152 info = buffer.pointer;
321 } 153 if ((info->valid & ACPI_VALID_HID) &&
322} 154 !strcmp(PCI_ROOT_HID_STRING,
323 155 info->hardware_id.value)) {
324static void print_pci_resource ( struct pci_resource *aprh) 156 acpi_os_free(buffer.pointer);
325{ 157 return 1;
326 struct pci_resource *res; 158 }
327 159 if (info->valid & ACPI_VALID_CID) {
328 for (res = aprh; res; res = res->next) 160 for (i=0; i < info->compatibility_id.count; i++) {
329 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length); 161 if (!strcmp(PCI_ROOT_HID_STRING,
330} 162 info->compatibility_id.id[i].value)) {
331 163 acpi_os_free(buffer.pointer);
332static void print_slot_resources( struct acpi_php_slot *aps) 164 return 1;
333{ 165 }
334 if (aps->bus_head) { 166 }
335 dbg(" BUS Resources:\n");
336 print_pci_resource (aps->bus_head);
337 }
338
339 if (aps->io_head) {
340 dbg(" IO Resources:\n");
341 print_pci_resource (aps->io_head);
342 }
343
344 if (aps->mem_head) {
345 dbg(" MEM Resources:\n");
346 print_pci_resource (aps->mem_head);
347 }
348
349 if (aps->p_mem_head) {
350 dbg(" PMEM Resources:\n");
351 print_pci_resource (aps->p_mem_head);
352 }
353}
354
355static void print_pci_resources( struct acpi_bridge *ab)
356{
357 if (ab->tbus_head) {
358 dbg(" Total BUS Resources:\n");
359 print_pci_resource (ab->tbus_head);
360 }
361 if (ab->bus_head) {
362 dbg(" BUS Resources:\n");
363 print_pci_resource (ab->bus_head);
364 }
365
366 if (ab->tio_head) {
367 dbg(" Total IO Resources:\n");
368 print_pci_resource (ab->tio_head);
369 }
370 if (ab->io_head) {
371 dbg(" IO Resources:\n");
372 print_pci_resource (ab->io_head);
373 }
374
375 if (ab->tmem_head) {
376 dbg(" Total MEM Resources:\n");
377 print_pci_resource (ab->tmem_head);
378 }
379 if (ab->mem_head) {
380 dbg(" MEM Resources:\n");
381 print_pci_resource (ab->mem_head);
382 }
383
384 if (ab->tp_mem_head) {
385 dbg(" Total PMEM Resources:\n");
386 print_pci_resource (ab->tp_mem_head);
387 }
388 if (ab->p_mem_head) {
389 dbg(" PMEM Resources:\n");
390 print_pci_resource (ab->p_mem_head);
391 }
392 if (ab->_hpp) {
393 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
394 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
395 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
396 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
397 }
398}
399
400static int pciehprm_delete_resource(
401 struct pci_resource **aprh,
402 ulong base,
403 ulong size)
404{
405 struct pci_resource *res;
406 struct pci_resource *prevnode;
407 struct pci_resource *split_node;
408 ulong tbase;
409
410 pciehp_resource_sort_and_combine(aprh);
411
412 for (res = *aprh; res; res = res->next) {
413 if (res->base > base)
414 continue;
415
416 if ((res->base + res->length) < (base + size))
417 continue;
418
419 if (res->base < base) {
420 tbase = base;
421
422 if ((res->length - (tbase - res->base)) < size)
423 continue;
424
425 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
426 if (!split_node)
427 return -ENOMEM;
428
429 split_node->base = res->base;
430 split_node->length = tbase - res->base;
431 res->base = tbase;
432 res->length -= split_node->length;
433
434 split_node->next = res->next;
435 res->next = split_node;
436 }
437
438 if (res->length >= size) {
439 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
440 if (!split_node)
441 return -ENOMEM;
442
443 split_node->base = res->base + size;
444 split_node->length = res->length - size;
445 res->length = size;
446
447 split_node->next = res->next;
448 res->next = split_node;
449 }
450
451 if (*aprh == res) {
452 *aprh = res->next;
453 } else {
454 prevnode = *aprh;
455 while (prevnode->next != res)
456 prevnode = prevnode->next;
457
458 prevnode->next = res->next;
459 }
460 res->next = NULL;
461 kfree(res);
462 break;
463 }
464
465 return 0;
466}
467
468static int pciehprm_delete_resources(
469 struct pci_resource **aprh,
470 struct pci_resource *this
471 )
472{
473 struct pci_resource *res;
474
475 for (res = this; res; res = res->next)
476 pciehprm_delete_resource(aprh, res->base, res->length);
477
478 return 0;
479}
480
481static int pciehprm_add_resource(
482 struct pci_resource **aprh,
483 ulong base,
484 ulong size)
485{
486 struct pci_resource *res;
487
488 for (res = *aprh; res; res = res->next) {
489 if ((res->base + res->length) == base) {
490 res->length += size;
491 size = 0L;
492 break;
493 } 167 }
494 if (res->next == *aprh)
495 break;
496 } 168 }
497
498 if (size) {
499 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
500 if (!res) {
501 err ("acpi_pciehprm: alloc for res fail\n");
502 return -ENOMEM;
503 }
504 memset(res, 0, sizeof (struct pci_resource));
505
506 res->base = base;
507 res->length = size;
508 res->next = *aprh;
509 *aprh = res;
510 }
511
512 return 0; 169 return 0;
513} 170}
514 171
515static int pciehprm_add_resources( 172int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
516 struct pci_resource **aprh,
517 struct pci_resource *this
518 )
519{
520 struct pci_resource *res;
521 int rc = 0;
522
523 for (res = this; res && !rc; res = res->next)
524 rc = pciehprm_add_resource(aprh, res->base, res->length);
525
526 return rc;
527}
528
529static void acpi_parse_io (
530 struct acpi_bridge *ab,
531 union acpi_resource_data *data
532 )
533{ 173{
534 struct acpi_resource_io *dataio; 174 acpi_status status;
535 dataio = (struct acpi_resource_io *) data; 175 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
536 176 struct pci_dev *pdev = dev;
537 dbg("Io Resource\n"); 177 u8 *path_name;
538 dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10); 178 /*
539 dbg(" Range minimum base: %08X\n", dataio->min_base_address); 179 * Per PCI firmware specification, we should run the ACPI _OSC
540 dbg(" Range maximum base: %08X\n", dataio->max_base_address); 180 * method to get control of hotplug hardware before using it.
541 dbg(" Alignment: %08X\n", dataio->alignment); 181 * If an _OSC is missing, we look for an OSHP to do the same thing.
542 dbg(" Range Length: %08X\n", dataio->range_length); 182 * To handle different BIOS behavior, we look for _OSC and OSHP
543} 183 * within the scope of the hotplug controller and its parents, upto
544 184 * the host bridge under which this controller exists.
545static void acpi_parse_fixed_io (
546 struct acpi_bridge *ab,
547 union acpi_resource_data *data
548 )
549{
550 struct acpi_resource_fixed_io *datafio;
551 datafio = (struct acpi_resource_fixed_io *) data;
552
553 dbg("Fixed Io Resource\n");
554 dbg(" Range base address: %08X", datafio->base_address);
555 dbg(" Range length: %08X", datafio->range_length);
556}
557
558static void acpi_parse_address16_32 (
559 struct acpi_bridge *ab,
560 union acpi_resource_data *data,
561 acpi_resource_type id
562 )
563{
564 /*
565 * acpi_resource_address16 == acpi_resource_address32
566 * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
567 */ 185 */
568 struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data; 186 while (!handle) {
569 struct pci_resource **aprh, **tprh; 187 /*
570 188 * This hotplug controller was not listed in the ACPI name
571 if (id == ACPI_RSTYPE_ADDRESS16) 189 * space at all. Try to get acpi handle of parent pci bus.
572 dbg("acpi_pciehprm:16-Bit Address Space Resource\n"); 190 */
573 else 191 if (!pdev || !pdev->bus->parent)
574 dbg("acpi_pciehprm:32-Bit Address Space Resource\n");
575
576 switch (data32->resource_type) {
577 case ACPI_MEMORY_RANGE:
578 dbg(" Resource Type: Memory Range\n");
579 aprh = &ab->mem_head;
580 tprh = &ab->tmem_head;
581
582 switch (data32->attribute.memory.cache_attribute) {
583 case ACPI_NON_CACHEABLE_MEMORY:
584 dbg(" Type Specific: Noncacheable memory\n");
585 break;
586 case ACPI_CACHABLE_MEMORY:
587 dbg(" Type Specific: Cacheable memory\n");
588 break;
589 case ACPI_WRITE_COMBINING_MEMORY:
590 dbg(" Type Specific: Write-combining memory\n");
591 break;
592 case ACPI_PREFETCHABLE_MEMORY:
593 aprh = &ab->p_mem_head;
594 dbg(" Type Specific: Prefetchable memory\n");
595 break;
596 default:
597 dbg(" Type Specific: Invalid cache attribute\n");
598 break; 192 break;
599 } 193 dbg("Could not find %s in acpi namespace, trying parent\n",
600 194 pci_name(pdev));
601 dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only"); 195 if (!pdev->bus->parent->self)
602 break; 196 /* Parent must be a host bridge */
603 197 handle = acpi_get_pci_rootbridge_handle(
604 case ACPI_IO_RANGE: 198 pci_domain_nr(pdev->bus->parent),
605 dbg(" Resource Type: I/O Range\n"); 199 pdev->bus->parent->number);
606 aprh = &ab->io_head; 200 else
607 tprh = &ab->tio_head; 201 handle = DEVICE_ACPI_HANDLE(
608 202 &(pdev->bus->parent->self->dev));
609 switch (data32->attribute.io.range_attribute) { 203 pdev = pdev->bus->parent->self;
610 case ACPI_NON_ISA_ONLY_RANGES: 204 }
611 dbg(" Type Specific: Non-ISA Io Addresses\n"); 205
612 break; 206 while (handle) {
613 case ACPI_ISA_ONLY_RANGES: 207 path_name = acpi_path_name(handle);
614 dbg(" Type Specific: ISA Io Addresses\n"); 208 dbg("Trying to get hotplug control for %s \n", path_name);
615 break; 209 status = pci_osc_control_set(handle,
616 case ACPI_ENTIRE_RANGE: 210 OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
617 dbg(" Type Specific: ISA and non-ISA Io Addresses\n"); 211 if (status == AE_NOT_FOUND)
618 break; 212 status = acpi_run_oshp(handle);
619 default: 213 if (ACPI_SUCCESS(status)) {
620 dbg(" Type Specific: Invalid range attribute\n"); 214 dbg("Gained control for hotplug HW for pci %s (%s)\n",
215 pci_name(dev), path_name);
216 return 0;
217 }
218 if (is_root_bridge(handle))
621 break; 219 break;
622 } 220 chandle = handle;
623 break; 221 status = acpi_get_parent(chandle, &handle);
624
625 case ACPI_BUS_NUMBER_RANGE:
626 dbg(" Resource Type: Bus Number Range(fixed)\n");
627 /* fixup to be compatible with the rest of php driver */
628 data32->min_address_range++;
629 data32->address_length--;
630 aprh = &ab->bus_head;
631 tprh = &ab->tbus_head;
632 break;
633 default:
634 dbg(" Resource Type: Invalid resource type. Exiting.\n");
635 return;
636 }
637
638 dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
639 dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
640 dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
641 dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
642 dbg(" Granularity: %08X\n", data32->granularity);
643 dbg(" Address range min: %08X\n", data32->min_address_range);
644 dbg(" Address range max: %08X\n", data32->max_address_range);
645 dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
646 dbg(" Address Length: %08X\n", data32->address_length);
647
648 if (0xFF != data32->resource_source.index) {
649 dbg(" Resource Source Index: %X\n", data32->resource_source.index);
650 /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
651 }
652
653 pciehprm_add_resource(aprh, data32->min_address_range, data32->address_length);
654}
655
656static acpi_status acpi_parse_crs(
657 struct acpi_bridge *ab,
658 struct acpi_resource *crsbuf
659 )
660{
661 acpi_status status = AE_OK;
662 struct acpi_resource *resource = crsbuf;
663 u8 count = 0;
664 u8 done = 0;
665
666 while (!done) {
667 dbg("acpi_pciehprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
668 switch (resource->id) {
669 case ACPI_RSTYPE_IRQ:
670 dbg("Irq -------- Resource\n");
671 break;
672 case ACPI_RSTYPE_DMA:
673 dbg("DMA -------- Resource\n");
674 break;
675 case ACPI_RSTYPE_START_DPF:
676 dbg("Start DPF -------- Resource\n");
677 break;
678 case ACPI_RSTYPE_END_DPF:
679 dbg("End DPF -------- Resource\n");
680 break;
681 case ACPI_RSTYPE_IO:
682 acpi_parse_io (ab, &resource->data);
683 break;
684 case ACPI_RSTYPE_FIXED_IO:
685 acpi_parse_fixed_io (ab, &resource->data);
686 break;
687 case ACPI_RSTYPE_VENDOR:
688 dbg("Vendor -------- Resource\n");
689 break;
690 case ACPI_RSTYPE_END_TAG:
691 dbg("End_tag -------- Resource\n");
692 done = 1;
693 break;
694 case ACPI_RSTYPE_MEM24:
695 dbg("Mem24 -------- Resource\n");
696 break;
697 case ACPI_RSTYPE_MEM32:
698 dbg("Mem32 -------- Resource\n");
699 break;
700 case ACPI_RSTYPE_FIXED_MEM32:
701 dbg("Fixed Mem32 -------- Resource\n");
702 break;
703 case ACPI_RSTYPE_ADDRESS16:
704 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
705 break;
706 case ACPI_RSTYPE_ADDRESS32:
707 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
708 break;
709 case ACPI_RSTYPE_ADDRESS64:
710 info("Address64 -------- Resource unparsed\n");
711 break;
712 case ACPI_RSTYPE_EXT_IRQ:
713 dbg("Ext Irq -------- Resource\n");
714 break;
715 default:
716 dbg("Invalid -------- resource type 0x%x\n", resource->id);
717 break;
718 }
719
720 resource = (struct acpi_resource *) ((char *)resource + resource->length);
721 }
722
723 return status;
724}
725
726static acpi_status acpi_get_crs( struct acpi_bridge *ab)
727{
728 acpi_status status;
729 struct acpi_resource *crsbuf;
730
731 status = acpi_evaluate_crs(ab->handle, &crsbuf);
732 if (ACPI_SUCCESS(status)) {
733 status = acpi_parse_crs(ab, crsbuf);
734 kfree(crsbuf);
735
736 pciehp_resource_sort_and_combine(&ab->bus_head);
737 pciehp_resource_sort_and_combine(&ab->io_head);
738 pciehp_resource_sort_and_combine(&ab->mem_head);
739 pciehp_resource_sort_and_combine(&ab->p_mem_head);
740
741 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
742 pciehprm_add_resources (&ab->tio_head, ab->io_head);
743 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
744 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
745 }
746
747 return status;
748}
749
750/* find acpi_bridge downword from ab. */
751static struct acpi_bridge *
752find_acpi_bridge_by_bus(
753 struct acpi_bridge *ab,
754 int seg,
755 int bus /* pdev->subordinate->number */
756 )
757{
758 struct acpi_bridge *lab = NULL;
759
760 if (!ab)
761 return NULL;
762
763 if ((ab->bus == bus) && (ab->seg == seg))
764 return ab;
765
766 if (ab->child)
767 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
768
769 if (!lab)
770 if (ab->next)
771 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
772
773 return lab;
774}
775
776/*
777 * Build a device tree of ACPI PCI Bridges
778 */
779static void pciehprm_acpi_register_a_bridge (
780 struct acpi_bridge **head,
781 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
782 struct acpi_bridge *cab /* child bridge to add */
783 )
784{
785 struct acpi_bridge *lpab;
786 struct acpi_bridge *lcab;
787
788 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
789 if (!lpab) {
790 if (!(pab->type & BRIDGE_TYPE_HOST))
791 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
792 pab->next = *head;
793 *head = pab;
794 lpab = pab;
795 }
796
797 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
798 return;
799
800 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
801 if (lcab) {
802 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
803 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
804 return;
805 } else
806 lcab = cab;
807
808 lcab->parent = lpab;
809 lcab->next = lpab->child;
810 lpab->child = lcab;
811}
812
813static acpi_status pciehprm_acpi_build_php_slots_callback(
814 acpi_handle handle,
815 u32 Level,
816 void *context,
817 void **retval
818 )
819{
820 ulong bus_num;
821 ulong seg_num;
822 ulong sun, adr;
823 ulong padr = 0;
824 acpi_handle phandle = NULL;
825 struct acpi_bridge *pab = (struct acpi_bridge *)context;
826 struct acpi_bridge *lab;
827 acpi_status status;
828 u8 *path_name = acpi_path_name(handle);
829
830 /* get _SUN */
831 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
832 switch(status) {
833 case AE_NOT_FOUND:
834 return AE_OK;
835 default:
836 if (ACPI_FAILURE(status)) {
837 err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
838 return status;
839 }
840 }
841
842 /* get _ADR. _ADR must exist if _SUN exists */
843 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
844 if (ACPI_FAILURE(status)) {
845 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
846 return status;
847 }
848
849 dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
850
851 status = acpi_get_parent(handle, &phandle);
852 if (ACPI_FAILURE(status)) {
853 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
854 return (status);
855 }
856
857 bus_num = pab->bus;
858 seg_num = pab->seg;
859
860 if (pab->bus == bus_num) {
861 lab = pab;
862 } else {
863 dbg("WARN: pab is not parent\n");
864 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
865 if (!lab) {
866 dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
867 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
868 if (!lab) {
869 err("acpi_pciehprm: alloc for ab fail\n");
870 return AE_NO_MEMORY;
871 }
872 memset(lab, 0, sizeof(struct acpi_bridge));
873
874 lab->handle = phandle;
875 lab->pbus = pab->bus;
876 lab->pdevice = (int)(padr >> 16) & 0xffff;
877 lab->pfunction = (int)(padr & 0xffff);
878 lab->bus = (int)bus_num;
879 lab->scanned = 0;
880 lab->type = BRIDGE_TYPE_P2P;
881
882 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
883 } else
884 dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
885 }
886
887 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
888
889 return (status);
890}
891
892static int pciehprm_acpi_build_php_slots(
893 struct acpi_bridge *ab,
894 u32 depth
895 )
896{
897 acpi_status status;
898 u8 *path_name = acpi_path_name(ab->handle);
899
900 /* Walk down this pci bridge to get _SUNs if any behind P2P */
901 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
902 ab->handle,
903 depth,
904 pciehprm_acpi_build_php_slots_callback,
905 ab,
906 NULL );
907 if (ACPI_FAILURE(status)) {
908 dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
909 return -1;
910 }
911
912 return 0;
913}
914
915static void build_a_bridge(
916 struct acpi_bridge *pab,
917 struct acpi_bridge *ab
918 )
919{
920 u8 *path_name = acpi_path_name(ab->handle);
921
922 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
923
924 switch (ab->type) {
925 case BRIDGE_TYPE_HOST:
926 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
927 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
928 break;
929 case BRIDGE_TYPE_P2P:
930 dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
931 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
932 break;
933 };
934
935 /* build any immediate PHP slots under this pci bridge */
936 pciehprm_acpi_build_php_slots(ab, 1);
937}
938
939static struct acpi_bridge * add_p2p_bridge(
940 acpi_handle handle,
941 struct acpi_bridge *pab, /* parent */
942 ulong adr
943 )
944{
945 struct acpi_bridge *ab;
946 struct pci_dev *pdev;
947 ulong devnum, funcnum;
948 u8 *path_name = acpi_path_name(handle);
949
950 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
951 if (!ab) {
952 err("acpi_pciehprm: alloc for ab fail\n");
953 return NULL;
954 }
955 memset(ab, 0, sizeof(struct acpi_bridge));
956
957 devnum = (adr >> 16) & 0xffff;
958 funcnum = adr & 0xffff;
959
960 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
961 if (!pdev || !pdev->subordinate) {
962 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
963 kfree(ab);
964 return NULL;
965 }
966
967 ab->handle = handle;
968 ab->seg = pab->seg;
969 ab->pbus = pab->bus; /* or pdev->bus->number */
970 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
971 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
972 ab->bus = pdev->subordinate->number;
973 ab->scanned = 0;
974 ab->type = BRIDGE_TYPE_P2P;
975
976 dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
977 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
978 pab->bus, (u32)devnum, (u32)funcnum, path_name);
979
980 build_a_bridge(pab, ab);
981
982 return ab;
983}
984
985static acpi_status scan_p2p_bridge(
986 acpi_handle handle,
987 u32 Level,
988 void *context,
989 void **retval
990 )
991{
992 struct acpi_bridge *pab = (struct acpi_bridge *)context;
993 struct acpi_bridge *ab;
994 acpi_status status;
995 ulong adr = 0;
996 u8 *path_name = acpi_path_name(handle);
997 ulong devnum, funcnum;
998 struct pci_dev *pdev;
999
1000 /* get device, function */
1001 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1002 if (ACPI_FAILURE(status)) {
1003 if (status != AE_NOT_FOUND)
1004 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1005 return AE_OK;
1006 }
1007
1008 devnum = (adr >> 16) & 0xffff;
1009 funcnum = adr & 0xffff;
1010
1011 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
1012 if (!pdev)
1013 return AE_OK;
1014 if (!pdev->subordinate)
1015 return AE_OK;
1016
1017 ab = add_p2p_bridge(handle, pab, adr);
1018 if (ab) {
1019 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1020 handle,
1021 (u32)1,
1022 scan_p2p_bridge,
1023 ab,
1024 NULL);
1025 if (ACPI_FAILURE(status)) 222 if (ACPI_FAILURE(status))
1026 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status); 223 break;
1027 }
1028
1029 return AE_OK;
1030}
1031
1032static struct acpi_bridge * add_host_bridge(
1033 acpi_handle handle,
1034 ulong segnum,
1035 ulong busnum
1036 )
1037{
1038 ulong adr = 0;
1039 acpi_status status;
1040 struct acpi_bridge *ab;
1041 u8 *path_name = acpi_path_name(handle);
1042
1043 /* get device, function: host br adr is always 0000 though. */
1044 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1045 if (ACPI_FAILURE(status)) {
1046 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1047 return NULL;
1048 }
1049 dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
1050 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
1051
1052 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
1053 if (!ab) {
1054 err("acpi_pciehprm: alloc for ab fail\n");
1055 return NULL;
1056 }
1057 memset(ab, 0, sizeof(struct acpi_bridge));
1058
1059 ab->handle = handle;
1060 ab->seg = (int)segnum;
1061 ab->bus = ab->pbus = (int)busnum;
1062 ab->pdevice = (int)(adr >> 16) & 0xffff;
1063 ab->pfunction = (int)(adr & 0xffff);
1064 ab->scanned = 0;
1065 ab->type = BRIDGE_TYPE_HOST;
1066
1067 /* get root pci bridge's current resources */
1068 status = acpi_get_crs(ab);
1069 if (ACPI_FAILURE(status)) {
1070 err("acpi_pciehprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
1071 kfree(ab);
1072 return NULL;
1073 }
1074
1075 status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
1076 if (ACPI_FAILURE(status)) {
1077 err("%s: status %x\n", __FUNCTION__, status);
1078 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
1079 } else {
1080 osc_run_status = NC_RUN_SUCCESS;
1081 }
1082 dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
1083
1084 build_a_bridge(ab, ab);
1085
1086 return ab;
1087}
1088
1089static acpi_status acpi_scan_from_root_pci_callback (
1090 acpi_handle handle,
1091 u32 Level,
1092 void *context,
1093 void **retval
1094 )
1095{
1096 ulong segnum = 0;
1097 ulong busnum = 0;
1098 acpi_status status;
1099 struct acpi_bridge *ab;
1100 u8 *path_name = acpi_path_name(handle);
1101
1102 /* get bus number of this pci root bridge */
1103 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
1104 if (ACPI_FAILURE(status)) {
1105 if (status != AE_NOT_FOUND) {
1106 err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
1107 return status;
1108 }
1109 segnum = 0;
1110 }
1111
1112 /* get bus number of this pci root bridge */
1113 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
1114 if (ACPI_FAILURE(status)) {
1115 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
1116 return (status);
1117 }
1118
1119 ab = add_host_bridge(handle, segnum, busnum);
1120 if (ab) {
1121 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1122 handle,
1123 1,
1124 scan_p2p_bridge,
1125 ab,
1126 NULL);
1127 if (ACPI_FAILURE(status))
1128 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1129 } 224 }
1130 225
1131 return AE_OK; 226 err("Cannot get control of hotplug hardware for pci %s\n",
227 pci_name(dev));
228 return -1;
1132} 229}
1133 230
1134static int pciehprm_acpi_scan_pci (void) 231void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
232 struct hotplug_params *hpp)
1135{ 233{
1136 acpi_status status; 234 acpi_status status = AE_NOT_FOUND;
235 struct pci_dev *pdev = dev;
1137 236
1138 /* 237 /*
1139 * TBD: traverse LDM device tree with the help of 238 * _HPP settings apply to all child buses, until another _HPP is
1140 * unified ACPI augmented for php device population. 239 * encountered. If we don't find an _HPP for the input pci dev,
240 * look for it in the parent device scope since that would apply to
241 * this pci dev. If we don't find any _HPP, use hardcoded defaults
1141 */ 242 */
1142 status = acpi_get_devices ( PCI_ROOT_HID_STRING, 243 while (pdev && (ACPI_FAILURE(status))) {
1143 acpi_scan_from_root_pci_callback, 244 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
1144 NULL, 245 if (!handle)
1145 NULL ); 246 break;
1146 if (ACPI_FAILURE(status)) { 247 status = acpi_run_hpp(handle, hpp);
1147 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status); 248 if (!(pdev->bus->parent))
1148 return -1; 249 break;
1149 } 250 /* Check if a parent object supports _HPP */
1150 251 pdev = pdev->bus->parent->self;
1151 return 0;
1152}
1153
1154int pciehprm_init(enum php_ctlr_type ctlr_type)
1155{
1156 int rc;
1157
1158 if (ctlr_type != PCI)
1159 return -ENODEV;
1160
1161 dbg("pciehprm ACPI init <enter>\n");
1162 acpi_bridges_head = NULL;
1163
1164 /* construct PCI bus:device tree of acpi_handles */
1165 rc = pciehprm_acpi_scan_pci();
1166 if (rc)
1167 return rc;
1168
1169 if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
1170 err("Fails to gain control of native hot-plug\n");
1171 rc = -ENODEV;
1172 }
1173
1174 dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
1175 return rc;
1176}
1177
1178static void free_a_slot(struct acpi_php_slot *aps)
1179{
1180 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
1181
1182 free_pci_resource (aps->io_head);
1183 free_pci_resource (aps->bus_head);
1184 free_pci_resource (aps->mem_head);
1185 free_pci_resource (aps->p_mem_head);
1186
1187 kfree(aps);
1188}
1189
1190static void free_a_bridge( struct acpi_bridge *ab)
1191{
1192 struct acpi_php_slot *aps, *next;
1193
1194 switch (ab->type) {
1195 case BRIDGE_TYPE_HOST:
1196 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1197 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1198 break;
1199 case BRIDGE_TYPE_P2P:
1200 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1201 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1202 break;
1203 };
1204
1205 /* free slots first */
1206 for (aps = ab->slots; aps; aps = next) {
1207 next = aps->next;
1208 free_a_slot(aps);
1209 }
1210
1211 free_pci_resource (ab->io_head);
1212 free_pci_resource (ab->tio_head);
1213 free_pci_resource (ab->bus_head);
1214 free_pci_resource (ab->tbus_head);
1215 free_pci_resource (ab->mem_head);
1216 free_pci_resource (ab->tmem_head);
1217 free_pci_resource (ab->p_mem_head);
1218 free_pci_resource (ab->tp_mem_head);
1219
1220 kfree(ab);
1221}
1222
1223static void pciehprm_free_bridges ( struct acpi_bridge *ab)
1224{
1225 if (!ab)
1226 return;
1227
1228 if (ab->child)
1229 pciehprm_free_bridges (ab->child);
1230
1231 if (ab->next)
1232 pciehprm_free_bridges (ab->next);
1233
1234 free_a_bridge(ab);
1235}
1236
1237void pciehprm_cleanup(void)
1238{
1239 pciehprm_free_bridges (acpi_bridges_head);
1240}
1241
1242static int get_number_of_slots (
1243 struct acpi_bridge *ab,
1244 int selfonly
1245 )
1246{
1247 struct acpi_php_slot *aps;
1248 int prev_slot = -1;
1249 int slot_num = 0;
1250
1251 for ( aps = ab->slots; aps; aps = aps->next)
1252 if (aps->dev != prev_slot) {
1253 prev_slot = aps->dev;
1254 slot_num++;
1255 }
1256
1257 if (ab->child)
1258 slot_num += get_number_of_slots (ab->child, 0);
1259
1260 if (selfonly)
1261 return slot_num;
1262
1263 if (ab->next)
1264 slot_num += get_number_of_slots (ab->next, 0);
1265
1266 return slot_num;
1267}
1268
1269static int print_acpi_resources (struct acpi_bridge *ab)
1270{
1271 struct acpi_php_slot *aps;
1272 int i;
1273
1274 switch (ab->type) {
1275 case BRIDGE_TYPE_HOST:
1276 dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
1277 break;
1278 case BRIDGE_TYPE_P2P:
1279 dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
1280 break;
1281 };
1282
1283 print_pci_resources (ab);
1284
1285 for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
1286 if (aps->dev == i)
1287 continue;
1288 dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1289 print_slot_resources(aps);
1290 i = aps->dev;
1291 }
1292
1293 if (ab->child)
1294 print_acpi_resources (ab->child);
1295
1296 if (ab->next)
1297 print_acpi_resources (ab->next);
1298
1299 return 0;
1300}
1301
1302int pciehprm_print_pirt(void)
1303{
1304 dbg("PCIEHPRM ACPI Slots\n");
1305 if (acpi_bridges_head)
1306 print_acpi_resources (acpi_bridges_head);
1307
1308 return 0;
1309}
1310
1311static struct acpi_php_slot * get_acpi_slot (
1312 struct acpi_bridge *ab,
1313 u32 sun
1314 )
1315{
1316 struct acpi_php_slot *aps = NULL;
1317
1318 for ( aps = ab->slots; aps; aps = aps->next)
1319 if (aps->sun == sun)
1320 return aps;
1321
1322 if (!aps && ab->child) {
1323 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
1324 if (aps)
1325 return aps;
1326 }
1327
1328 if (!aps && ab->next) {
1329 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
1330 if (aps)
1331 return aps;
1332 }
1333
1334 return aps;
1335
1336}
1337
1338#if 0
1339void * pciehprm_get_slot(struct slot *slot)
1340{
1341 struct acpi_bridge *ab = acpi_bridges_head;
1342 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
1343
1344 aps->slot = slot;
1345
1346 dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1347
1348 return (void *)aps;
1349}
1350#endif
1351
1352static void pciehprm_dump_func_res( struct pci_func *fun)
1353{
1354 struct pci_func *func = fun;
1355
1356 if (func->bus_head) {
1357 dbg(": BUS Resources:\n");
1358 print_pci_resource (func->bus_head);
1359 }
1360 if (func->io_head) {
1361 dbg(": IO Resources:\n");
1362 print_pci_resource (func->io_head);
1363 }
1364 if (func->mem_head) {
1365 dbg(": MEM Resources:\n");
1366 print_pci_resource (func->mem_head);
1367 }
1368 if (func->p_mem_head) {
1369 dbg(": PMEM Resources:\n");
1370 print_pci_resource (func->p_mem_head);
1371 }
1372}
1373
1374static void pciehprm_dump_ctrl_res( struct controller *ctlr)
1375{
1376 struct controller *ctrl = ctlr;
1377
1378 if (ctrl->bus_head) {
1379 dbg(": BUS Resources:\n");
1380 print_pci_resource (ctrl->bus_head);
1381 }
1382 if (ctrl->io_head) {
1383 dbg(": IO Resources:\n");
1384 print_pci_resource (ctrl->io_head);
1385 }
1386 if (ctrl->mem_head) {
1387 dbg(": MEM Resources:\n");
1388 print_pci_resource (ctrl->mem_head);
1389 }
1390 if (ctrl->p_mem_head) {
1391 dbg(": PMEM Resources:\n");
1392 print_pci_resource (ctrl->p_mem_head);
1393 }
1394}
1395
1396static int pciehprm_get_used_resources (
1397 struct controller *ctrl,
1398 struct pci_func *func
1399 )
1400{
1401 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
1402}
1403
1404static int configure_existing_function(
1405 struct controller *ctrl,
1406 struct pci_func *func
1407 )
1408{
1409 int rc;
1410
1411 /* see how much resources the func has used. */
1412 rc = pciehprm_get_used_resources (ctrl, func);
1413
1414 if (!rc) {
1415 /* subtract the resources used by the func from ctrl resources */
1416 rc = pciehprm_delete_resources (&ctrl->bus_head, func->bus_head);
1417 rc |= pciehprm_delete_resources (&ctrl->io_head, func->io_head);
1418 rc |= pciehprm_delete_resources (&ctrl->mem_head, func->mem_head);
1419 rc |= pciehprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
1420 if (rc)
1421 warn("aCEF: cannot del used resources\n");
1422 } else
1423 err("aCEF: cannot get used resources\n");
1424
1425 return rc;
1426}
1427
1428static int bind_pci_resources_to_slots ( struct controller *ctrl)
1429{
1430 struct pci_func *func, new_func;
1431 int busn = ctrl->slot_bus;
1432 int devn, funn;
1433 u32 vid;
1434
1435 for (devn = 0; devn < 32; devn++) {
1436 for (funn = 0; funn < 8; funn++) {
1437 /*
1438 if (devn == ctrl->device && funn == ctrl->function)
1439 continue;
1440 */
1441 /* find out if this entry is for an occupied slot */
1442 vid = 0xFFFFFFFF;
1443 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
1444
1445 if (vid != 0xFFFFFFFF) {
1446 dbg("%s: vid = %x\n", __FUNCTION__, vid);
1447 func = pciehp_slot_find(busn, devn, funn);
1448 if (!func) {
1449 memset(&new_func, 0, sizeof(struct pci_func));
1450 new_func.bus = busn;
1451 new_func.device = devn;
1452 new_func.function = funn;
1453 new_func.is_a_board = 1;
1454 configure_existing_function(ctrl, &new_func);
1455 pciehprm_dump_func_res(&new_func);
1456 } else {
1457 configure_existing_function(ctrl, func);
1458 pciehprm_dump_func_res(func);
1459 }
1460 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
1461 }
1462 }
1463 }
1464
1465 return 0;
1466}
1467
1468static int bind_pci_resources(
1469 struct controller *ctrl,
1470 struct acpi_bridge *ab
1471 )
1472{
1473 int status = 0;
1474
1475 if (ab->bus_head) {
1476 dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
1477 status = pciehprm_add_resources (&ctrl->bus_head, ab->bus_head);
1478 if (pciehprm_delete_resources (&ab->bus_head, ctrl->bus_head))
1479 warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
1480 if (status) {
1481 err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1482 return status;
1483 }
1484 } else
1485 info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
1486
1487 if (ab->io_head) {
1488 dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
1489 status = pciehprm_add_resources (&ctrl->io_head, ab->io_head);
1490 if (pciehprm_delete_resources (&ab->io_head, ctrl->io_head))
1491 warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
1492 if (status) {
1493 err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1494 return status;
1495 }
1496 } else
1497 info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
1498
1499 if (ab->mem_head) {
1500 dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
1501 status = pciehprm_add_resources (&ctrl->mem_head, ab->mem_head);
1502 if (pciehprm_delete_resources (&ab->mem_head, ctrl->mem_head))
1503 warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
1504 if (status) {
1505 err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1506 return status;
1507 }
1508 } else
1509 info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
1510
1511 if (ab->p_mem_head) {
1512 dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
1513 status = pciehprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
1514 if (pciehprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
1515 warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
1516 if (status) {
1517 err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1518 return status;
1519 }
1520 } else
1521 info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
1522
1523 return status;
1524}
1525
1526static int no_pci_resources( struct acpi_bridge *ab)
1527{
1528 return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
1529}
1530
1531static int find_pci_bridge_resources (
1532 struct controller *ctrl,
1533 struct acpi_bridge *ab
1534 )
1535{
1536 int rc = 0;
1537 struct pci_func func;
1538
1539 memset(&func, 0, sizeof(struct pci_func));
1540
1541 func.bus = ab->pbus;
1542 func.device = ab->pdevice;
1543 func.function = ab->pfunction;
1544 func.is_a_board = 1;
1545
1546 /* Get used resources for this PCI bridge */
1547 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
1548
1549 ab->io_head = func.io_head;
1550 ab->mem_head = func.mem_head;
1551 ab->p_mem_head = func.p_mem_head;
1552 ab->bus_head = func.bus_head;
1553 if (ab->bus_head)
1554 pciehprm_delete_resource(&ab->bus_head, ctrl->pci_dev->subordinate->number, 1);
1555
1556 return rc;
1557}
1558
1559static int get_pci_resources_from_bridge(
1560 struct controller *ctrl,
1561 struct acpi_bridge *ab
1562 )
1563{
1564 int rc = 0;
1565
1566 dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
1567
1568 rc = find_pci_bridge_resources (ctrl, ab);
1569
1570 pciehp_resource_sort_and_combine(&ab->bus_head);
1571 pciehp_resource_sort_and_combine(&ab->io_head);
1572 pciehp_resource_sort_and_combine(&ab->mem_head);
1573 pciehp_resource_sort_and_combine(&ab->p_mem_head);
1574
1575 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
1576 pciehprm_add_resources (&ab->tio_head, ab->io_head);
1577 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
1578 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
1579
1580 return rc;
1581}
1582
1583static int get_pci_resources(
1584 struct controller *ctrl,
1585 struct acpi_bridge *ab
1586 )
1587{
1588 int rc = 0;
1589
1590 if (no_pci_resources(ab)) {
1591 dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
1592 rc = get_pci_resources_from_bridge(ctrl, ab);
1593 }
1594
1595 return rc;
1596}
1597
1598/*
1599 * Get resources for this ctrl.
1600 * 1. get total resources from ACPI _CRS or bridge (this ctrl)
1601 * 2. find used resources of existing adapters
1602 * 3. subtract used resources from total resources
1603 */
1604int pciehprm_find_available_resources( struct controller *ctrl)
1605{
1606 int rc = 0;
1607 struct acpi_bridge *ab;
1608
1609 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
1610 if (!ab) {
1611 err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1612 return -1;
1613 }
1614 if (no_pci_resources(ab)) {
1615 rc = get_pci_resources(ctrl, ab);
1616 if (rc) {
1617 err("pfar:cannot get pci resources of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1618 return -1;
1619 }
1620 }
1621
1622 rc = bind_pci_resources(ctrl, ab);
1623 dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1624 pciehprm_dump_ctrl_res(ctrl);
1625
1626 bind_pci_resources_to_slots (ctrl);
1627
1628 dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1629 pciehprm_dump_ctrl_res(ctrl);
1630
1631 return rc;
1632}
1633
1634int pciehprm_set_hpp(
1635 struct controller *ctrl,
1636 struct pci_func *func,
1637 u8 card_type
1638 )
1639{
1640 struct acpi_bridge *ab;
1641 struct pci_bus lpci_bus, *pci_bus;
1642 int rc = 0;
1643 unsigned int devfn;
1644 u8 cls= 0x08; /* default cache line size */
1645 u8 lt = 0x40; /* default latency timer */
1646 u8 ep = 0;
1647 u8 es = 0;
1648
1649 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1650 pci_bus = &lpci_bus;
1651 pci_bus->number = func->bus;
1652 devfn = PCI_DEVFN(func->device, func->function);
1653
1654 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1655
1656 if (ab) {
1657 if (ab->_hpp) {
1658 lt = (u8)ab->_hpp->latency_timer;
1659 cls = (u8)ab->_hpp->cache_line_size;
1660 ep = (u8)ab->_hpp->enable_perr;
1661 es = (u8)ab->_hpp->enable_serr;
1662 } else
1663 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1664 } else
1665 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1666
1667
1668 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1669 /* set subordinate Latency Timer */
1670 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
1671 } 252 }
1672
1673 /* set base Latency Timer */
1674 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
1675 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
1676
1677 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
1678 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
1679
1680 return rc;
1681} 253}
1682 254
1683void pciehprm_enable_card(
1684 struct controller *ctrl,
1685 struct pci_func *func,
1686 u8 card_type)
1687{
1688 u16 command, cmd, bcommand, bcmd;
1689 struct pci_bus lpci_bus, *pci_bus;
1690 struct acpi_bridge *ab;
1691 unsigned int devfn;
1692 int rc;
1693
1694 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1695 pci_bus = &lpci_bus;
1696 pci_bus->number = func->bus;
1697 devfn = PCI_DEVFN(func->device, func->function);
1698
1699 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
1700
1701 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1702 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
1703 }
1704
1705 command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1706 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1707 bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
1708
1709 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1710 if (ab) {
1711 if (ab->_hpp) {
1712 if (ab->_hpp->enable_perr) {
1713 command |= PCI_COMMAND_PARITY;
1714 bcommand |= PCI_BRIDGE_CTL_PARITY;
1715 } else {
1716 command &= ~PCI_COMMAND_PARITY;
1717 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
1718 }
1719 if (ab->_hpp->enable_serr) {
1720 command |= PCI_COMMAND_SERR;
1721 bcommand |= PCI_BRIDGE_CTL_SERR;
1722 } else {
1723 command &= ~PCI_COMMAND_SERR;
1724 bcommand &= ~PCI_BRIDGE_CTL_SERR;
1725 }
1726 } else
1727 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1728 } else
1729 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1730
1731 if (command != cmd) {
1732 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
1733 }
1734 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
1735 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
1736 }
1737}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
index 76c727c74cc0..29180dfe8493 100644
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -27,479 +27,21 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/pci.h> 34#include <linux/pci.h>
36#include <linux/init.h>
37#include <linux/slab.h> 35#include <linux/slab.h>
38
39#include <asm/uaccess.h>
40#ifdef CONFIG_IA64
41#include <asm/iosapic.h>
42#endif
43
44#include "pciehp.h" 36#include "pciehp.h"
45#include "pciehprm.h"
46#include "pciehprm_nonacpi.h"
47
48 37
49void pciehprm_cleanup(void) 38void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
39 struct hotplug_params *hpp)
50{ 40{
51 return; 41 return;
52} 42}
53 43
54int pciehprm_print_pirt(void) 44int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
55{
56 return 0;
57}
58
59int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
60{
61
62 *sun = (u8) (ctrl->first_slot);
63 return 0;
64}
65
66
67static void print_pci_resource ( struct pci_resource *aprh)
68{
69 struct pci_resource *res;
70
71 for (res = aprh; res; res = res->next)
72 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
73}
74
75
76static void phprm_dump_func_res( struct pci_func *fun)
77{
78 struct pci_func *func = fun;
79
80 if (func->bus_head) {
81 dbg(": BUS Resources:\n");
82 print_pci_resource (func->bus_head);
83 }
84 if (func->io_head) {
85 dbg(": IO Resources:\n");
86 print_pci_resource (func->io_head);
87 }
88 if (func->mem_head) {
89 dbg(": MEM Resources:\n");
90 print_pci_resource (func->mem_head);
91 }
92 if (func->p_mem_head) {
93 dbg(": PMEM Resources:\n");
94 print_pci_resource (func->p_mem_head);
95 }
96}
97
98static int phprm_get_used_resources (
99 struct controller *ctrl,
100 struct pci_func *func
101 )
102{
103 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
104}
105
106static int phprm_delete_resource(
107 struct pci_resource **aprh,
108 ulong base,
109 ulong size)
110{
111 struct pci_resource *res;
112 struct pci_resource *prevnode;
113 struct pci_resource *split_node;
114 ulong tbase;
115
116 pciehp_resource_sort_and_combine(aprh);
117
118 for (res = *aprh; res; res = res->next) {
119 if (res->base > base)
120 continue;
121
122 if ((res->base + res->length) < (base + size))
123 continue;
124
125 if (res->base < base) {
126 tbase = base;
127
128 if ((res->length - (tbase - res->base)) < size)
129 continue;
130
131 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
132 if (!split_node)
133 return -ENOMEM;
134
135 split_node->base = res->base;
136 split_node->length = tbase - res->base;
137 res->base = tbase;
138 res->length -= split_node->length;
139
140 split_node->next = res->next;
141 res->next = split_node;
142 }
143
144 if (res->length >= size) {
145 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
146 if (!split_node)
147 return -ENOMEM;
148
149 split_node->base = res->base + size;
150 split_node->length = res->length - size;
151 res->length = size;
152
153 split_node->next = res->next;
154 res->next = split_node;
155 }
156
157 if (*aprh == res) {
158 *aprh = res->next;
159 } else {
160 prevnode = *aprh;
161 while (prevnode->next != res)
162 prevnode = prevnode->next;
163
164 prevnode->next = res->next;
165 }
166 res->next = NULL;
167 kfree(res);
168 break;
169 }
170
171 return 0;
172}
173
174
175static int phprm_delete_resources(
176 struct pci_resource **aprh,
177 struct pci_resource *this
178 )
179{
180 struct pci_resource *res;
181
182 for (res = this; res; res = res->next)
183 phprm_delete_resource(aprh, res->base, res->length);
184
185 return 0;
186}
187
188
189static int configure_existing_function(
190 struct controller *ctrl,
191 struct pci_func *func
192 )
193{
194 int rc;
195
196 /* see how much resources the func has used. */
197 rc = phprm_get_used_resources (ctrl, func);
198
199 if (!rc) {
200 /* subtract the resources used by the func from ctrl resources */
201 rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
202 rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
203 rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
204 rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
205 if (rc)
206 warn("aCEF: cannot del used resources\n");
207 } else
208 err("aCEF: cannot get used resources\n");
209
210 return rc;
211}
212
213static int pciehprm_delete_resource(
214 struct pci_resource **aprh,
215 ulong base,
216 ulong size)
217{
218 struct pci_resource *res;
219 struct pci_resource *prevnode;
220 struct pci_resource *split_node;
221 ulong tbase;
222
223 pciehp_resource_sort_and_combine(aprh);
224
225 for (res = *aprh; res; res = res->next) {
226 if (res->base > base)
227 continue;
228
229 if ((res->base + res->length) < (base + size))
230 continue;
231
232 if (res->base < base) {
233 tbase = base;
234
235 if ((res->length - (tbase - res->base)) < size)
236 continue;
237
238 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
239 if (!split_node)
240 return -ENOMEM;
241
242 split_node->base = res->base;
243 split_node->length = tbase - res->base;
244 res->base = tbase;
245 res->length -= split_node->length;
246
247 split_node->next = res->next;
248 res->next = split_node;
249 }
250
251 if (res->length >= size) {
252 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
253 if (!split_node)
254 return -ENOMEM;
255
256 split_node->base = res->base + size;
257 split_node->length = res->length - size;
258 res->length = size;
259
260 split_node->next = res->next;
261 res->next = split_node;
262 }
263
264 if (*aprh == res) {
265 *aprh = res->next;
266 } else {
267 prevnode = *aprh;
268 while (prevnode->next != res)
269 prevnode = prevnode->next;
270
271 prevnode->next = res->next;
272 }
273 res->next = NULL;
274 kfree(res);
275 break;
276 }
277
278 return 0;
279}
280
281static int bind_pci_resources_to_slots ( struct controller *ctrl)
282{ 45{
283 struct pci_func *func, new_func;
284 int busn = ctrl->slot_bus;
285 int devn, funn;
286 u32 vid;
287
288 for (devn = 0; devn < 32; devn++) {
289 for (funn = 0; funn < 8; funn++) {
290 /*
291 if (devn == ctrl->device && funn == ctrl->function)
292 continue;
293 */
294 /* find out if this entry is for an occupied slot */
295 vid = 0xFFFFFFFF;
296
297 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
298
299 if (vid != 0xFFFFFFFF) {
300 dbg("%s: vid = %x bus %x dev %x fun %x\n", __FUNCTION__,
301 vid, busn, devn, funn);
302 func = pciehp_slot_find(busn, devn, funn);
303 dbg("%s: func = %p\n", __FUNCTION__,func);
304 if (!func) {
305 memset(&new_func, 0, sizeof(struct pci_func));
306 new_func.bus = busn;
307 new_func.device = devn;
308 new_func.function = funn;
309 new_func.is_a_board = 1;
310 configure_existing_function(ctrl, &new_func);
311 phprm_dump_func_res(&new_func);
312 } else {
313 configure_existing_function(ctrl, func);
314 phprm_dump_func_res(func);
315 }
316 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
317 }
318 }
319 }
320
321 return 0; 46 return 0;
322} 47}
323
324static void phprm_dump_ctrl_res( struct controller *ctlr)
325{
326 struct controller *ctrl = ctlr;
327
328 if (ctrl->bus_head) {
329 dbg(": BUS Resources:\n");
330 print_pci_resource (ctrl->bus_head);
331 }
332 if (ctrl->io_head) {
333 dbg(": IO Resources:\n");
334 print_pci_resource (ctrl->io_head);
335 }
336 if (ctrl->mem_head) {
337 dbg(": MEM Resources:\n");
338 print_pci_resource (ctrl->mem_head);
339 }
340 if (ctrl->p_mem_head) {
341 dbg(": PMEM Resources:\n");
342 print_pci_resource (ctrl->p_mem_head);
343 }
344}
345
346/*
347 * phprm_find_available_resources
348 *
349 * Finds available memory, IO, and IRQ resources for programming
350 * devices which may be added to the system
351 * this function is for hot plug ADD!
352 *
353 * returns 0 if success
354 */
355int pciehprm_find_available_resources(struct controller *ctrl)
356{
357 struct pci_func func;
358 u32 rc;
359
360 memset(&func, 0, sizeof(struct pci_func));
361
362 func.bus = ctrl->bus;
363 func.device = ctrl->device;
364 func.function = ctrl->function;
365 func.is_a_board = 1;
366
367 /* Get resources for this PCI bridge */
368 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
369 dbg("%s: pciehp_save_used_resources rc = %d\n", __FUNCTION__, rc);
370
371 if (func.mem_head)
372 func.mem_head->next = ctrl->mem_head;
373 ctrl->mem_head = func.mem_head;
374
375 if (func.p_mem_head)
376 func.p_mem_head->next = ctrl->p_mem_head;
377 ctrl->p_mem_head = func.p_mem_head;
378
379 if (func.io_head)
380 func.io_head->next = ctrl->io_head;
381 ctrl->io_head = func.io_head;
382
383 if(func.bus_head)
384 func.bus_head->next = ctrl->bus_head;
385 ctrl->bus_head = func.bus_head;
386
387 if (ctrl->bus_head)
388 pciehprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
389
390 dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
391 phprm_dump_ctrl_res(ctrl);
392
393 dbg("%s: before bind_pci_resources_to slots\n", __FUNCTION__);
394
395 bind_pci_resources_to_slots (ctrl);
396
397 dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
398 phprm_dump_ctrl_res(ctrl);
399
400 return (rc);
401}
402
403int pciehprm_set_hpp(
404 struct controller *ctrl,
405 struct pci_func *func,
406 u8 card_type)
407{
408 u32 rc;
409 u8 temp_byte;
410 struct pci_bus lpci_bus, *pci_bus;
411 unsigned int devfn;
412 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
413 pci_bus = &lpci_bus;
414 pci_bus->number = func->bus;
415 devfn = PCI_DEVFN(func->device, func->function);
416
417 temp_byte = 0x40; /* hard coded value for LT */
418 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
419 /* set subordinate Latency Timer */
420 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
421
422 if (rc) {
423 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
424 func->bus, func->device, func->function);
425 return rc;
426 }
427 }
428
429 /* set base Latency Timer */
430 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
431
432 if (rc) {
433 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
434 return rc;
435 }
436
437 /* set Cache Line size */
438 temp_byte = 0x08; /* hard coded value for CLS */
439
440 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
441
442 if (rc) {
443 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
444 }
445
446 /* set enable_perr */
447 /* set enable_serr */
448
449 return rc;
450}
451
452void pciehprm_enable_card(
453 struct controller *ctrl,
454 struct pci_func *func,
455 u8 card_type)
456{
457 u16 command, bcommand;
458 struct pci_bus lpci_bus, *pci_bus;
459 unsigned int devfn;
460 int rc;
461
462 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
463 pci_bus = &lpci_bus;
464 pci_bus->number = func->bus;
465 devfn = PCI_DEVFN(func->device, func->function);
466
467 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
468
469 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
470 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
471 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
472
473 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
474
475 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
476
477 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
478
479 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
480 | PCI_BRIDGE_CTL_NO_ISA;
481
482 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
483 }
484}
485
486static int legacy_pciehprm_init_pci(void)
487{
488 return 0;
489}
490
491int pciehprm_init(enum php_ctlr_type ctrl_type)
492{
493 int retval;
494
495 switch (ctrl_type) {
496 case PCI:
497 retval = legacy_pciehprm_init_pci();
498 break;
499 default:
500 retval = -ENODEV;
501 break;
502 }
503
504 return retval;
505}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
deleted file mode 100644
index b10603b0e958..000000000000
--- a/drivers/pci/hotplug/pciehprm_nonacpi.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_NONACPI_H_
31#define _PCIEHPRM_NONACPI_H_
32
33struct irq_info {
34 u8 bus, devfn; /* bus, device and function */
35 struct {
36 u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
37 u16 bitmap; /* Available IRQs */
38 } __attribute__ ((packed)) irq[4];
39 u8 slot; /* slot number, 0=onboard */
40 u8 rfu;
41} __attribute__ ((packed));
42
43struct irq_routing_table {
44 u32 signature; /* PIRQ_SIGNATURE should be here */
45 u16 version; /* PIRQ_VERSION */
46 u16 size; /* Table size in bytes */
47 u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
48 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
49 u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
50 u32 miniport_data; /* Crap */
51 u8 rfu[11];
52 u8 checksum; /* Modulo 256 checksum must give zero */
53 struct irq_info slots[0];
54} __attribute__ ((packed));
55
56#endif /* _PCIEHPRM_NONACPI_H_ */
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index fcb66b9a0e28..cc03609f45d0 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -134,43 +134,6 @@ static void rpadlpar_claim_one_bus(struct pci_bus *b)
134 rpadlpar_claim_one_bus(child_bus); 134 rpadlpar_claim_one_bus(child_bus);
135} 135}
136 136
137static int pci_add_secondary_bus(struct device_node *dn,
138 struct pci_dev *bridge_dev)
139{
140 struct pci_dn *pdn = dn->data;
141 struct pci_controller *hose = pdn->phb;
142 struct pci_bus *child;
143 u8 sec_busno;
144
145 /* Get busno of downstream bus */
146 pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
147
148 /* Allocate and add to children of bridge_dev->bus */
149 child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
150 if (!child) {
151 printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
152 return -ENOMEM;
153 }
154
155 sprintf(child->name, "PCI Bus #%02x", child->number);
156
157 /* Fixup subordinate bridge bases and resources */
158 pcibios_fixup_bus(child);
159
160 /* Claim new bus resources */
161 rpadlpar_claim_one_bus(bridge_dev->bus);
162
163 if (hose->last_busno < child->number)
164 hose->last_busno = child->number;
165
166 pdn->bussubno = child->number;
167
168 /* ioremap() for child bus, which may or may not succeed */
169 remap_bus_range(child);
170
171 return 0;
172}
173
174static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, 137static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
175 struct device_node *dev_dn) 138 struct device_node *dev_dn)
176{ 139{
@@ -188,29 +151,41 @@ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
188static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) 151static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
189{ 152{
190 struct pci_dn *pdn = dn->data; 153 struct pci_dn *pdn = dn->data;
191 struct pci_controller *hose = pdn->phb; 154 struct pci_controller *phb = pdn->phb;
192 struct pci_dev *dev = NULL; 155 struct pci_dev *dev = NULL;
193 156
194 /* Scan phb bus for EADS device, adding new one to bus->devices */ 157 rpaphp_eeh_init_nodes(dn);
195 if (!pci_scan_single_device(hose->bus, pdn->devfn)) { 158 /* Add EADS device to PHB bus, adding new entry to bus->devices */
196 printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__); 159 dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);
160 if (!dev) {
161 printk(KERN_ERR "%s: failed to create pci dev for %s\n",
162 __FUNCTION__, dn->full_name);
197 return NULL; 163 return NULL;
198 } 164 }
199 165
166 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
167 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
168 of_scan_pci_bridge(dn, dev);
169
170 rpaphp_init_new_devs(dev->subordinate);
171
172 /* Claim new bus resources */
173 rpadlpar_claim_one_bus(dev->bus);
174
175 /* ioremap() for child bus, which may or may not succeed */
176 (void) remap_bus_range(dev->bus);
177
200 /* Add new devices to global lists. Register in proc, sysfs. */ 178 /* Add new devices to global lists. Register in proc, sysfs. */
201 pci_bus_add_devices(hose->bus); 179 pci_bus_add_devices(phb->bus);
202 180
203 /* Confirm new bridge dev was created */ 181 /* Confirm new bridge dev was created */
204 dev = dlpar_find_new_dev(hose->bus, dn); 182 dev = dlpar_find_new_dev(phb->bus, dn);
205 if (dev) { 183 if (dev) {
206 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { 184 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
207 printk(KERN_ERR "%s: unexpected header type %d\n", 185 printk(KERN_ERR "%s: unexpected header type %d\n",
208 __FUNCTION__, dev->hdr_type); 186 __FUNCTION__, dev->hdr_type);
209 return NULL; 187 return NULL;
210 } 188 }
211
212 if (pci_add_secondary_bus(dn, dev))
213 return NULL;
214 } 189 }
215 190
216 return dev; 191 return dev;
@@ -219,7 +194,6 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
219static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) 194static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
220{ 195{
221 struct pci_dev *dev; 196 struct pci_dev *dev;
222 int rc;
223 197
224 if (rpaphp_find_pci_bus(dn)) 198 if (rpaphp_find_pci_bus(dn))
225 return -EINVAL; 199 return -EINVAL;
@@ -232,15 +206,6 @@ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
232 return -EIO; 206 return -EIO;
233 } 207 }
234 208
235 if (dn->child) {
236 rc = rpaphp_config_pci_adapter(dev->subordinate);
237 if (rc < 0) {
238 printk(KERN_ERR "%s: unable to enable slot %s\n",
239 __FUNCTION__, drc_name);
240 return -EIO;
241 }
242 }
243
244 /* Add hotplug slot */ 209 /* Add hotplug slot */
245 if (rpaphp_add_slot(dn)) { 210 if (rpaphp_add_slot(dn)) {
246 printk(KERN_ERR "%s: unable to add hotplug slot %s\n", 211 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
@@ -306,7 +271,7 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn)
306{ 271{
307 struct pci_controller *phb; 272 struct pci_controller *phb;
308 273
309 if (PCI_DN(dn)->phb) { 274 if (PCI_DN(dn) && PCI_DN(dn)->phb) {
310 /* PHB already exists */ 275 /* PHB already exists */
311 return -EINVAL; 276 return -EINVAL;
312 } 277 }
@@ -435,6 +400,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
435 __FUNCTION__, drc_name); 400 __FUNCTION__, drc_name);
436 return -EIO; 401 return -EIO;
437 } 402 }
403 } else {
404 rpaphp_unconfig_pci_adapter(bus);
438 } 405 }
439 406
440 if (unmap_bus_range(bus)) { 407 if (unmap_bus_range(bus)) {
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 71ea5f9bb284..57ea71a7bda5 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -93,6 +93,8 @@ extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
93extern int rpaphp_enable_pci_slot(struct slot *slot); 93extern int rpaphp_enable_pci_slot(struct slot *slot);
94extern int register_pci_slot(struct slot *slot); 94extern int register_pci_slot(struct slot *slot);
95extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); 95extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
96extern void rpaphp_init_new_devs(struct pci_bus *bus);
97extern void rpaphp_eeh_init_nodes(struct device_node *dn);
96 98
97extern int rpaphp_config_pci_adapter(struct pci_bus *bus); 99extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
98extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); 100extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index f7c12d7dfcfc..a7859a84d1ae 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -154,8 +154,7 @@ exit:
154} 154}
155 155
156/* Must be called before pci_bus_add_devices */ 156/* Must be called before pci_bus_add_devices */
157static void 157void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
158rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
159{ 158{
160 struct pci_dev *dev; 159 struct pci_dev *dev;
161 160
@@ -184,6 +183,20 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
184 } 183 }
185} 184}
186 185
186static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
187{
188 struct pci_dev *dev;
189
190 list_for_each_entry(dev, &bus->devices, bus_list) {
191 eeh_add_device_late(dev);
192 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
193 struct pci_bus *subbus = dev->subordinate;
194 if (subbus)
195 rpaphp_eeh_add_bus_device (subbus);
196 }
197 }
198}
199
187static int rpaphp_pci_config_bridge(struct pci_dev *dev) 200static int rpaphp_pci_config_bridge(struct pci_dev *dev)
188{ 201{
189 u8 sec_busno; 202 u8 sec_busno;
@@ -217,6 +230,13 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
217 return 0; 230 return 0;
218} 231}
219 232
233void rpaphp_init_new_devs(struct pci_bus *bus)
234{
235 rpaphp_fixup_new_pci_devices(bus, 0);
236 rpaphp_eeh_add_bus_device(bus);
237}
238EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
239
220/***************************************************************************** 240/*****************************************************************************
221 rpaphp_pci_config_slot() will configure all devices under the 241 rpaphp_pci_config_slot() will configure all devices under the
222 given slot->dn and return the the first pci_dev. 242 given slot->dn and return the the first pci_dev.
@@ -233,36 +253,51 @@ rpaphp_pci_config_slot(struct pci_bus *bus)
233 if (!dn || !dn->child) 253 if (!dn || !dn->child)
234 return NULL; 254 return NULL;
235 255
236 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 256 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
257 of_scan_bus(dn, bus);
258 if (list_empty(&bus->devices)) {
259 err("%s: No new device found\n", __FUNCTION__);
260 return NULL;
261 }
237 262
238 /* pci_scan_slot should find all children */ 263 rpaphp_init_new_devs(bus);
239 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
240 if (num) {
241 rpaphp_fixup_new_pci_devices(bus, 1);
242 pci_bus_add_devices(bus); 264 pci_bus_add_devices(bus);
243 } 265 dev = list_entry(&bus->devices, struct pci_dev, bus_list);
244 if (list_empty(&bus->devices)) { 266 } else {
245 err("%s: No new device found\n", __FUNCTION__); 267 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
246 return NULL; 268
247 } 269 /* pci_scan_slot should find all children */
248 list_for_each_entry(dev, &bus->devices, bus_list) { 270 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
249 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 271 if (num) {
250 rpaphp_pci_config_bridge(dev); 272 rpaphp_fixup_new_pci_devices(bus, 1);
273 pci_bus_add_devices(bus);
274 }
275 if (list_empty(&bus->devices)) {
276 err("%s: No new device found\n", __FUNCTION__);
277 return NULL;
278 }
279 list_for_each_entry(dev, &bus->devices, bus_list) {
280 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
281 rpaphp_pci_config_bridge(dev);
282
283 rpaphp_eeh_add_bus_device(bus);
284 }
251 } 285 }
252 286
253 return dev; 287 return dev;
254} 288}
255 289
256static void enable_eeh(struct device_node *dn) 290void rpaphp_eeh_init_nodes(struct device_node *dn)
257{ 291{
258 struct device_node *sib; 292 struct device_node *sib;
259 293
260 for (sib = dn->child; sib; sib = sib->sibling) 294 for (sib = dn->child; sib; sib = sib->sibling)
261 enable_eeh(sib); 295 rpaphp_eeh_init_nodes(sib);
262 eeh_add_device_early(dn); 296 eeh_add_device_early(dn);
263 return; 297 return;
264 298
265} 299}
300EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);
266 301
267static void print_slot_pci_funcs(struct pci_bus *bus) 302static void print_slot_pci_funcs(struct pci_bus *bus)
268{ 303{
@@ -289,7 +324,7 @@ int rpaphp_config_pci_adapter(struct pci_bus *bus)
289 if (!dn) 324 if (!dn)
290 goto exit; 325 goto exit;
291 326
292 enable_eeh(dn); 327 rpaphp_eeh_init_nodes(dn);
293 dev = rpaphp_pci_config_slot(bus); 328 dev = rpaphp_pci_config_slot(bus);
294 if (!dev) { 329 if (!dev) {
295 err("%s: can't find any devices.\n", __FUNCTION__); 330 err("%s: can't find any devices.\n", __FUNCTION__);
@@ -331,6 +366,7 @@ int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
331 } 366 }
332 return 0; 367 return 0;
333} 368}
369EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
334 370
335static int setup_pci_hotplug_slot_info(struct slot *slot) 371static int setup_pci_hotplug_slot_info(struct slot *slot)
336{ 372{
@@ -444,8 +480,8 @@ int rpaphp_enable_pci_slot(struct slot *slot)
444 retval = rpaphp_config_pci_adapter(slot->bus); 480 retval = rpaphp_config_pci_adapter(slot->bus);
445 if (!retval) { 481 if (!retval) {
446 slot->state = CONFIGURED; 482 slot->state = CONFIGURED;
447 dbg("%s: PCI devices in slot[%s] has been configured\n", 483 info("%s: devices in slot[%s] configured\n",
448 __FUNCTION__, slot->name); 484 __FUNCTION__, slot->name);
449 } else { 485 } else {
450 slot->state = NOT_CONFIGURED; 486 slot->state = NOT_CONFIGURED;
451 dbg("%s: no pci_dev struct for adapter in slot[%s]\n", 487 dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index b8e95acea3b6..38009bc0fd5d 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -34,7 +34,7 @@
34#include "../pci.h" 34#include "../pci.h"
35#include "shpchp.h" 35#include "shpchp.h"
36 36
37void program_fw_provided_values(struct pci_dev *dev) 37static void program_fw_provided_values(struct pci_dev *dev)
38{ 38{
39 u16 pci_cmd, pci_bctl; 39 u16 pci_cmd, pci_bctl;
40 struct pci_dev *cdev; 40 struct pci_dev *cdev;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index a2033552423c..202b7507a357 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,8 @@
23#include "pci.h" 23#include "pci.h"
24#include "msi.h" 24#include "msi.h"
25 25
26#define MSI_TARGET_CPU first_cpu(cpu_online_map)
27
26static DEFINE_SPINLOCK(msi_lock); 28static DEFINE_SPINLOCK(msi_lock);
27static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; 29static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
28static kmem_cache_t* msi_cachep; 30static kmem_cache_t* msi_cachep;
@@ -92,6 +94,7 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
92 struct msi_desc *entry; 94 struct msi_desc *entry;
93 struct msg_address address; 95 struct msg_address address;
94 unsigned int irq = vector; 96 unsigned int irq = vector;
97 unsigned int dest_cpu = first_cpu(cpu_mask);
95 98
96 entry = (struct msi_desc *)msi_desc[vector]; 99 entry = (struct msi_desc *)msi_desc[vector];
97 if (!entry || !entry->dev) 100 if (!entry || !entry->dev)
@@ -108,9 +111,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
108 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), 111 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
109 &address.lo_address.value); 112 &address.lo_address.value);
110 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 113 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
111 address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) << 114 address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
112 MSI_TARGET_CPU_SHIFT); 115 MSI_TARGET_CPU_SHIFT);
113 entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); 116 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
114 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos), 117 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
115 address.lo_address.value); 118 address.lo_address.value);
116 set_native_irq_info(irq, cpu_mask); 119 set_native_irq_info(irq, cpu_mask);
@@ -123,9 +126,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
123 126
124 address.lo_address.value = readl(entry->mask_base + offset); 127 address.lo_address.value = readl(entry->mask_base + offset);
125 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 128 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
126 address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) << 129 address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
127 MSI_TARGET_CPU_SHIFT); 130 MSI_TARGET_CPU_SHIFT);
128 entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); 131 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
129 writel(address.lo_address.value, entry->mask_base + offset); 132 writel(address.lo_address.value, entry->mask_base + offset);
130 set_native_irq_info(irq, cpu_mask); 133 set_native_irq_info(irq, cpu_mask);
131 break; 134 break;
@@ -259,14 +262,15 @@ static void msi_data_init(struct msg_data *msi_data,
259static void msi_address_init(struct msg_address *msi_address) 262static void msi_address_init(struct msg_address *msi_address)
260{ 263{
261 unsigned int dest_id; 264 unsigned int dest_id;
265 unsigned long dest_phys_id = cpu_physical_id(MSI_TARGET_CPU);
262 266
263 memset(msi_address, 0, sizeof(struct msg_address)); 267 memset(msi_address, 0, sizeof(struct msg_address));
264 msi_address->hi_address = (u32)0; 268 msi_address->hi_address = (u32)0;
265 dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT); 269 dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
266 msi_address->lo_address.u.dest_mode = MSI_DEST_MODE; 270 msi_address->lo_address.u.dest_mode = MSI_PHYSICAL_MODE;
267 msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE; 271 msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
268 msi_address->lo_address.u.dest_id = dest_id; 272 msi_address->lo_address.u.dest_id = dest_id;
269 msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT); 273 msi_address->lo_address.value |= (dest_phys_id << MSI_TARGET_CPU_SHIFT);
270} 274}
271 275
272static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); 276static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index e9e37abe1f76..a9b00cc2d885 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -91,9 +91,7 @@ acpi_query_osc (
91static acpi_status 91static acpi_status
92acpi_run_osc ( 92acpi_run_osc (
93 acpi_handle handle, 93 acpi_handle handle,
94 u32 level, 94 void *context)
95 void *context,
96 void **retval )
97{ 95{
98 acpi_status status; 96 acpi_status status;
99 struct acpi_object_list input; 97 struct acpi_object_list input;
@@ -184,7 +182,7 @@ EXPORT_SYMBOL(pci_osc_support_set);
184 * 182 *
185 * Attempt to take control from Firmware on requested control bits. 183 * Attempt to take control from Firmware on requested control bits.
186 **/ 184 **/
187acpi_status pci_osc_control_set(u32 flags) 185acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
188{ 186{
189 acpi_status status; 187 acpi_status status;
190 u32 ctrlset; 188 u32 ctrlset;
@@ -198,10 +196,7 @@ acpi_status pci_osc_control_set(u32 flags)
198 return AE_SUPPORT; 196 return AE_SUPPORT;
199 } 197 }
200 ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; 198 ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
201 status = acpi_get_devices ( PCI_ROOT_HID_STRING, 199 status = acpi_run_osc(handle, ctrlset_buf);
202 acpi_run_osc,
203 ctrlset_buf,
204 NULL );
205 if (ACPI_FAILURE (status)) { 200 if (ACPI_FAILURE (status)) {
206 ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; 201 ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
207 } 202 }
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 94e68c54d273..a9046d4b8af3 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -37,7 +37,7 @@ struct pci_dynid {
37 * Adds a new dynamic pci device ID to this driver, 37 * Adds a new dynamic pci device ID to this driver,
38 * and causes the driver to probe for all devices again. 38 * and causes the driver to probe for all devices again.
39 */ 39 */
40static inline ssize_t 40static ssize_t
41store_new_id(struct device_driver *driver, const char *buf, size_t count) 41store_new_id(struct device_driver *driver, const char *buf, size_t count)
42{ 42{
43 struct pci_dynid *dynid; 43 struct pci_dynid *dynid;
@@ -364,15 +364,16 @@ static struct kobj_type pci_driver_kobj_type = {
364}; 364};
365 365
366/** 366/**
367 * pci_register_driver - register a new pci driver 367 * __pci_register_driver - register a new pci driver
368 * @drv: the driver structure to register 368 * @drv: the driver structure to register
369 * @owner: owner module of drv
369 * 370 *
370 * Adds the driver structure to the list of registered drivers. 371 * Adds the driver structure to the list of registered drivers.
371 * Returns a negative value on error, otherwise 0. 372 * Returns a negative value on error, otherwise 0.
372 * If no error occurred, the driver remains registered even if 373 * If no error occurred, the driver remains registered even if
373 * no device was claimed during registration. 374 * no device was claimed during registration.
374 */ 375 */
375int pci_register_driver(struct pci_driver *drv) 376int __pci_register_driver(struct pci_driver *drv, struct module *owner)
376{ 377{
377 int error; 378 int error;
378 379
@@ -389,7 +390,7 @@ int pci_register_driver(struct pci_driver *drv)
389 printk(KERN_WARNING "Warning: PCI driver %s has a struct " 390 printk(KERN_WARNING "Warning: PCI driver %s has a struct "
390 "device_driver shutdown method, please update!\n", 391 "device_driver shutdown method, please update!\n",
391 drv->name); 392 drv->name);
392 drv->driver.owner = drv->owner; 393 drv->driver.owner = owner;
393 drv->driver.kobj.ktype = &pci_driver_kobj_type; 394 drv->driver.kobj.ktype = &pci_driver_kobj_type;
394 395
395 spin_lock_init(&drv->dynids.lock); 396 spin_lock_init(&drv->dynids.lock);
@@ -526,7 +527,7 @@ postcore_initcall(pci_driver_init);
526 527
527EXPORT_SYMBOL(pci_match_id); 528EXPORT_SYMBOL(pci_match_id);
528EXPORT_SYMBOL(pci_match_device); 529EXPORT_SYMBOL(pci_match_device);
529EXPORT_SYMBOL(pci_register_driver); 530EXPORT_SYMBOL(__pci_register_driver);
530EXPORT_SYMBOL(pci_unregister_driver); 531EXPORT_SYMBOL(pci_unregister_driver);
531EXPORT_SYMBOL(pci_dev_driver); 532EXPORT_SYMBOL(pci_dev_driver);
532EXPORT_SYMBOL(pci_bus_type); 533EXPORT_SYMBOL(pci_bus_type);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e74d75843047..8e287a828d5d 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -63,11 +63,38 @@ pci_max_busnr(void)
63 return max; 63 return max;
64} 64}
65 65
66static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
67{
68 u8 id;
69 int ttl = 48;
70
71 while (ttl--) {
72 pci_bus_read_config_byte(bus, devfn, pos, &pos);
73 if (pos < 0x40)
74 break;
75 pos &= ~3;
76 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
77 &id);
78 if (id == 0xff)
79 break;
80 if (id == cap)
81 return pos;
82 pos += PCI_CAP_LIST_NEXT;
83 }
84 return 0;
85}
86
87int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
88{
89 return __pci_find_next_cap(dev->bus, dev->devfn,
90 pos + PCI_CAP_LIST_NEXT, cap);
91}
92EXPORT_SYMBOL_GPL(pci_find_next_capability);
93
66static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap) 94static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
67{ 95{
68 u16 status; 96 u16 status;
69 u8 pos, id; 97 u8 pos;
70 int ttl = 48;
71 98
72 pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); 99 pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
73 if (!(status & PCI_STATUS_CAP_LIST)) 100 if (!(status & PCI_STATUS_CAP_LIST))
@@ -76,24 +103,15 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
76 switch (hdr_type) { 103 switch (hdr_type) {
77 case PCI_HEADER_TYPE_NORMAL: 104 case PCI_HEADER_TYPE_NORMAL:
78 case PCI_HEADER_TYPE_BRIDGE: 105 case PCI_HEADER_TYPE_BRIDGE:
79 pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos); 106 pos = PCI_CAPABILITY_LIST;
80 break; 107 break;
81 case PCI_HEADER_TYPE_CARDBUS: 108 case PCI_HEADER_TYPE_CARDBUS:
82 pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos); 109 pos = PCI_CB_CAPABILITY_LIST;
83 break; 110 break;
84 default: 111 default:
85 return 0; 112 return 0;
86 } 113 }
87 while (ttl-- && pos >= 0x40) { 114 return __pci_find_next_cap(bus, devfn, pos, cap);
88 pos &= ~3;
89 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
90 if (id == 0xff)
91 break;
92 if (id == cap)
93 return pos;
94 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
95 }
96 return 0;
97} 115}
98 116
99/** 117/**
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 5627ce1d2b32..3a4f49f4effb 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -462,11 +462,11 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
462 462
463 pci_read_config_word(dev, 0x70, &hm); 463 pci_read_config_word(dev, 0x70, &hm);
464 hm &= PCI_BASE_ADDRESS_IO_MASK; 464 hm &= PCI_BASE_ADDRESS_IO_MASK;
465 quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c868 HW-mon"); 465 quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon");
466 466
467 pci_read_config_dword(dev, 0x90, &smb); 467 pci_read_config_dword(dev, 0x90, &smb);
468 smb &= PCI_BASE_ADDRESS_IO_MASK; 468 smb &= PCI_BASE_ADDRESS_IO_MASK;
469 quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c868 SMB"); 469 quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB");
470} 470}
471DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi ); 471DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi );
472 472
@@ -1243,6 +1243,21 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
1243} 1243}
1244DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); 1244DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
1245 1245
1246
1247static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
1248{
1249 /* rev 1 ncr53c810 chips don't set the class at all which means
1250 * they don't get their resources remapped. Fix that here.
1251 */
1252
1253 if (dev->class == PCI_CLASS_NOT_DEFINED) {
1254 printk(KERN_INFO "NCR 53c810 rev 1 detected, setting PCI class.\n");
1255 dev->class = PCI_CLASS_STORAGE_SCSI;
1256 }
1257}
1258DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
1259
1260
1246static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) 1261static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
1247{ 1262{
1248 while (f < end) { 1263 while (f < end) {
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index ccf20039e909..309eb557f9a3 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -156,7 +156,7 @@ config TCIC
156 156
157config PCMCIA_M8XX 157config PCMCIA_M8XX
158 tristate "MPC8xx PCMCIA support" 158 tristate "MPC8xx PCMCIA support"
159 depends on PCMCIA && PPC 159 depends on PCMCIA && PPC && 8xx
160 select PCCARD_NONSTATIC 160 select PCCARD_NONSTATIC
161 help 161 help
162 Say Y here to include support for PowerPC 8xx series PCMCIA 162 Say Y here to include support for PowerPC 8xx series PCMCIA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index fe37541abbfe..bcecf5133b7e 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_PD6729) += pd6729.o
25obj-$(CONFIG_I82365) += i82365.o 25obj-$(CONFIG_I82365) += i82365.o
26obj-$(CONFIG_I82092) += i82092.o 26obj-$(CONFIG_I82092) += i82092.o
27obj-$(CONFIG_TCIC) += tcic.o 27obj-$(CONFIG_TCIC) += tcic.o
28obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o 28obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
29obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o 29obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
30obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o 30obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
31obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o 31obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
@@ -47,10 +47,10 @@ au1x00_ss-$(CONFIG_MIPS_PB1200) += au1000_db1x00.o
47au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o 47au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o
48au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o 48au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o
49au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o 49au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o
50au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o 50au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o
51au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o 51au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o
52au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o 52au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o
53au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o 53au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o
54 54
55sa1111_cs-y += sa1111_generic.o 55sa1111_cs-y += sa1111_generic.o
56sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o 56sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
index 24cfee1a412c..abc13f28ba3f 100644
--- a/drivers/pcmcia/au1000_db1x00.c
+++ b/drivers/pcmcia/au1000_db1x00.c
@@ -30,6 +30,7 @@
30 * 30 *
31 */ 31 */
32 32
33#include <linux/config.h>
33#include <linux/module.h> 34#include <linux/module.h>
34#include <linux/kernel.h> 35#include <linux/kernel.h>
35#include <linux/errno.h> 36#include <linux/errno.h>
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index b0e7908392a7..f2c970b5f4ff 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -22,6 +22,8 @@
22#define __ASM_AU1000_PCMCIA_H 22#define __ASM_AU1000_PCMCIA_H
23 23
24/* include the world */ 24/* include the world */
25#include <linux/config.h>
26
25#include <pcmcia/cs_types.h> 27#include <pcmcia/cs_types.h>
26#include <pcmcia/cs.h> 28#include <pcmcia/cs.h>
27#include <pcmcia/ss.h> 29#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index d414a3bb50b9..fd5522ede867 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -21,6 +21,7 @@
21 * with this program; if not, write to the Free Software Foundation, Inc., 21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 22 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 */ 23 */
24#include <linux/config.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/init.h> 26#include <linux/init.h>
26#include <linux/delay.h> 27#include <linux/delay.h>
@@ -30,7 +31,6 @@
30#include <linux/timer.h> 31#include <linux/timer.h>
31#include <linux/mm.h> 32#include <linux/mm.h>
32#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
33#include <linux/version.h>
34#include <linux/types.h> 34#include <linux/types.h>
35 35
36#include <pcmcia/cs_types.h> 36#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index f113b69d699b..01874b0bb03b 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -27,7 +27,6 @@
27 */ 27 */
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/config.h>
31#include <linux/delay.h> 30#include <linux/delay.h>
32#include <linux/ioport.h> 31#include <linux/ioport.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
@@ -35,7 +34,6 @@
35#include <linux/timer.h> 34#include <linux/timer.h>
36#include <linux/mm.h> 35#include <linux/mm.h>
37#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
38#include <linux/version.h>
39#include <linux/types.h> 37#include <linux/types.h>
40 38
41#include <pcmcia/cs_types.h> 39#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 7ce455d01cc9..4ddd76239b34 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1366,6 +1366,7 @@ static int __init init_i82365(void)
1366 if (sockets == 0) { 1366 if (sockets == 0) {
1367 printk("not found.\n"); 1367 printk("not found.\n");
1368 platform_device_unregister(&i82365_device); 1368 platform_device_unregister(&i82365_device);
1369 release_region(i365_base, 2);
1369 driver_unregister(&i82365_driver); 1370 driver_unregister(&i82365_driver);
1370 return -ENODEV; 1371 return -ENODEV;
1371 } 1372 }
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index f8bed87cf2f1..6d9f71cfcb34 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -39,7 +39,6 @@
39 39
40#include <asm/io.h> 40#include <asm/io.h>
41#include <asm/bitops.h> 41#include <asm/bitops.h>
42#include <asm/segment.h>
43#include <asm/system.h> 42#include <asm/system.h>
44 43
45#include <linux/kernel.h> 44#include <linux/kernel.h>
@@ -50,6 +49,7 @@
50#include <linux/ioport.h> 49#include <linux/ioport.h>
51#include <linux/delay.h> 50#include <linux/delay.h>
52#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/platform_device.h>
53 53
54#include <asm/mpc8xx.h> 54#include <asm/mpc8xx.h>
55#include <asm/8xx_immap.h> 55#include <asm/8xx_immap.h>
@@ -546,29 +546,11 @@ static void m8xx_shutdown(void)
546 free_irq(pcmcia_schlvl, NULL); 546 free_irq(pcmcia_schlvl, NULL);
547} 547}
548 548
549/* copied from tcic.c */
550
551static int m8xx_drv_suspend(struct device *dev, pm_message_t state, u32 level)
552{
553 int ret = 0;
554 if (level == SUSPEND_SAVE_STATE)
555 ret = pcmcia_socket_dev_suspend(dev, state);
556 return ret;
557}
558
559static int m8xx_drv_resume(struct device *dev, u32 level)
560{
561 int ret = 0;
562 if (level == RESUME_RESTORE_STATE)
563 ret = pcmcia_socket_dev_resume(dev);
564 return ret;
565}
566
567static struct device_driver m8xx_driver = { 549static struct device_driver m8xx_driver = {
568 .name = "m8xx-pcmcia", 550 .name = "m8xx-pcmcia",
569 .bus = &platform_bus_type, 551 .bus = &platform_bus_type,
570 .suspend = m8xx_drv_suspend, 552 .suspend = pcmcia_socket_dev_suspend,
571 .resume = m8xx_drv_resume, 553 .resume = pcmcia_socket_dev_resume,
572}; 554};
573 555
574static struct platform_device m8xx_device = { 556static struct platform_device m8xx_device = {
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 3b4da5a9cf79..f7bf45c6bf0d 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -41,14 +41,14 @@ int kbd_ioctl(struct kbd_data *, struct file *, unsigned int, unsigned long);
41/* 41/*
42 * Helper Functions. 42 * Helper Functions.
43 */ 43 */
44extern inline void 44static inline void
45kbd_put_queue(struct tty_struct *tty, int ch) 45kbd_put_queue(struct tty_struct *tty, int ch)
46{ 46{
47 tty_insert_flip_char(tty, ch, 0); 47 tty_insert_flip_char(tty, ch, 0);
48 tty_schedule_flip(tty); 48 tty_schedule_flip(tty);
49} 49}
50 50
51extern inline void 51static inline void
52kbd_puts_queue(struct tty_struct *tty, char *cp) 52kbd_puts_queue(struct tty_struct *tty, char *cp)
53{ 53{
54 while (*cp) 54 while (*cp)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 6b8aa6a852be..328e31cc6854 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -265,7 +265,7 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
265/* 265/*
266 * Some instructions as assembly 266 * Some instructions as assembly
267 */ 267 */
268extern __inline__ int 268static inline int
269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) 269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
270{ 270{
271 int cc; 271 int cc;
@@ -300,7 +300,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
300 return cc; 300 return cc;
301} 301}
302 302
303extern __inline__ int 303static inline int
304do_siga_input(unsigned int irq, unsigned int mask) 304do_siga_input(unsigned int irq, unsigned int mask)
305{ 305{
306 int cc; 306 int cc;
@@ -334,7 +334,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
334 return cc; 334 return cc;
335} 335}
336 336
337extern __inline__ int 337static inline int
338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) 338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
339{ 339{
340 int cc; 340 int cc;
@@ -401,7 +401,7 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
401 return cc; 401 return cc;
402} 402}
403 403
404extern __inline__ unsigned long 404static inline unsigned long
405do_clear_global_summary(void) 405do_clear_global_summary(void)
406{ 406{
407 407
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 04c2ef778ec6..4010f2bb85af 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -37,7 +37,6 @@
37#include <linux/kobject_uevent.h> 37#include <linux/kobject_uevent.h>
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/syscalls.h> 39#include <linux/syscalls.h>
40#include <linux/version.h>
41#include "z90crypt.h" 40#include "z90crypt.h"
42#include "z90common.h" 41#include "z90common.h"
43 42
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 1a1c3decea72..6b63d21612ec 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -88,7 +88,6 @@
88#include <linux/tcp.h> 88#include <linux/tcp.h>
89#include <linux/timer.h> 89#include <linux/timer.h>
90#include <linux/types.h> 90#include <linux/types.h>
91#include <linux/version.h>
92 91
93#include "cu3088.h" 92#include "cu3088.h"
94#include "claw.h" 93#include "claw.h"
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index 1b8a7e7c34f3..5b98253be7aa 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -140,7 +140,7 @@ fsm_record_history(fsm_instance *fi, int state, int event);
140 * 1 if current state or event is out of range 140 * 1 if current state or event is out of range
141 * !0 if state and event in range, but no action defined. 141 * !0 if state and event in range, but no action defined.
142 */ 142 */
143extern __inline__ int 143static inline int
144fsm_event(fsm_instance *fi, int event, void *arg) 144fsm_event(fsm_instance *fi, int event, void *arg)
145{ 145{
146 fsm_function_t r; 146 fsm_function_t r;
@@ -188,7 +188,7 @@ fsm_event(fsm_instance *fi, int event, void *arg)
188 * @param fi Pointer to FSM 188 * @param fi Pointer to FSM
189 * @param state The new state for this FSM. 189 * @param state The new state for this FSM.
190 */ 190 */
191extern __inline__ void 191static inline void
192fsm_newstate(fsm_instance *fi, int newstate) 192fsm_newstate(fsm_instance *fi, int newstate)
193{ 193{
194 atomic_set(&fi->state,newstate); 194 atomic_set(&fi->state,newstate);
@@ -208,7 +208,7 @@ fsm_newstate(fsm_instance *fi, int newstate)
208 * 208 *
209 * @return The current state of the FSM. 209 * @return The current state of the FSM.
210 */ 210 */
211extern __inline__ int 211static inline int
212fsm_getstate(fsm_instance *fi) 212fsm_getstate(fsm_instance *fi)
213{ 213{
214 return atomic_read(&fi->state); 214 return atomic_read(&fi->state);
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index 4eaa70179182..d9ea7ed2e46e 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -88,7 +88,7 @@ struct crw {
88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ 88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */ 89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
90 90
91extern __inline__ int stcrw(struct crw *pcrw ) 91static inline int stcrw(struct crw *pcrw )
92{ 92{
93 int ccode; 93 int ccode;
94 94
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index 071ae24be892..fd2cc7782f76 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -407,7 +407,7 @@ static long wd_compat_ioctl(struct file *file, unsigned int cmd,
407 case WIOCGSTAT: 407 case WIOCGSTAT:
408 lock_kernel(); 408 lock_kernel();
409 rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg); 409 rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg);
410 lock_kernel(); 410 unlock_kernel();
411 break; 411 break;
412 /* everything else is handled by the generic compat layer */ 412 /* everything else is handled by the generic compat layer */
413 default: 413 default:
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 39f54213a6d5..c3a51d1fae5d 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -119,7 +119,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
119{ 119{
120 __u8 regs = readb(d7s_regs); 120 __u8 regs = readb(d7s_regs);
121 __u8 ireg = 0; 121 __u8 ireg = 0;
122 int error = 0 122 int error = 0;
123 123
124 if (D7S_MINOR != iminor(file->f_dentry->d_inode)) 124 if (D7S_MINOR != iminor(file->f_dentry->d_inode))
125 return -ENODEV; 125 return -ENODEV;
@@ -161,7 +161,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
161 writeb(regs, d7s_regs); 161 writeb(regs, d7s_regs);
162 break; 162 break;
163 }; 163 };
164 lock_kernel(); 164 unlock_kernel();
165 165
166 return error; 166 return error;
167} 167}
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 9b988baf0b51..5774bdd0e26f 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -210,6 +210,27 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
210 } 210 }
211} 211}
212 212
213static long rtc_compat_ioctl(struct file *file, unsigned int cmd,
214 unsigned long arg)
215{
216 int rval = -ENOIOCTLCMD;
217
218 switch (cmd) {
219 /*
220 * These two are specific to this driver, the generic rtc ioctls
221 * are hanlded elsewhere.
222 */
223 case RTCGET:
224 case RTCSET:
225 lock_kernel();
226 rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
227 unlock_kernel();
228 break;
229 }
230
231 return rval;
232}
233
213static int rtc_open(struct inode *inode, struct file *file) 234static int rtc_open(struct inode *inode, struct file *file)
214{ 235{
215 int ret; 236 int ret;
@@ -237,6 +258,7 @@ static struct file_operations rtc_fops = {
237 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
238 .llseek = no_llseek, 259 .llseek = no_llseek,
239 .ioctl = rtc_ioctl, 260 .ioctl = rtc_ioctl,
261 .compat_ioctl = rtc_compat_ioctl,
240 .open = rtc_open, 262 .open = rtc_open,
241 .release = rtc_release, 263 .release = rtc_release,
242}; 264};
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 98bad773f240..4f81fc39ec57 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -54,7 +54,6 @@
54#ifndef _3W_XXXX_H 54#ifndef _3W_XXXX_H
55#define _3W_XXXX_H 55#define _3W_XXXX_H
56 56
57#include <linux/version.h>
58#include <linux/types.h> 57#include <linux/types.h>
59 58
60/* AEN strings */ 59/* AEN strings */
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index f7a1751e892d..30a14ba77a6a 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 4612312c0c2d..10c470e7d316 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -42,8 +42,8 @@
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/dma-mapping.h> 43#include <linux/dma-mapping.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
46#include <scsi/scsi_cmnd.h>
47#include <linux/libata.h> 47#include <linux/libata.h>
48#include <asm/io.h> 48#include <asm/io.h>
49 49
@@ -196,7 +196,7 @@ static u8 ahci_check_status(struct ata_port *ap);
196static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); 196static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
197static void ahci_remove_one (struct pci_dev *pdev); 197static void ahci_remove_one (struct pci_dev *pdev);
198 198
199static Scsi_Host_Template ahci_sht = { 199static struct scsi_host_template ahci_sht = {
200 .module = THIS_MODULE, 200 .module = THIS_MODULE,
201 .name = DRV_NAME, 201 .name = DRV_NAME,
202 .ioctl = ata_scsi_ioctl, 202 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 052c6619accc..bc44222d6cc3 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -49,7 +49,6 @@
49#include <linux/ioport.h> 49#include <linux/ioport.h>
50#include <linux/pci.h> 50#include <linux/pci.h>
51#include <linux/smp_lock.h> 51#include <linux/smp_lock.h>
52#include <linux/version.h>
53#include <linux/interrupt.h> 52#include <linux/interrupt.h>
54#include <linux/module.h> 53#include <linux/module.h>
55#include <linux/slab.h> 54#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index be9edbe26dbe..f2a95447142c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -66,7 +66,6 @@
66#include <linux/ioport.h> 66#include <linux/ioport.h>
67#include <linux/pci.h> 67#include <linux/pci.h>
68#include <linux/smp_lock.h> 68#include <linux/smp_lock.h>
69#include <linux/version.h>
70#include <linux/interrupt.h> 69#include <linux/interrupt.h>
71#include <linux/module.h> 70#include <linux/module.h>
72#include <linux/slab.h> 71#include <linux/slab.h>
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index 5f13546d6392..dea8446f5360 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -11,7 +11,6 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/version.h>
15#include <linux/config.h> 14#include <linux/config.h>
16#include <linux/zorro.h> 15#include <linux/zorro.h>
17#include <linux/stat.h> 16#include <linux/stat.h>
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 7f8aa1b552ce..a1bd8d95623c 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -46,7 +46,6 @@
46#include <linux/blkdev.h> 46#include <linux/blkdev.h>
47#include <linux/delay.h> 47#include <linux/delay.h>
48#include <linux/device.h> 48#include <linux/device.h>
49#include "scsi.h"
50#include <scsi/scsi_host.h> 49#include <scsi/scsi_host.h>
51#include <linux/libata.h> 50#include <linux/libata.h>
52 51
@@ -128,7 +127,7 @@ static struct pci_driver piix_pci_driver = {
128 .remove = ata_pci_remove_one, 127 .remove = ata_pci_remove_one,
129}; 128};
130 129
131static Scsi_Host_Template piix_sht = { 130static struct scsi_host_template piix_sht = {
132 .module = THIS_MODULE, 131 .module = THIS_MODULE,
133 .name = DRV_NAME, 132 .name = DRV_NAME,
134 .ioctl = ata_scsi_ioctl, 133 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
index 29c7ed30c09e..130f30f51a9b 100644
--- a/drivers/scsi/bvme6000.c
+++ b/drivers/scsi/bvme6000.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11#include <linux/zorro.h> 10#include <linux/zorro.h>
12 11
13#include <asm/setup.h> 12#include <asm/setup.h>
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index d12342fa8199..ab22387c9df1 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 887a5c3ded28..8d97999db60e 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -18,12 +18,6 @@
18 */ 18 */
19 19
20#include <linux/config.h> 20#include <linux/config.h>
21#ifndef LINUX_VERSION_CODE
22#include <linux/version.h>
23#endif
24#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
25#error "This driver works only with kernel 2.5.45 or higher!"
26#endif
27#include <linux/module.h> 21#include <linux/module.h>
28#include <linux/kernel.h> 22#include <linux/kernel.h>
29#include <linux/types.h> 23#include <linux/types.h>
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index c888af4a4562..3553da0e1cd5 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -395,6 +395,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
395 int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); 395 int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
396 struct Scsi_Host *host; 396 struct Scsi_Host *host;
397 u8 *scsi_buf; 397 u8 *scsi_buf;
398 int errors = rq->errors;
398 unsigned long flags; 399 unsigned long flags;
399 400
400 if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) { 401 if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) {
@@ -421,11 +422,11 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
421 printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n", 422 printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n",
422 drive->name, pc->scsi_cmd->serial_number); 423 drive->name, pc->scsi_cmd->serial_number);
423 pc->scsi_cmd->result = DID_TIME_OUT << 16; 424 pc->scsi_cmd->result = DID_TIME_OUT << 16;
424 } else if (rq->errors >= ERROR_MAX) { 425 } else if (errors >= ERROR_MAX) {
425 pc->scsi_cmd->result = DID_ERROR << 16; 426 pc->scsi_cmd->result = DID_ERROR << 16;
426 if (log) 427 if (log)
427 printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number); 428 printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);
428 } else if (rq->errors) { 429 } else if (errors) {
429 if (log) 430 if (log)
430 printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number); 431 printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
431 if (!idescsi_check_condition(drive, rq)) 432 if (!idescsi_check_condition(drive, rq))
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 505e967013de..adc6eabbf610 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -50,6 +50,7 @@
50#ifndef _IPS_H_ 50#ifndef _IPS_H_
51 #define _IPS_H_ 51 #define _IPS_H_
52 52
53#include <linux/version.h>
53 #include <asm/uaccess.h> 54 #include <asm/uaccess.h>
54 #include <asm/io.h> 55 #include <asm/io.h>
55 56
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 1c1a7caf785e..a74b4071a662 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -51,8 +51,8 @@
51#include <linux/jiffies.h> 51#include <linux/jiffies.h>
52#include <linux/scatterlist.h> 52#include <linux/scatterlist.h>
53#include <scsi/scsi.h> 53#include <scsi/scsi.h>
54#include "scsi.h"
55#include "scsi_priv.h" 54#include "scsi_priv.h"
55#include <scsi/scsi_cmnd.h>
56#include <scsi/scsi_host.h> 56#include <scsi/scsi_host.h>
57#include <linux/libata.h> 57#include <linux/libata.h>
58#include <asm/io.h> 58#include <asm/io.h>
@@ -1144,7 +1144,7 @@ retry:
1144 * ATA software reset (SRST, the default) does not appear 1144 * ATA software reset (SRST, the default) does not appear
1145 * to have this problem. 1145 * to have this problem.
1146 */ 1146 */
1147 if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) { 1147 if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
1148 u8 err = qc->tf.feature; 1148 u8 err = qc->tf.feature;
1149 if (err & ATA_ABORTED) { 1149 if (err & ATA_ABORTED) {
1150 dev->class = ATA_DEV_ATAPI; 1150 dev->class = ATA_DEV_ATAPI;
@@ -2713,7 +2713,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
2713/** 2713/**
2714 * ata_poll_qc_complete - turn irq back on and finish qc 2714 * ata_poll_qc_complete - turn irq back on and finish qc
2715 * @qc: Command to complete 2715 * @qc: Command to complete
2716 * @drv_stat: ATA status register content 2716 * @err_mask: ATA status register content
2717 * 2717 *
2718 * LOCKING: 2718 * LOCKING:
2719 * None. (grabs host lock) 2719 * None. (grabs host lock)
@@ -2747,7 +2747,6 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2747 u8 status; 2747 u8 status;
2748 unsigned int poll_state = HSM_ST_UNKNOWN; 2748 unsigned int poll_state = HSM_ST_UNKNOWN;
2749 unsigned int reg_state = HSM_ST_UNKNOWN; 2749 unsigned int reg_state = HSM_ST_UNKNOWN;
2750 const unsigned int tmout_state = HSM_ST_TMOUT;
2751 2750
2752 switch (ap->hsm_task_state) { 2751 switch (ap->hsm_task_state) {
2753 case HSM_ST: 2752 case HSM_ST:
@@ -2768,7 +2767,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2768 status = ata_chk_status(ap); 2767 status = ata_chk_status(ap);
2769 if (status & ATA_BUSY) { 2768 if (status & ATA_BUSY) {
2770 if (time_after(jiffies, ap->pio_task_timeout)) { 2769 if (time_after(jiffies, ap->pio_task_timeout)) {
2771 ap->hsm_task_state = tmout_state; 2770 ap->hsm_task_state = HSM_ST_TMOUT;
2772 return 0; 2771 return 0;
2773 } 2772 }
2774 ap->hsm_task_state = poll_state; 2773 ap->hsm_task_state = poll_state;
@@ -3478,7 +3477,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
3478/** 3477/**
3479 * ata_qc_complete - Complete an active ATA command 3478 * ata_qc_complete - Complete an active ATA command
3480 * @qc: Command to complete 3479 * @qc: Command to complete
3481 * @drv_stat: ATA Status register contents 3480 * @err_mask: ATA Status register contents
3482 * 3481 *
3483 * Indicate to the mid and upper layers that an ATA 3482 * Indicate to the mid and upper layers that an ATA
3484 * command has completed, with either an ok or not-ok status. 3483 * command has completed, with either an ok or not-ok status.
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index eb604b0a8990..bb30fcdc9297 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -37,9 +37,9 @@
37#include <linux/blkdev.h> 37#include <linux/blkdev.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <scsi/scsi.h> 39#include <scsi/scsi.h>
40#include "scsi.h"
41#include <scsi/scsi_host.h> 40#include <scsi/scsi_host.h>
42#include <scsi/scsi_device.h> 41#include <scsi/scsi_device.h>
42#include <scsi/scsi_request.h>
43#include <linux/libata.h> 43#include <linux/libata.h>
44#include <linux/hdreg.h> 44#include <linux/hdreg.h>
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -131,7 +131,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
131 131
132/** 132/**
133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl 133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
134 * @dev: Device to whom we are issuing command 134 * @scsidev: Device to which we are issuing command
135 * @arg: User provided data for issuing command 135 * @arg: User provided data for issuing command
136 * 136 *
137 * LOCKING: 137 * LOCKING:
@@ -217,7 +217,7 @@ error:
217 217
218/** 218/**
219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl 219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
220 * @dev: Device to whom we are issuing command 220 * @scsidev: Device to which we are issuing command
221 * @arg: User provided data for issuing command 221 * @arg: User provided data for issuing command
222 * 222 *
223 * LOCKING: 223 * LOCKING:
@@ -416,6 +416,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
416 416
417/** 417/**
418 * ata_to_sense_error - convert ATA error to SCSI error 418 * ata_to_sense_error - convert ATA error to SCSI error
419 * @id: ATA device number
419 * @drv_stat: value contained in ATA status register 420 * @drv_stat: value contained in ATA status register
420 * @drv_err: value contained in ATA error register 421 * @drv_err: value contained in ATA error register
421 * @sk: the sense key we'll fill out 422 * @sk: the sense key we'll fill out
@@ -2231,7 +2232,7 @@ ata_scsi_map_proto(u8 byte1)
2231/** 2232/**
2232 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile 2233 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
2233 * @qc: command structure to be initialized 2234 * @qc: command structure to be initialized
2234 * @cmd: SCSI command to convert 2235 * @scsicmd: SCSI command to convert
2235 * 2236 *
2236 * Handles either 12 or 16-byte versions of the CDB. 2237 * Handles either 12 or 16-byte versions of the CDB.
2237 * 2238 *
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index c90723860a04..07498118359d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1704,7 +1704,6 @@ MODULE_DEVICE_TABLE(pci, lpfc_id_table);
1704 1704
1705static struct pci_driver lpfc_driver = { 1705static struct pci_driver lpfc_driver = {
1706 .name = LPFC_DRIVER_NAME, 1706 .name = LPFC_DRIVER_NAME,
1707 .owner = THIS_MODULE,
1708 .id_table = lpfc_id_table, 1707 .id_table = lpfc_id_table,
1709 .probe = lpfc_pci_probe_one, 1708 .probe = lpfc_pci_probe_one,
1710 .remove = __devexit_p(lpfc_pci_remove_one), 1709 .remove = __devexit_p(lpfc_pci_remove_one),
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 69df1a9b935d..8e547130e97d 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -25,7 +25,6 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/blkdev.h> 26#include <linux/blkdev.h>
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/version.h>
29#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
30#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
31#include <asm/semaphore.h> 30#include <asm/semaphore.h>
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h
index 7e36c46e7c43..eb8c390a0fa3 100644
--- a/drivers/scsi/megaraid/megaraid_mm.h
+++ b/drivers/scsi/megaraid/megaraid_mm.h
@@ -18,7 +18,6 @@
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/moduleparam.h> 22#include <linux/moduleparam.h>
24#include <linux/pci.h> 23#include <linux/pci.h>
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 4245d05e628b..801a63bea8a5 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/version.h>
30#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/spinlock.h> 31#include <linux/spinlock.h>
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index 2fb31ee6d9f5..33380cee9b77 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/interrupt.h> 5#include <linux/interrupt.h>
7 6
8#include <asm/page.h> 7#include <asm/page.h>
diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
index b2d8d8ea1604..29ec699e0e4d 100644
--- a/drivers/scsi/mvme16x.c
+++ b/drivers/scsi/mvme16x.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11 10
12#include <asm/page.h> 11#include <asm/page.h>
13#include <asm/pgtable.h> 12#include <asm/pgtable.h>
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index 5664398fa0ad..5addf9fb1e15 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -16,6 +16,7 @@
16#ifndef _NSP32_H 16#ifndef _NSP32_H
17#define _NSP32_H 17#define _NSP32_H
18 18
19#include <linux/version.h>
19//#define NSP32_DEBUG 9 20//#define NSP32_DEBUG 9
20 21
21/* 22/*
diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
index c65afc964121..6c962d7dca47 100644
--- a/drivers/scsi/pci2000.h
+++ b/drivers/scsi/pci2000.h
@@ -26,9 +26,6 @@
26#ifndef PSI_EIDE_SCSIOP 26#ifndef PSI_EIDE_SCSIOP
27#define PSI_EIDE_SCSIOP 1 27#define PSI_EIDE_SCSIOP 1
28 28
29#ifndef LINUX_VERSION_CODE
30#include <linux/version.h>
31#endif
32#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s)) 29#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
33 30
34/************************************************/ 31/************************************************/
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index a50588c60fab..78b4ff117af6 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -41,7 +41,6 @@
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/device.h> 43#include <linux/device.h>
44#include "scsi.h"
45#include <scsi/scsi_host.h> 44#include <scsi/scsi_host.h>
46#include <asm/io.h> 45#include <asm/io.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
@@ -139,7 +138,7 @@ static u8 adma_bmdma_status(struct ata_port *ap);
139static void adma_irq_clear(struct ata_port *ap); 138static void adma_irq_clear(struct ata_port *ap);
140static void adma_eng_timeout(struct ata_port *ap); 139static void adma_eng_timeout(struct ata_port *ap);
141 140
142static Scsi_Host_Template adma_ata_sht = { 141static struct scsi_host_template adma_ata_sht = {
143 .module = THIS_MODULE, 142 .module = THIS_MODULE,
144 .name = DRV_NAME, 143 .name = DRV_NAME,
145 .ioctl = ata_scsi_ioctl, 144 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 0f469e3dabe2..93d55233af7b 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -30,8 +30,8 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include "scsi.h"
34#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
34#include <scsi/scsi_cmnd.h>
35#include <linux/libata.h> 35#include <linux/libata.h>
36#include <asm/io.h> 36#include <asm/io.h>
37 37
@@ -270,7 +270,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
270static void mv_eng_timeout(struct ata_port *ap); 270static void mv_eng_timeout(struct ata_port *ap);
271static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 271static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
272 272
273static Scsi_Host_Template mv_sht = { 273static struct scsi_host_template mv_sht = {
274 .module = THIS_MODULE, 274 .module = THIS_MODULE,
275 .name = DRV_NAME, 275 .name = DRV_NAME,
276 .ioctl = ata_scsi_ioctl, 276 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index d573888eda76..37a4fae95ed4 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -62,7 +62,6 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/device.h> 64#include <linux/device.h>
65#include "scsi.h"
66#include <scsi/scsi_host.h> 65#include <scsi/scsi_host.h>
67#include <linux/libata.h> 66#include <linux/libata.h>
68 67
@@ -219,7 +218,7 @@ static struct pci_driver nv_pci_driver = {
219 .remove = ata_pci_remove_one, 218 .remove = ata_pci_remove_one,
220}; 219};
221 220
222static Scsi_Host_Template nv_sht = { 221static struct scsi_host_template nv_sht = {
223 .module = THIS_MODULE, 222 .module = THIS_MODULE,
224 .name = DRV_NAME, 223 .name = DRV_NAME,
225 .ioctl = ata_scsi_ioctl, 224 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index b41c977d6fab..9edc9d91efc3 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
@@ -94,7 +94,7 @@ static void pdc_irq_clear(struct ata_port *ap);
94static int pdc_qc_issue_prot(struct ata_queued_cmd *qc); 94static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
95 95
96 96
97static Scsi_Host_Template pdc_ata_sht = { 97static struct scsi_host_template pdc_ata_sht = {
98 .module = THIS_MODULE, 98 .module = THIS_MODULE,
99 .name = DRV_NAME, 99 .name = DRV_NAME,
100 .ioctl = ata_scsi_ioctl, 100 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 65502c157a54..d274ab235781 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -36,7 +36,6 @@
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include "scsi.h"
40#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
41#include <asm/io.h> 40#include <asm/io.h>
42#include <linux/libata.h> 41#include <linux/libata.h>
@@ -128,7 +127,7 @@ static u8 qs_bmdma_status(struct ata_port *ap);
128static void qs_irq_clear(struct ata_port *ap); 127static void qs_irq_clear(struct ata_port *ap);
129static void qs_eng_timeout(struct ata_port *ap); 128static void qs_eng_timeout(struct ata_port *ap);
130 129
131static Scsi_Host_Template qs_ata_sht = { 130static struct scsi_host_template qs_ata_sht = {
132 .module = THIS_MODULE, 131 .module = THIS_MODULE,
133 .name = DRV_NAME, 132 .name = DRV_NAME,
134 .ioctl = ata_scsi_ioctl, 133 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 435f7e0085ec..d0e3c3c6c25f 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -42,7 +42,6 @@
42#include <linux/delay.h> 42#include <linux/delay.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48 47
@@ -131,7 +130,7 @@ static struct pci_driver sil_pci_driver = {
131 .remove = ata_pci_remove_one, 130 .remove = ata_pci_remove_one,
132}; 131};
133 132
134static Scsi_Host_Template sil_sht = { 133static struct scsi_host_template sil_sht = {
135 .module = THIS_MODULE, 134 .module = THIS_MODULE,
136 .name = DRV_NAME, 135 .name = DRV_NAME,
137 .ioctl = ata_scsi_ioctl, 136 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index e6c8e89c226f..4682a50650b4 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -37,7 +37,7 @@
37#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
40#include "scsi.h" 40#include <scsi/scsi_cmnd.h>
41#include <linux/libata.h> 41#include <linux/libata.h>
42#include <asm/io.h> 42#include <asm/io.h>
43 43
@@ -255,7 +255,7 @@ static struct pci_driver sil24_pci_driver = {
255 .remove = ata_pci_remove_one, /* safe? */ 255 .remove = ata_pci_remove_one, /* safe? */
256}; 256};
257 257
258static Scsi_Host_Template sil24_sht = { 258static struct scsi_host_template sil24_sht = {
259 .module = THIS_MODULE, 259 .module = THIS_MODULE,
260 .name = DRV_NAME, 260 .name = DRV_NAME,
261 .ioctl = ata_scsi_ioctl, 261 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 42288be0e561..42d7c4e92501 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -39,7 +39,6 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
44#include <linux/libata.h> 43#include <linux/libata.h>
45 44
@@ -83,7 +82,7 @@ static struct pci_driver sis_pci_driver = {
83 .remove = ata_pci_remove_one, 82 .remove = ata_pci_remove_one,
84}; 83};
85 84
86static Scsi_Host_Template sis_sht = { 85static struct scsi_host_template sis_sht = {
87 .module = THIS_MODULE, 86 .module = THIS_MODULE,
88 .name = DRV_NAME, 87 .name = DRV_NAME,
89 .ioctl = ata_scsi_ioctl, 88 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index db615ff794d8..9895d1caefcf 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -45,7 +45,6 @@
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/interrupt.h> 46#include <linux/interrupt.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include "scsi.h"
49#include <scsi/scsi_host.h> 48#include <scsi/scsi_host.h>
50#include <linux/libata.h> 49#include <linux/libata.h>
51 50
@@ -284,7 +283,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
284#endif /* CONFIG_PPC_OF */ 283#endif /* CONFIG_PPC_OF */
285 284
286 285
287static Scsi_Host_Template k2_sata_sht = { 286static struct scsi_host_template k2_sata_sht = {
288 .module = THIS_MODULE, 287 .module = THIS_MODULE,
289 .name = DRV_NAME, 288 .name = DRV_NAME,
290 .ioctl = ata_scsi_ioctl, 289 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index f859bbd681ed..d5a38784352b 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
@@ -177,7 +177,7 @@ static void pdc20621_irq_clear(struct ata_port *ap);
177static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); 177static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
178 178
179 179
180static Scsi_Host_Template pdc_sata_sht = { 180static struct scsi_host_template pdc_sata_sht = {
181 .module = THIS_MODULE, 181 .module = THIS_MODULE,
182 .name = DRV_NAME, 182 .name = DRV_NAME,
183 .ioctl = ata_scsi_ioctl, 183 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index a5e245c098e1..cf0baaa4e045 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -33,7 +33,6 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include "scsi.h"
37#include <scsi/scsi_host.h> 36#include <scsi/scsi_host.h>
38#include <linux/libata.h> 37#include <linux/libata.h>
39 38
@@ -71,7 +70,7 @@ static struct pci_driver uli_pci_driver = {
71 .remove = ata_pci_remove_one, 70 .remove = ata_pci_remove_one,
72}; 71};
73 72
74static Scsi_Host_Template uli_sht = { 73static struct scsi_host_template uli_sht = {
75 .module = THIS_MODULE, 74 .module = THIS_MODULE,
76 .name = DRV_NAME, 75 .name = DRV_NAME,
77 .ioctl = ata_scsi_ioctl, 76 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index b3ecdbe400e9..ab19d2ba2a4b 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -42,7 +42,6 @@
42#include <linux/blkdev.h> 42#include <linux/blkdev.h>
43#include <linux/delay.h> 43#include <linux/delay.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48#include <asm/io.h> 47#include <asm/io.h>
@@ -90,7 +89,7 @@ static struct pci_driver svia_pci_driver = {
90 .remove = ata_pci_remove_one, 89 .remove = ata_pci_remove_one,
91}; 90};
92 91
93static Scsi_Host_Template svia_sht = { 92static struct scsi_host_template svia_sht = {
94 .module = THIS_MODULE, 93 .module = THIS_MODULE,
95 .name = DRV_NAME, 94 .name = DRV_NAME,
96 .ioctl = ata_scsi_ioctl, 95 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index bb84ba0c7e83..ce8a2fd7da84 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -43,7 +43,6 @@
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/dma-mapping.h> 44#include <linux/dma-mapping.h>
45#include <linux/device.h> 45#include <linux/device.h>
46#include "scsi.h"
47#include <scsi/scsi_host.h> 46#include <scsi/scsi_host.h>
48#include <linux/libata.h> 47#include <linux/libata.h>
49 48
@@ -219,7 +218,7 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
219} 218}
220 219
221 220
222static Scsi_Host_Template vsc_sata_sht = { 221static struct scsi_host_template vsc_sata_sht = {
223 .module = THIS_MODULE, 222 .module = THIS_MODULE,
224 .name = DRV_NAME, 223 .name = DRV_NAME,
225 .ioctl = ata_scsi_ioctl, 224 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index aadf051274fa..b61fb1295b8b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -48,10 +48,6 @@
48 48
49#include <linux/stat.h> 49#include <linux/stat.h>
50 50
51#ifndef LINUX_VERSION_CODE
52#include <linux/version.h>
53#endif
54
55#include "scsi_logging.h" 51#include "scsi_logging.h"
56#include "scsi_debug.h" 52#include "scsi_debug.h"
57 53
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 62e3f340cc52..72ec59456e69 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -68,10 +68,6 @@ static int sg_proc_init(void);
68static void sg_proc_cleanup(void); 68static void sg_proc_cleanup(void);
69#endif 69#endif
70 70
71#ifndef LINUX_VERSION_CODE
72#include <linux/version.h>
73#endif /* LINUX_VERSION_CODE */
74
75#define SG_ALLOW_DIO_DEF 0 71#define SG_ALLOW_DIO_DEF 0
76#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */ 72#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
77 73
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index 09fd203e4b86..f37147f8f7bf 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -15,7 +15,6 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/blkdev.h> 17#include <linux/blkdev.h>
18#include <linux/version.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
21#include <linux/spinlock.h> 20#include <linux/spinlock.h>
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 5754445fb36a..fd63add6a577 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -77,7 +77,6 @@
77#include <linux/sched.h> 77#include <linux/sched.h>
78#include <linux/string.h> 78#include <linux/string.h>
79#include <linux/delay.h> 79#include <linux/delay.h>
80#include <linux/version.h>
81#include <linux/init.h> 80#include <linux/init.h>
82#include <linux/blkdev.h> 81#include <linux/blkdev.h>
83#include <asm/irq.h> 82#include <asm/irq.h>
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 51e3f7f6597b..fbea4541c234 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -40,7 +40,6 @@
40 *****************************************************************************/ 40 *****************************************************************************/
41#define IXJ_VERSION 3031 41#define IXJ_VERSION 3031
42 42
43#include <linux/version.h>
44#include <linux/types.h> 43#include <linux/types.h>
45 44
46#include <linux/ixjuser.h> 45#include <linux/ixjuser.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 6b93dbbf3246..1e407745c115 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -49,7 +49,6 @@
49#include <linux/timer.h> 49#include <linux/timer.h>
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/version.h>
53#include <linux/platform_device.h> 52#include <linux/platform_device.h>
54#include <linux/usb.h> 53#include <linux/usb.h>
55#include <linux/usb_gadget.h> 54#include <linux/usb_gadget.h>
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 654469778ab5..b0f3cd63e3b9 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1970,7 +1970,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
1970static struct pci_driver goku_pci_driver = { 1970static struct pci_driver goku_pci_driver = {
1971 .name = (char *) driver_name, 1971 .name = (char *) driver_name,
1972 .id_table = pci_ids, 1972 .id_table = pci_ids,
1973 .owner = THIS_MODULE,
1974 1973
1975 .probe = goku_probe, 1974 .probe = goku_probe,
1976 .remove = goku_remove, 1975 .remove = goku_remove,
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h
index 1bb455c045a9..9b2e6f7cbb8b 100644
--- a/drivers/usb/gadget/lh7a40x_udc.h
+++ b/drivers/usb/gadget/lh7a40x_udc.h
@@ -29,7 +29,6 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/version.h>
33#include <linux/errno.h> 32#include <linux/errno.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
35#include <linux/sched.h> 34#include <linux/sched.h>
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 0dc6bb00bf72..c32e1f7476da 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2948,7 +2948,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
2948static struct pci_driver net2280_pci_driver = { 2948static struct pci_driver net2280_pci_driver = {
2949 .name = (char *) driver_name, 2949 .name = (char *) driver_name,
2950 .id_table = pci_ids, 2950 .id_table = pci_ids,
2951 .owner = THIS_MODULE,
2952 2951
2953 .probe = net2280_probe, 2952 .probe = net2280_probe,
2954 .remove = net2280_remove, 2953 .remove = net2280_remove,
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 91bf18b8191f..bb028c5b8952 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -32,7 +32,6 @@
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/ioport.h> 33#include <linux/ioport.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/version.h>
36#include <linux/errno.h> 35#include <linux/errno.h>
37#include <linux/delay.h> 36#include <linux/delay.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 06b6eba925b5..9689efeb364c 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -28,7 +28,6 @@
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/version.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/list.h> 32#include <linux/list.h>
34#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 145008853966..dfd9bd0b1828 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -383,7 +383,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
383static struct pci_driver ehci_pci_driver = { 383static struct pci_driver ehci_pci_driver = {
384 .name = (char *) hcd_name, 384 .name = (char *) hcd_name,
385 .id_table = pci_ids, 385 .id_table = pci_ids,
386 .owner = THIS_MODULE,
387 386
388 .probe = usb_hcd_pci_probe, 387 .probe = usb_hcd_pci_probe,
389 .remove = usb_hcd_pci_remove, 388 .remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index a8267cf17db4..0eaabeb37ac3 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -14,7 +14,6 @@
14#include <linux/unistd.h> 14#include <linux/unistd.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/list.h> 17#include <linux/list.h>
19#include <linux/spinlock.h> 18#include <linux/spinlock.h>
20 19
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 7ce1d9ef0289..a59e536441e1 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -218,7 +218,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
218static struct pci_driver ohci_pci_driver = { 218static struct pci_driver ohci_pci_driver = {
219 .name = (char *) hcd_name, 219 .name = (char *) hcd_name,
220 .id_table = pci_ids, 220 .id_table = pci_ids,
221 .owner = THIS_MODULE,
222 221
223 .probe = usb_hcd_pci_probe, 222 .probe = usb_hcd_pci_probe,
224 .remove = usb_hcd_pci_remove, 223 .remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 15e0a511069b..d33ce3982a5f 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -831,7 +831,6 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
831static struct pci_driver uhci_pci_driver = { 831static struct pci_driver uhci_pci_driver = {
832 .name = (char *)hcd_name, 832 .name = (char *)hcd_name,
833 .id_table = uhci_pci_ids, 833 .id_table = uhci_pci_ids,
834 .owner = THIS_MODULE,
835 834
836 .probe = usb_hcd_pci_probe, 835 .probe = usb_hcd_pci_probe,
837 .remove = usb_hcd_pci_remove, 836 .remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index b77e65c03659..5524fd70210b 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -62,6 +62,7 @@
62#include <linux/poll.h> 62#include <linux/poll.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/vmalloc.h> 64#include <linux/vmalloc.h>
65#include <linux/version.h>
65#include <asm/io.h> 66#include <asm/io.h>
66 67
67#include "pwc.h" 68#include "pwc.h"
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
index 267869dab185..6dd76bb3dff1 100644
--- a/drivers/usb/media/pwc/pwc.h
+++ b/drivers/usb/media/pwc/pwc.h
@@ -25,8 +25,6 @@
25#ifndef PWC_H 25#ifndef PWC_H
26#define PWC_H 26#define PWC_H
27 27
28#include <linux/version.h>
29
30#include <linux/config.h> 28#include <linux/config.h>
31#include <linux/module.h> 29#include <linux/module.h>
32#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index f36c0b6c6e36..67612c81cb9f 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -25,7 +25,6 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/ 26 ***************************************************************************/
27 27
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/kmod.h> 30#include <linux/kmod.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index c946c9a538a0..41ef2b606751 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/signal.h> 42#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h
index 401ff21d7881..1d7a77cc7c4a 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.h
+++ b/drivers/usb/misc/sisusbvga/sisusb.h
@@ -37,6 +37,7 @@
37#ifndef _SISUSB_H_ 37#ifndef _SISUSB_H_
38#define _SISUSB_H_ 38#define _SISUSB_H_
39 39
40#include <linux/version.h>
40#ifdef CONFIG_COMPAT 41#ifdef CONFIG_COMPAT
41#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) 42#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
42#include <linux/ioctl32.h> 43#include <linux/ioctl32.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 24584463553d..be5c1a25ae21 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -48,7 +48,6 @@
48 */ 48 */
49 49
50#include <linux/config.h> 50#include <linux/config.h>
51#include <linux/version.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/kernel.h> 52#include <linux/kernel.h>
54#include <linux/signal.h> 53#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
index f28bc240f9b6..044fa4482f9f 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 44b6ca290ce3..25b6ca6ad081 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -593,38 +593,6 @@ config FB_EPSON1355
593 framebuffer. Product specs at 593 framebuffer. Product specs at
594 <http://www.erd.epson.com/vdc/html/products.htm>. 594 <http://www.erd.epson.com/vdc/html/products.htm>.
595 595
596config FB_E1356
597 tristate "Epson SED1356 framebuffer support"
598 depends on FB && EXPERIMENTAL && PCI && MIPS
599
600config PB1000_CRT
601 bool "Use CRT on Pb1000 (J65)"
602 depends on MIPS_PB1000=y && FB_E1356
603
604config PB1000_NTSC
605 bool "Use Compsite NTSC on Pb1000 (J63)"
606 depends on MIPS_PB1000=y && FB_E1356
607
608config PB1000_TFT
609 bool "Use TFT Panel on Pb1000 (J64)"
610 depends on MIPS_PB1000=y && FB_E1356
611
612config PB1500_CRT
613 bool "Use CRT on Pb1500 " if MIPS_PB1500=y
614 depends on FB_E1356
615
616config PB1500_CRT
617 prompt "Use CRT on Pb1100 "
618 depends on FB_E1356 && MIPS_PB1100=y
619
620config PB1500_TFT
621 bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
622 depends on FB_E1356
623
624config PB1500_TFT
625 prompt "Use TFT Panel on Pb1100 "
626 depends on FB_E1356 && MIPS_PB1100=y
627
628config FB_S1D13XXX 596config FB_S1D13XXX
629 tristate "Epson S1D13XXX framebuffer support" 597 tristate "Epson S1D13XXX framebuffer support"
630 depends on FB 598 depends on FB
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index acc81cb01d56..9d5015e99372 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index bc492f26c5a9..6a219b2c77e3 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -48,6 +48,12 @@ static void corgibl_send_intensity(int intensity)
48 corgibl_mach_set_intensity(intensity); 48 corgibl_mach_set_intensity(intensity);
49 49
50 spin_unlock_irqrestore(&bl_lock, flags); 50 spin_unlock_irqrestore(&bl_lock, flags);
51
52 corgi_kick_batt = symbol_get(sharpsl_battery_kick);
53 if (corgi_kick_batt) {
54 corgi_kick_batt();
55 symbol_put(sharpsl_battery_kick);
56 }
51} 57}
52 58
53static void corgibl_blank(int blank) 59static void corgibl_blank(int blank)
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 470e6f0ee4dd..68c690605aa7 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index da664cea7eca..a7770c4f17d0 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -80,10 +80,12 @@ static u32 cfb_tab32[] = {
80#define LEFT_POS(bpp) (32 - bpp) 80#define LEFT_POS(bpp) (32 - bpp)
81#define SHIFT_HIGH(val, bits) ((val) >> (bits)) 81#define SHIFT_HIGH(val, bits) ((val) >> (bits))
82#define SHIFT_LOW(val, bits) ((val) << (bits)) 82#define SHIFT_LOW(val, bits) ((val) << (bits))
83#define BIT_NR(b) (7 - (b))
83#else 84#else
84#define LEFT_POS(bpp) (0) 85#define LEFT_POS(bpp) (0)
85#define SHIFT_HIGH(val, bits) ((val) << (bits)) 86#define SHIFT_HIGH(val, bits) ((val) << (bits))
86#define SHIFT_LOW(val, bits) ((val) >> (bits)) 87#define SHIFT_LOW(val, bits) ((val) >> (bits))
88#define BIT_NR(b) (b)
87#endif 89#endif
88 90
89static inline void color_imageblit(const struct fb_image *image, 91static inline void color_imageblit(const struct fb_image *image,
@@ -177,7 +179,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
177 179
178 while (j--) { 180 while (j--) {
179 l--; 181 l--;
180 color = (*s & (1 << l)) ? fgcolor : bgcolor; 182 color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor;
181 color <<= LEFT_POS(bpp); 183 color <<= LEFT_POS(bpp);
182 val |= SHIFT_HIGH(color, shift); 184 val |= SHIFT_HIGH(color, shift);
183 185
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fadf7c5d216e..94c5f1392cce 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -101,6 +101,16 @@ config FRAMEBUFFER_CONSOLE
101 help 101 help
102 Low-level framebuffer-based console driver. 102 Low-level framebuffer-based console driver.
103 103
104config FRAMEBUFFER_CONSOLE_ROTATION
105 bool "Framebuffer Console Rotation"
106 depends on FRAMEBUFFER_CONSOLE
107 help
108 Enable display rotation for the framebuffer console. This is done
109 in software and may be significantly slower than a normally oriented
110 display. Note that the rotation is done at the console level only
111 such that other users of the framebuffer will remain normally
112 oriented.
113
104config STI_CONSOLE 114config STI_CONSOLE
105 tristate "STI text console" 115 tristate "STI text console"
106 depends on PARISC 116 depends on PARISC
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 5222628accce..fed600c9ca55 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -31,6 +31,10 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
31ifeq ($(CONFIG_FB_TILEBLITTING),y) 31ifeq ($(CONFIG_FB_TILEBLITTING),y)
32obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o 32obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o
33endif 33endif
34ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
35obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
36 fbcon_ccw.o
37endif
34 38
35obj-$(CONFIG_FB_STI) += sticore.o font.o 39obj-$(CONFIG_FB_STI) += sticore.o font.o
36 40
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 67857b3cfc8b..e65fc3ef7630 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -22,35 +22,6 @@
22/* 22/*
23 * Accelerated handlers. 23 * Accelerated handlers.
24 */ 24 */
25#define FBCON_ATTRIBUTE_UNDERLINE 1
26#define FBCON_ATTRIBUTE_REVERSE 2
27#define FBCON_ATTRIBUTE_BOLD 4
28
29static inline int real_y(struct display *p, int ypos)
30{
31 int rows = p->vrows;
32
33 ypos += p->yscroll;
34 return ypos < rows ? ypos : ypos - rows;
35}
36
37
38static inline int get_attribute(struct fb_info *info, u16 c)
39{
40 int attribute = 0;
41
42 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
43 if (attr_underline(c))
44 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
45 if (attr_reverse(c))
46 attribute |= FBCON_ATTRIBUTE_REVERSE;
47 if (attr_bold(c))
48 attribute |= FBCON_ATTRIBUTE_BOLD;
49 }
50
51 return attribute;
52}
53
54static inline void update_attr(u8 *dst, u8 *src, int attribute, 25static inline void update_attr(u8 *dst, u8 *src, int attribute,
55 struct vc_data *vc) 26 struct vc_data *vc)
56{ 27{
@@ -418,6 +389,18 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
418 ops->cursor_reset = 0; 389 ops->cursor_reset = 0;
419} 390}
420 391
392static int bit_update_start(struct fb_info *info)
393{
394 struct fbcon_ops *ops = info->fbcon_par;
395 int err;
396
397 err = fb_pan_display(info, &ops->var);
398 ops->var.xoffset = info->var.xoffset;
399 ops->var.yoffset = info->var.yoffset;
400 ops->var.vmode = info->var.vmode;
401 return err;
402}
403
421void fbcon_set_bitops(struct fbcon_ops *ops) 404void fbcon_set_bitops(struct fbcon_ops *ops)
422{ 405{
423 ops->bmove = bit_bmove; 406 ops->bmove = bit_bmove;
@@ -425,6 +408,11 @@ void fbcon_set_bitops(struct fbcon_ops *ops)
425 ops->putcs = bit_putcs; 408 ops->putcs = bit_putcs;
426 ops->clear_margins = bit_clear_margins; 409 ops->clear_margins = bit_clear_margins;
427 ops->cursor = bit_cursor; 410 ops->cursor = bit_cursor;
411 ops->update_start = bit_update_start;
412 ops->rotate_font = NULL;
413
414 if (ops->rotate)
415 fbcon_set_rotate(ops);
428} 416}
429 417
430EXPORT_SYMBOL(fbcon_set_bitops); 418EXPORT_SYMBOL(fbcon_set_bitops);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3cf1b61ff1f8..e7802ffe549a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,6 +107,8 @@ enum {
107}; 107};
108 108
109struct display fb_display[MAX_NR_CONSOLES]; 109struct display fb_display[MAX_NR_CONSOLES];
110EXPORT_SYMBOL(fb_display);
111
110static signed char con2fb_map[MAX_NR_CONSOLES]; 112static signed char con2fb_map[MAX_NR_CONSOLES];
111static signed char con2fb_map_boot[MAX_NR_CONSOLES]; 113static signed char con2fb_map_boot[MAX_NR_CONSOLES];
112static int logo_height; 114static int logo_height;
@@ -130,6 +132,9 @@ static char fontname[40];
130/* current fb_info */ 132/* current fb_info */
131static int info_idx = -1; 133static int info_idx = -1;
132 134
135/* console rotation */
136static int rotate;
137
133static const struct consw fb_con; 138static const struct consw fb_con;
134 139
135#define CM_SOFTBACK (8) 140#define CM_SOFTBACK (8)
@@ -176,7 +181,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines);
176/* 181/*
177 * Internal routines 182 * Internal routines
178 */ 183 */
179static __inline__ int real_y(struct display *p, int ypos);
180static __inline__ void ywrap_up(struct vc_data *vc, int count); 184static __inline__ void ywrap_up(struct vc_data *vc, int count);
181static __inline__ void ywrap_down(struct vc_data *vc, int count); 185static __inline__ void ywrap_down(struct vc_data *vc, int count);
182static __inline__ void ypan_up(struct vc_data *vc, int count); 186static __inline__ void ypan_up(struct vc_data *vc, int count);
@@ -189,6 +193,8 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
189 int unit); 193 int unit);
190static void fbcon_redraw_move(struct vc_data *vc, struct display *p, 194static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
191 int line, int count, int dy); 195 int line, int count, int dy);
196static void fbcon_modechanged(struct fb_info *info);
197static void fbcon_set_all_vcs(struct fb_info *info);
192 198
193#ifdef CONFIG_MAC 199#ifdef CONFIG_MAC
194/* 200/*
@@ -203,6 +209,88 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
203} 209}
204#endif 210#endif
205 211
212#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
213static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
214{
215 struct fbcon_ops *ops = info->fbcon_par;
216
217 if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
218 p->con_rotate < 4)
219 ops->rotate = p->con_rotate;
220 else
221 ops->rotate = 0;
222}
223
224static void fbcon_rotate(struct fb_info *info, u32 rotate)
225{
226 struct fbcon_ops *ops= info->fbcon_par;
227 struct fb_info *fb_info;
228
229 if (!ops || ops->currcon == -1)
230 return;
231
232 fb_info = registered_fb[con2fb_map[ops->currcon]];
233
234 if (info == fb_info) {
235 struct display *p = &fb_display[ops->currcon];
236
237 if (rotate < 4)
238 p->con_rotate = rotate;
239 else
240 p->con_rotate = 0;
241
242 fbcon_modechanged(info);
243 }
244}
245
246static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
247{
248 struct fbcon_ops *ops = info->fbcon_par;
249 struct vc_data *vc;
250 struct display *p;
251 int i;
252
253 if (!ops || ops->currcon < 0 || rotate > 3)
254 return;
255
256 for (i = 0; i < MAX_NR_CONSOLES; i++) {
257 vc = vc_cons[i].d;
258 if (!vc || vc->vc_mode != KD_TEXT ||
259 registered_fb[con2fb_map[i]] != info)
260 continue;
261
262 p = &fb_display[vc->vc_num];
263 p->con_rotate = rotate;
264 }
265
266 fbcon_set_all_vcs(info);
267}
268#else
269static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
270{
271 struct fbcon_ops *ops = info->fbcon_par;
272
273 ops->rotate = FB_ROTATE_UR;
274}
275
276static void fbcon_rotate(struct fb_info *info, u32 rotate)
277{
278 return;
279}
280
281static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
282{
283 return;
284}
285#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
286
287static int fbcon_get_rotate(struct fb_info *info)
288{
289 struct fbcon_ops *ops = info->fbcon_par;
290
291 return (ops) ? ops->rotate : 0;
292}
293
206static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) 294static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
207{ 295{
208 struct fbcon_ops *ops = info->fbcon_par; 296 struct fbcon_ops *ops = info->fbcon_par;
@@ -422,6 +510,14 @@ static int __init fb_console_setup(char *this_opt)
422 last_fb_vc = simple_strtoul(options, &options, 10) - 1; 510 last_fb_vc = simple_strtoul(options, &options, 10) - 1;
423 fbcon_is_default = 0; 511 fbcon_is_default = 0;
424 } 512 }
513
514 if (!strncmp(options, "rotate:", 7)) {
515 options += 7;
516 if (*options)
517 rotate = simple_strtoul(options, &options, 0);
518 if (rotate > 3)
519 rotate = 0;
520 }
425 } 521 }
426 return 0; 522 return 0;
427} 523}
@@ -480,6 +576,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
480 int cols, int rows, int new_cols, int new_rows) 576 int cols, int rows, int new_cols, int new_rows)
481{ 577{
482 /* Need to make room for the logo */ 578 /* Need to make room for the logo */
579 struct fbcon_ops *ops = info->fbcon_par;
483 int cnt, erase = vc->vc_video_erase_char, step; 580 int cnt, erase = vc->vc_video_erase_char, step;
484 unsigned short *save = NULL, *r, *q; 581 unsigned short *save = NULL, *r, *q;
485 582
@@ -489,7 +586,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
489 */ 586 */
490 if (fb_get_color_depth(&info->var, &info->fix) == 1) 587 if (fb_get_color_depth(&info->var, &info->fix) == 1)
491 erase &= ~0x400; 588 erase &= ~0x400;
492 logo_height = fb_prepare_logo(info); 589 logo_height = fb_prepare_logo(info, ops->rotate);
493 logo_lines = (logo_height + vc->vc_font.height - 1) / 590 logo_lines = (logo_height + vc->vc_font.height - 1) /
494 vc->vc_font.height; 591 vc->vc_font.height;
495 q = (unsigned short *) (vc->vc_origin + 592 q = (unsigned short *) (vc->vc_origin +
@@ -558,16 +655,24 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
558 655
559 if ((info->flags & FBINFO_MISC_TILEBLITTING)) 656 if ((info->flags & FBINFO_MISC_TILEBLITTING))
560 fbcon_set_tileops(vc, info, p, ops); 657 fbcon_set_tileops(vc, info, p, ops);
561 else 658 else {
659 struct display *disp;
660
661 disp = (p) ? p : &fb_display[vc->vc_num];
662 fbcon_set_rotation(info, disp);
562 fbcon_set_bitops(ops); 663 fbcon_set_bitops(ops);
664 }
563} 665}
564#else 666#else
565static void set_blitting_type(struct vc_data *vc, struct fb_info *info, 667static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
566 struct display *p) 668 struct display *p)
567{ 669{
568 struct fbcon_ops *ops = info->fbcon_par; 670 struct fbcon_ops *ops = info->fbcon_par;
671 struct display *disp;
569 672
570 info->flags &= ~FBINFO_MISC_TILEBLITTING; 673 info->flags &= ~FBINFO_MISC_TILEBLITTING;
674 disp = (p) ? p : &fb_display[vc->vc_num];
675 fbcon_set_rotation(info, disp);
571 fbcon_set_bitops(ops); 676 fbcon_set_bitops(ops);
572} 677}
573#endif /* CONFIG_MISC_TILEBLITTING */ 678#endif /* CONFIG_MISC_TILEBLITTING */
@@ -627,6 +732,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
627 fbcon_del_cursor_timer(oldinfo); 732 fbcon_del_cursor_timer(oldinfo);
628 kfree(ops->cursor_state.mask); 733 kfree(ops->cursor_state.mask);
629 kfree(ops->cursor_data); 734 kfree(ops->cursor_data);
735 kfree(ops->fontbuffer);
630 kfree(oldinfo->fbcon_par); 736 kfree(oldinfo->fbcon_par);
631 oldinfo->fbcon_par = NULL; 737 oldinfo->fbcon_par = NULL;
632 module_put(oldinfo->fbops->owner); 738 module_put(oldinfo->fbops->owner);
@@ -827,7 +933,9 @@ static const char *fbcon_startup(void)
827 memset(ops, 0, sizeof(struct fbcon_ops)); 933 memset(ops, 0, sizeof(struct fbcon_ops));
828 ops->currcon = -1; 934 ops->currcon = -1;
829 ops->graphics = 1; 935 ops->graphics = 1;
936 ops->cur_rotate = -1;
830 info->fbcon_par = ops; 937 info->fbcon_par = ops;
938 p->con_rotate = rotate;
831 set_blitting_type(vc, info, NULL); 939 set_blitting_type(vc, info, NULL);
832 940
833 if (info->fix.type != FB_TYPE_TEXT) { 941 if (info->fix.type != FB_TYPE_TEXT) {
@@ -866,8 +974,10 @@ static const char *fbcon_startup(void)
866 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ 974 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
867 } 975 }
868 976
869 cols = info->var.xres / vc->vc_font.width; 977 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
870 rows = info->var.yres / vc->vc_font.height; 978 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
979 cols /= vc->vc_font.width;
980 rows /= vc->vc_font.height;
871 vc_resize(vc, cols, rows); 981 vc_resize(vc, cols, rows);
872 982
873 DPRINTK("mode: %s\n", info->fix.id); 983 DPRINTK("mode: %s\n", info->fix.id);
@@ -953,8 +1063,6 @@ static void fbcon_init(struct vc_data *vc, int init)
953 (info->fix.type == FB_TYPE_TEXT)) 1063 (info->fix.type == FB_TYPE_TEXT))
954 logo = 0; 1064 logo = 0;
955 1065
956 info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
957
958 if (var_to_display(p, &info->var, info)) 1066 if (var_to_display(p, &info->var, info))
959 return; 1067 return;
960 1068
@@ -986,13 +1094,18 @@ static void fbcon_init(struct vc_data *vc, int init)
986 if (!*vc->vc_uni_pagedir_loc) 1094 if (!*vc->vc_uni_pagedir_loc)
987 con_copy_unimap(vc, svc); 1095 con_copy_unimap(vc, svc);
988 1096
1097 ops = info->fbcon_par;
1098 p->con_rotate = rotate;
1099 set_blitting_type(vc, info, NULL);
1100
989 cols = vc->vc_cols; 1101 cols = vc->vc_cols;
990 rows = vc->vc_rows; 1102 rows = vc->vc_rows;
991 new_cols = info->var.xres / vc->vc_font.width; 1103 new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
992 new_rows = info->var.yres / vc->vc_font.height; 1104 new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1105 new_cols /= vc->vc_font.width;
1106 new_rows /= vc->vc_font.height;
993 vc_resize(vc, new_cols, new_rows); 1107 vc_resize(vc, new_cols, new_rows);
994 1108
995 ops = info->fbcon_par;
996 /* 1109 /*
997 * We must always set the mode. The mode of the previous console 1110 * We must always set the mode. The mode of the previous console
998 * driver could be in the same resolution but we are using different 1111 * driver could be in the same resolution but we are using different
@@ -1030,6 +1143,12 @@ static void fbcon_init(struct vc_data *vc, int init)
1030 1143
1031 if (vc == svc && softback_buf) 1144 if (vc == svc && softback_buf)
1032 fbcon_update_softback(vc); 1145 fbcon_update_softback(vc);
1146
1147 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
1148 ops->rotate = FB_ROTATE_UR;
1149 set_blitting_type(vc, info, p);
1150 }
1151
1033} 1152}
1034 1153
1035static void fbcon_deinit(struct vc_data *vc) 1154static void fbcon_deinit(struct vc_data *vc)
@@ -1066,15 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc)
1066 * restriction is simplicity & efficiency at the moment. 1185 * restriction is simplicity & efficiency at the moment.
1067 */ 1186 */
1068 1187
1069static __inline__ int real_y(struct display *p, int ypos)
1070{
1071 int rows = p->vrows;
1072
1073 ypos += p->yscroll;
1074 return ypos < rows ? ypos : ypos - rows;
1075}
1076
1077
1078static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, 1188static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
1079 int width) 1189 int width)
1080{ 1190{
@@ -1162,13 +1272,6 @@ static int scrollback_phys_max = 0;
1162static int scrollback_max = 0; 1272static int scrollback_max = 0;
1163static int scrollback_current = 0; 1273static int scrollback_current = 0;
1164 1274
1165static int update_var(int con, struct fb_info *info)
1166{
1167 if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
1168 return fb_pan_display(info, &info->var);
1169 return 0;
1170}
1171
1172/* 1275/*
1173 * If no vc is existent yet, just set struct display 1276 * If no vc is existent yet, just set struct display
1174 */ 1277 */
@@ -1178,7 +1281,6 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
1178 struct display *p = &fb_display[unit]; 1281 struct display *p = &fb_display[unit];
1179 struct display *t = &fb_display[fg_console]; 1282 struct display *t = &fb_display[fg_console];
1180 1283
1181 var->xoffset = var->yoffset = p->yscroll = 0;
1182 if (var_to_display(p, var, info)) 1284 if (var_to_display(p, var, info))
1183 return; 1285 return;
1184 1286
@@ -1194,9 +1296,9 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1194 struct display *p = &fb_display[vc->vc_num], *t; 1296 struct display *p = &fb_display[vc->vc_num], *t;
1195 struct vc_data **default_mode = vc->vc_display_fg; 1297 struct vc_data **default_mode = vc->vc_display_fg;
1196 struct vc_data *svc = *default_mode; 1298 struct vc_data *svc = *default_mode;
1299 struct fbcon_ops *ops = info->fbcon_par;
1197 int rows, cols, charcnt = 256; 1300 int rows, cols, charcnt = 256;
1198 1301
1199 var->xoffset = var->yoffset = p->yscroll = 0;
1200 if (var_to_display(p, var, info)) 1302 if (var_to_display(p, var, info))
1201 return; 1303 return;
1202 t = &fb_display[svc->vc_num]; 1304 t = &fb_display[svc->vc_num];
@@ -1213,9 +1315,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1213 1315
1214 var->activate = FB_ACTIVATE_NOW; 1316 var->activate = FB_ACTIVATE_NOW;
1215 info->var.activate = var->activate; 1317 info->var.activate = var->activate;
1216 info->var.yoffset = info->var.xoffset = 0; 1318 var->yoffset = info->var.yoffset;
1319 var->xoffset = info->var.xoffset;
1217 fb_set_var(info, var); 1320 fb_set_var(info, var);
1218 1321 ops->var = info->var;
1219 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 1322 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1220 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1323 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1221 if (charcnt == 256) { 1324 if (charcnt == 256) {
@@ -1231,9 +1334,12 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1231 if (!*vc->vc_uni_pagedir_loc) 1334 if (!*vc->vc_uni_pagedir_loc)
1232 con_copy_unimap(vc, svc); 1335 con_copy_unimap(vc, svc);
1233 1336
1234 cols = var->xres / vc->vc_font.width; 1337 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1235 rows = var->yres / vc->vc_font.height; 1338 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1339 cols /= vc->vc_font.width;
1340 rows /= vc->vc_font.height;
1236 vc_resize(vc, cols, rows); 1341 vc_resize(vc, cols, rows);
1342
1237 if (CON_IS_VISIBLE(vc)) { 1343 if (CON_IS_VISIBLE(vc)) {
1238 update_screen(vc); 1344 update_screen(vc);
1239 if (softback_buf) 1345 if (softback_buf)
@@ -1244,15 +1350,16 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1244static __inline__ void ywrap_up(struct vc_data *vc, int count) 1350static __inline__ void ywrap_up(struct vc_data *vc, int count)
1245{ 1351{
1246 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1352 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1353 struct fbcon_ops *ops = info->fbcon_par;
1247 struct display *p = &fb_display[vc->vc_num]; 1354 struct display *p = &fb_display[vc->vc_num];
1248 1355
1249 p->yscroll += count; 1356 p->yscroll += count;
1250 if (p->yscroll >= p->vrows) /* Deal with wrap */ 1357 if (p->yscroll >= p->vrows) /* Deal with wrap */
1251 p->yscroll -= p->vrows; 1358 p->yscroll -= p->vrows;
1252 info->var.xoffset = 0; 1359 ops->var.xoffset = 0;
1253 info->var.yoffset = p->yscroll * vc->vc_font.height; 1360 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1254 info->var.vmode |= FB_VMODE_YWRAP; 1361 ops->var.vmode |= FB_VMODE_YWRAP;
1255 update_var(vc->vc_num, info); 1362 ops->update_start(info);
1256 scrollback_max += count; 1363 scrollback_max += count;
1257 if (scrollback_max > scrollback_phys_max) 1364 if (scrollback_max > scrollback_phys_max)
1258 scrollback_max = scrollback_phys_max; 1365 scrollback_max = scrollback_phys_max;
@@ -1262,15 +1369,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count)
1262static __inline__ void ywrap_down(struct vc_data *vc, int count) 1369static __inline__ void ywrap_down(struct vc_data *vc, int count)
1263{ 1370{
1264 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1371 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1372 struct fbcon_ops *ops = info->fbcon_par;
1265 struct display *p = &fb_display[vc->vc_num]; 1373 struct display *p = &fb_display[vc->vc_num];
1266 1374
1267 p->yscroll -= count; 1375 p->yscroll -= count;
1268 if (p->yscroll < 0) /* Deal with wrap */ 1376 if (p->yscroll < 0) /* Deal with wrap */
1269 p->yscroll += p->vrows; 1377 p->yscroll += p->vrows;
1270 info->var.xoffset = 0; 1378 ops->var.xoffset = 0;
1271 info->var.yoffset = p->yscroll * vc->vc_font.height; 1379 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1272 info->var.vmode |= FB_VMODE_YWRAP; 1380 ops->var.vmode |= FB_VMODE_YWRAP;
1273 update_var(vc->vc_num, info); 1381 ops->update_start(info);
1274 scrollback_max -= count; 1382 scrollback_max -= count;
1275 if (scrollback_max < 0) 1383 if (scrollback_max < 0)
1276 scrollback_max = 0; 1384 scrollback_max = 0;
@@ -1289,10 +1397,11 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1289 0, 0, 0, vc->vc_rows, vc->vc_cols); 1397 0, 0, 0, vc->vc_rows, vc->vc_cols);
1290 p->yscroll -= p->vrows - vc->vc_rows; 1398 p->yscroll -= p->vrows - vc->vc_rows;
1291 } 1399 }
1292 info->var.xoffset = 0; 1400
1293 info->var.yoffset = p->yscroll * vc->vc_font.height; 1401 ops->var.xoffset = 0;
1294 info->var.vmode &= ~FB_VMODE_YWRAP; 1402 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1295 update_var(vc->vc_num, info); 1403 ops->var.vmode &= ~FB_VMODE_YWRAP;
1404 ops->update_start(info);
1296 fbcon_clear_margins(vc, 1); 1405 fbcon_clear_margins(vc, 1);
1297 scrollback_max += count; 1406 scrollback_max += count;
1298 if (scrollback_max > scrollback_phys_max) 1407 if (scrollback_max > scrollback_phys_max)
@@ -1303,6 +1412,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1303static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) 1412static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1304{ 1413{
1305 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1414 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1415 struct fbcon_ops *ops = info->fbcon_par;
1306 struct display *p = &fb_display[vc->vc_num]; 1416 struct display *p = &fb_display[vc->vc_num];
1307 int redraw = 0; 1417 int redraw = 0;
1308 1418
@@ -1312,12 +1422,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1312 redraw = 1; 1422 redraw = 1;
1313 } 1423 }
1314 1424
1315 info->var.xoffset = 0;
1316 info->var.yoffset = p->yscroll * vc->vc_font.height;
1317 info->var.vmode &= ~FB_VMODE_YWRAP;
1318 if (redraw) 1425 if (redraw)
1319 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); 1426 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
1320 update_var(vc->vc_num, info); 1427
1428 ops->var.xoffset = 0;
1429 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1430 ops->var.vmode &= ~FB_VMODE_YWRAP;
1431 ops->update_start(info);
1321 fbcon_clear_margins(vc, 1); 1432 fbcon_clear_margins(vc, 1);
1322 scrollback_max += count; 1433 scrollback_max += count;
1323 if (scrollback_max > scrollback_phys_max) 1434 if (scrollback_max > scrollback_phys_max)
@@ -1337,10 +1448,11 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1337 0, vc->vc_rows, vc->vc_cols); 1448 0, vc->vc_rows, vc->vc_cols);
1338 p->yscroll += p->vrows - vc->vc_rows; 1449 p->yscroll += p->vrows - vc->vc_rows;
1339 } 1450 }
1340 info->var.xoffset = 0; 1451
1341 info->var.yoffset = p->yscroll * vc->vc_font.height; 1452 ops->var.xoffset = 0;
1342 info->var.vmode &= ~FB_VMODE_YWRAP; 1453 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1343 update_var(vc->vc_num, info); 1454 ops->var.vmode &= ~FB_VMODE_YWRAP;
1455 ops->update_start(info);
1344 fbcon_clear_margins(vc, 1); 1456 fbcon_clear_margins(vc, 1);
1345 scrollback_max -= count; 1457 scrollback_max -= count;
1346 if (scrollback_max < 0) 1458 if (scrollback_max < 0)
@@ -1351,6 +1463,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1351static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) 1463static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1352{ 1464{
1353 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1465 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1466 struct fbcon_ops *ops = info->fbcon_par;
1354 struct display *p = &fb_display[vc->vc_num]; 1467 struct display *p = &fb_display[vc->vc_num];
1355 int redraw = 0; 1468 int redraw = 0;
1356 1469
@@ -1359,12 +1472,14 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1359 p->yscroll += p->vrows - vc->vc_rows; 1472 p->yscroll += p->vrows - vc->vc_rows;
1360 redraw = 1; 1473 redraw = 1;
1361 } 1474 }
1362 info->var.xoffset = 0; 1475
1363 info->var.yoffset = p->yscroll * vc->vc_font.height;
1364 info->var.vmode &= ~FB_VMODE_YWRAP;
1365 if (redraw) 1476 if (redraw)
1366 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); 1477 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
1367 update_var(vc->vc_num, info); 1478
1479 ops->var.xoffset = 0;
1480 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1481 ops->var.vmode &= ~FB_VMODE_YWRAP;
1482 ops->update_start(info);
1368 fbcon_clear_margins(vc, 1); 1483 fbcon_clear_margins(vc, 1);
1369 scrollback_max -= count; 1484 scrollback_max -= count;
1370 if (scrollback_max < 0) 1485 if (scrollback_max < 0)
@@ -1838,31 +1953,41 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
1838 height, width); 1953 height, width);
1839} 1954}
1840 1955
1841static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, 1956static __inline__ void updatescrollmode(struct display *p,
1957 struct fb_info *info,
1842 struct vc_data *vc) 1958 struct vc_data *vc)
1843{ 1959{
1960 struct fbcon_ops *ops = info->fbcon_par;
1844 int fh = vc->vc_font.height; 1961 int fh = vc->vc_font.height;
1845 int cap = info->flags; 1962 int cap = info->flags;
1846 int good_pan = (cap & FBINFO_HWACCEL_YPAN) 1963 u16 t = 0;
1847 && divides(info->fix.ypanstep, vc->vc_font.height) 1964 int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
1848 && info->var.yres_virtual > info->var.yres; 1965 info->fix.xpanstep);
1849 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) 1966 int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
1850 && divides(info->fix.ywrapstep, vc->vc_font.height) 1967 int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1851 && divides(vc->vc_font.height, info->var.yres_virtual); 1968 int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
1969 info->var.xres_virtual);
1970 int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
1971 divides(ypan, vc->vc_font.height) && vyres > yres;
1972 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
1973 divides(ywrap, vc->vc_font.height) &&
1974 divides(vc->vc_font.height, vyres);
1852 int reading_fast = cap & FBINFO_READS_FAST; 1975 int reading_fast = cap & FBINFO_READS_FAST;
1853 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED); 1976 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
1854 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && !(cap & FBINFO_HWACCEL_DISABLED); 1977 !(cap & FBINFO_HWACCEL_DISABLED);
1855 1978 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
1856 p->vrows = info->var.yres_virtual/fh; 1979 !(cap & FBINFO_HWACCEL_DISABLED);
1857 if (info->var.yres > (fh * (vc->vc_rows + 1))) 1980
1858 p->vrows -= (info->var.yres - (fh * vc->vc_rows)) / fh; 1981 p->vrows = vyres/fh;
1859 if ((info->var.yres % fh) && (info->var.yres_virtual % fh < 1982 if (yres > (fh * (vc->vc_rows + 1)))
1860 info->var.yres % fh)) 1983 p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
1984 if ((yres % fh) && (vyres % fh < yres % fh))
1861 p->vrows--; 1985 p->vrows--;
1862 1986
1863 if (good_wrap || good_pan) { 1987 if (good_wrap || good_pan) {
1864 if (reading_fast || fast_copyarea) 1988 if (reading_fast || fast_copyarea)
1865 p->scrollmode = good_wrap ? SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; 1989 p->scrollmode = good_wrap ?
1990 SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
1866 else 1991 else
1867 p->scrollmode = good_wrap ? SCROLL_REDRAW : 1992 p->scrollmode = good_wrap ? SCROLL_REDRAW :
1868 SCROLL_PAN_REDRAW; 1993 SCROLL_PAN_REDRAW;
@@ -1878,17 +2003,23 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1878 unsigned int height) 2003 unsigned int height)
1879{ 2004{
1880 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2005 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2006 struct fbcon_ops *ops = info->fbcon_par;
1881 struct display *p = &fb_display[vc->vc_num]; 2007 struct display *p = &fb_display[vc->vc_num];
1882 struct fb_var_screeninfo var = info->var; 2008 struct fb_var_screeninfo var = info->var;
1883 int x_diff, y_diff; 2009 int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
1884 int fw = vc->vc_font.width; 2010
1885 int fh = vc->vc_font.height; 2011 virt_w = FBCON_SWAP(ops->rotate, width, height);
1886 2012 virt_h = FBCON_SWAP(ops->rotate, height, width);
1887 var.xres = width * fw; 2013 virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
1888 var.yres = height * fh; 2014 vc->vc_font.height);
2015 virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
2016 vc->vc_font.width);
2017 var.xres = virt_w * virt_fw;
2018 var.yres = virt_h * virt_fh;
1889 x_diff = info->var.xres - var.xres; 2019 x_diff = info->var.xres - var.xres;
1890 y_diff = info->var.yres - var.yres; 2020 y_diff = info->var.yres - var.yres;
1891 if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) { 2021 if (x_diff < 0 || x_diff > virt_fw ||
2022 y_diff < 0 || y_diff > virt_fh) {
1892 struct fb_videomode *mode; 2023 struct fb_videomode *mode;
1893 2024
1894 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); 2025 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
@@ -1898,7 +2029,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1898 display_to_var(&var, p); 2029 display_to_var(&var, p);
1899 fb_videomode_to_var(&var, mode); 2030 fb_videomode_to_var(&var, mode);
1900 2031
1901 if (width > var.xres/fw || height > var.yres/fh) 2032 if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
1902 return -EINVAL; 2033 return -EINVAL;
1903 2034
1904 DPRINTK("resize now %ix%i\n", var.xres, var.yres); 2035 DPRINTK("resize now %ix%i\n", var.xres, var.yres);
@@ -1908,6 +2039,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1908 fb_set_var(info, &var); 2039 fb_set_var(info, &var);
1909 } 2040 }
1910 var_to_display(p, &info->var, info); 2041 var_to_display(p, &info->var, info);
2042 ops->var = info->var;
1911 } 2043 }
1912 updatescrollmode(p, info, vc); 2044 updatescrollmode(p, info, vc);
1913 return 0; 2045 return 0;
@@ -1916,11 +2048,13 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1916static int fbcon_switch(struct vc_data *vc) 2048static int fbcon_switch(struct vc_data *vc)
1917{ 2049{
1918 struct fb_info *info, *old_info = NULL; 2050 struct fb_info *info, *old_info = NULL;
2051 struct fbcon_ops *ops;
1919 struct display *p = &fb_display[vc->vc_num]; 2052 struct display *p = &fb_display[vc->vc_num];
1920 struct fb_var_screeninfo var; 2053 struct fb_var_screeninfo var;
1921 int i, prev_console; 2054 int i, prev_console;
1922 2055
1923 info = registered_fb[con2fb_map[vc->vc_num]]; 2056 info = registered_fb[con2fb_map[vc->vc_num]];
2057 ops = info->fbcon_par;
1924 2058
1925 if (softback_top) { 2059 if (softback_top) {
1926 if (softback_lines) 2060 if (softback_lines)
@@ -1939,7 +2073,7 @@ static int fbcon_switch(struct vc_data *vc)
1939 logo_shown = FBCON_LOGO_CANSHOW; 2073 logo_shown = FBCON_LOGO_CANSHOW;
1940 } 2074 }
1941 2075
1942 prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; 2076 prev_console = ops->currcon;
1943 if (prev_console != -1) 2077 if (prev_console != -1)
1944 old_info = registered_fb[con2fb_map[prev_console]]; 2078 old_info = registered_fb[con2fb_map[prev_console]];
1945 /* 2079 /*
@@ -1952,9 +2086,9 @@ static int fbcon_switch(struct vc_data *vc)
1952 */ 2086 */
1953 for (i = 0; i < FB_MAX; i++) { 2087 for (i = 0; i < FB_MAX; i++) {
1954 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { 2088 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
1955 struct fbcon_ops *ops = registered_fb[i]->fbcon_par; 2089 struct fbcon_ops *o = registered_fb[i]->fbcon_par;
1956 2090
1957 ops->currcon = vc->vc_num; 2091 o->currcon = vc->vc_num;
1958 } 2092 }
1959 } 2093 }
1960 memset(&var, 0, sizeof(struct fb_var_screeninfo)); 2094 memset(&var, 0, sizeof(struct fb_var_screeninfo));
@@ -1966,8 +2100,11 @@ static int fbcon_switch(struct vc_data *vc)
1966 * in fb_set_var() 2100 * in fb_set_var()
1967 */ 2101 */
1968 info->var.activate = var.activate; 2102 info->var.activate = var.activate;
1969 info->var.yoffset = info->var.xoffset = p->yscroll = 0; 2103 var.yoffset = info->var.yoffset;
2104 var.xoffset = info->var.xoffset;
2105 var.vmode = info->var.vmode;
1970 fb_set_var(info, &var); 2106 fb_set_var(info, &var);
2107 ops->var = info->var;
1971 2108
1972 if (old_info != NULL && old_info != info) { 2109 if (old_info != NULL && old_info != info) {
1973 if (info->fbops->fb_set_par) 2110 if (info->fbops->fb_set_par)
@@ -1977,7 +2114,12 @@ static int fbcon_switch(struct vc_data *vc)
1977 } 2114 }
1978 2115
1979 set_blitting_type(vc, info, p); 2116 set_blitting_type(vc, info, p);
1980 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; 2117 ops->cursor_reset = 1;
2118
2119 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
2120 ops->rotate = FB_ROTATE_UR;
2121 set_blitting_type(vc, info, p);
2122 }
1981 2123
1982 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 2124 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1983 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 2125 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
@@ -1997,10 +2139,11 @@ static int fbcon_switch(struct vc_data *vc)
1997 scrollback_phys_max = 0; 2139 scrollback_phys_max = 0;
1998 break; 2140 break;
1999 } 2141 }
2142
2000 scrollback_max = 0; 2143 scrollback_max = 0;
2001 scrollback_current = 0; 2144 scrollback_current = 0;
2002 2145 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2003 update_var(vc->vc_num, info); 2146 ops->update_start(info);
2004 fbcon_set_palette(vc, color_table); 2147 fbcon_set_palette(vc, color_table);
2005 fbcon_clear_margins(vc, 0); 2148 fbcon_clear_margins(vc, 0);
2006 2149
@@ -2008,7 +2151,7 @@ static int fbcon_switch(struct vc_data *vc)
2008 2151
2009 logo_shown = fg_console; 2152 logo_shown = fg_console;
2010 /* This is protected above by initmem_freed */ 2153 /* This is protected above by initmem_freed */
2011 fb_show_logo(info); 2154 fb_show_logo(info, ops->rotate);
2012 update_region(vc, 2155 update_region(vc,
2013 vc->vc_origin + vc->vc_size_row * vc->vc_top, 2156 vc->vc_origin + vc->vc_size_row * vc->vc_top,
2014 vc->vc_size_row * (vc->vc_bottom - 2157 vc->vc_size_row * (vc->vc_bottom -
@@ -2047,6 +2190,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2047 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; 2190 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
2048 fb_set_var(info, &var); 2191 fb_set_var(info, &var);
2049 ops->graphics = 0; 2192 ops->graphics = 0;
2193 ops->var = info->var;
2050 } 2194 }
2051 } 2195 }
2052 2196
@@ -2135,6 +2279,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2135 const u8 * data, int userfont) 2279 const u8 * data, int userfont)
2136{ 2280{
2137 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2281 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2282 struct fbcon_ops *ops = info->fbcon_par;
2138 struct display *p = &fb_display[vc->vc_num]; 2283 struct display *p = &fb_display[vc->vc_num];
2139 int resize; 2284 int resize;
2140 int cnt; 2285 int cnt;
@@ -2214,9 +2359,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2214 } 2359 }
2215 2360
2216 if (resize) { 2361 if (resize) {
2217 /* reset wrap/pan */ 2362 int cols, rows;
2218 info->var.xoffset = info->var.yoffset = p->yscroll = 0; 2363
2219 vc_resize(vc, info->var.xres / w, info->var.yres / h); 2364 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2365 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2366 cols /= w;
2367 rows /= h;
2368 vc_resize(vc, cols, rows);
2220 if (CON_IS_VISIBLE(vc) && softback_buf) 2369 if (CON_IS_VISIBLE(vc) && softback_buf)
2221 fbcon_update_softback(vc); 2370 fbcon_update_softback(vc);
2222 } else if (CON_IS_VISIBLE(vc) 2371 } else if (CON_IS_VISIBLE(vc)
@@ -2444,6 +2593,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
2444static int fbcon_scrolldelta(struct vc_data *vc, int lines) 2593static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2445{ 2594{
2446 struct fb_info *info = registered_fb[con2fb_map[fg_console]]; 2595 struct fb_info *info = registered_fb[con2fb_map[fg_console]];
2596 struct fbcon_ops *ops = info->fbcon_par;
2447 struct display *p = &fb_display[fg_console]; 2597 struct display *p = &fb_display[fg_console];
2448 int offset, limit, scrollback_old; 2598 int offset, limit, scrollback_old;
2449 2599
@@ -2520,9 +2670,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2520 offset += limit; 2670 offset += limit;
2521 else if (offset >= limit) 2671 else if (offset >= limit)
2522 offset -= limit; 2672 offset -= limit;
2523 info->var.xoffset = 0; 2673
2524 info->var.yoffset = offset * vc->vc_font.height; 2674 ops->var.xoffset = 0;
2525 update_var(vc->vc_num, info); 2675 ops->var.yoffset = offset * vc->vc_font.height;
2676 ops->update_start(info);
2677
2526 if (!scrollback_current) 2678 if (!scrollback_current)
2527 fbcon_cursor(vc, CM_DRAW); 2679 fbcon_cursor(vc, CM_DRAW);
2528 return 0; 2680 return 0;
@@ -2570,22 +2722,25 @@ static void fbcon_modechanged(struct fb_info *info)
2570 if (!ops || ops->currcon < 0) 2722 if (!ops || ops->currcon < 0)
2571 return; 2723 return;
2572 vc = vc_cons[ops->currcon].d; 2724 vc = vc_cons[ops->currcon].d;
2573 if (vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info) 2725 if (vc->vc_mode != KD_TEXT ||
2726 registered_fb[con2fb_map[ops->currcon]] != info)
2574 return; 2727 return;
2575 2728
2576 p = &fb_display[vc->vc_num]; 2729 p = &fb_display[vc->vc_num];
2577 2730 set_blitting_type(vc, info, p);
2578 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2579 2731
2580 if (CON_IS_VISIBLE(vc)) { 2732 if (CON_IS_VISIBLE(vc)) {
2581 var_to_display(p, &info->var, info); 2733 var_to_display(p, &info->var, info);
2582 cols = info->var.xres / vc->vc_font.width; 2734 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2583 rows = info->var.yres / vc->vc_font.height; 2735 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2736 cols /= vc->vc_font.width;
2737 rows /= vc->vc_font.height;
2584 vc_resize(vc, cols, rows); 2738 vc_resize(vc, cols, rows);
2585 updatescrollmode(p, info, vc); 2739 updatescrollmode(p, info, vc);
2586 scrollback_max = 0; 2740 scrollback_max = 0;
2587 scrollback_current = 0; 2741 scrollback_current = 0;
2588 update_var(vc->vc_num, info); 2742 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2743 ops->update_start(info);
2589 fbcon_set_palette(vc, color_table); 2744 fbcon_set_palette(vc, color_table);
2590 update_screen(vc); 2745 update_screen(vc);
2591 if (softback_buf) 2746 if (softback_buf)
@@ -2610,18 +2765,20 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2610 continue; 2765 continue;
2611 2766
2612 p = &fb_display[vc->vc_num]; 2767 p = &fb_display[vc->vc_num];
2613 2768 set_blitting_type(vc, info, p);
2614 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2615 var_to_display(p, &info->var, info); 2769 var_to_display(p, &info->var, info);
2616 cols = info->var.xres / vc->vc_font.width; 2770 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2617 rows = info->var.yres / vc->vc_font.height; 2771 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2772 cols /= vc->vc_font.width;
2773 rows /= vc->vc_font.height;
2618 vc_resize(vc, cols, rows); 2774 vc_resize(vc, cols, rows);
2619 2775
2620 if (CON_IS_VISIBLE(vc)) { 2776 if (CON_IS_VISIBLE(vc)) {
2621 updatescrollmode(p, info, vc); 2777 updatescrollmode(p, info, vc);
2622 scrollback_max = 0; 2778 scrollback_max = 0;
2623 scrollback_current = 0; 2779 scrollback_current = 0;
2624 update_var(vc->vc_num, info); 2780 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2781 ops->update_start(info);
2625 fbcon_set_palette(vc, color_table); 2782 fbcon_set_palette(vc, color_table);
2626 update_screen(vc); 2783 update_screen(vc);
2627 if (softback_buf) 2784 if (softback_buf)
@@ -2771,6 +2928,14 @@ static int fbcon_event_notify(struct notifier_block *self,
2771 case FB_EVENT_NEW_MODELIST: 2928 case FB_EVENT_NEW_MODELIST:
2772 fbcon_new_modelist(info); 2929 fbcon_new_modelist(info);
2773 break; 2930 break;
2931 case FB_EVENT_SET_CON_ROTATE:
2932 fbcon_rotate(info, *(int *)event->data);
2933 break;
2934 case FB_EVENT_GET_CON_ROTATE:
2935 ret = fbcon_get_rotate(info);
2936 break;
2937 case FB_EVENT_SET_CON_ROTATE_ALL:
2938 fbcon_rotate_all(info, *(int *)event->data);
2774 } 2939 }
2775 2940
2776 return ret; 2941 return ret;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index b68e0e2c2d16..accfd7bd8e93 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -27,15 +27,15 @@
27 */ 27 */
28 28
29struct display { 29struct display {
30 /* Filled in by the frame buffer device */
31 u_short inverse; /* != 0 text black on white as default */
32 /* Filled in by the low-level console driver */ 30 /* Filled in by the low-level console driver */
33 const u_char *fontdata; 31 const u_char *fontdata;
34 int userfont; /* != 0 if fontdata kmalloc()ed */ 32 int userfont; /* != 0 if fontdata kmalloc()ed */
35 u_short scrollmode; /* Scroll Method */ 33 u_short scrollmode; /* Scroll Method */
34 u_short inverse; /* != 0 text black on white as default */
36 short yscroll; /* Hardware scrolling */ 35 short yscroll; /* Hardware scrolling */
37 int vrows; /* number of virtual rows */ 36 int vrows; /* number of virtual rows */
38 int cursor_shape; 37 int cursor_shape;
38 int con_rotate;
39 u32 xres_virtual; 39 u32 xres_virtual;
40 u32 yres_virtual; 40 u32 yres_virtual;
41 u32 height; 41 u32 height;
@@ -52,6 +52,8 @@ struct display {
52 struct fb_videomode *mode; 52 struct fb_videomode *mode;
53}; 53};
54 54
55extern struct display fb_display[];
56
55struct fbcon_ops { 57struct fbcon_ops {
56 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, 58 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
57 int sx, int dy, int dx, int height, int width); 59 int sx, int dy, int dx, int height, int width);
@@ -63,8 +65,12 @@ struct fbcon_ops {
63 void (*clear_margins)(struct vc_data *vc, struct fb_info *info, 65 void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
64 int bottom_only); 66 int bottom_only);
65 void (*cursor)(struct vc_data *vc, struct fb_info *info, 67 void (*cursor)(struct vc_data *vc, struct fb_info *info,
66 struct display *p, int mode, int softback_lines, int fg, int bg); 68 struct display *p, int mode, int softback_lines,
67 69 int fg, int bg);
70 int (*update_start)(struct fb_info *info);
71 int (*rotate_font)(struct fb_info *info, struct vc_data *vc,
72 struct display *p);
73 struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
68 struct timer_list cursor_timer; /* Cursor timer */ 74 struct timer_list cursor_timer; /* Cursor timer */
69 struct fb_cursor cursor_state; 75 struct fb_cursor cursor_state;
70 int currcon; /* Current VC. */ 76 int currcon; /* Current VC. */
@@ -73,7 +79,12 @@ struct fbcon_ops {
73 int blank_state; 79 int blank_state;
74 int graphics; 80 int graphics;
75 int flags; 81 int flags;
82 int rotate;
83 int cur_rotate;
76 char *cursor_data; 84 char *cursor_data;
85 u8 *fontbuffer;
86 u8 *fontdata;
87 u32 fd_size;
77}; 88};
78 /* 89 /*
79 * Attribute Decoding 90 * Attribute Decoding
@@ -168,4 +179,47 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
168#endif 179#endif
169extern void fbcon_set_bitops(struct fbcon_ops *ops); 180extern void fbcon_set_bitops(struct fbcon_ops *ops);
170extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); 181extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
182
183#define FBCON_ATTRIBUTE_UNDERLINE 1
184#define FBCON_ATTRIBUTE_REVERSE 2
185#define FBCON_ATTRIBUTE_BOLD 4
186
187static inline int real_y(struct display *p, int ypos)
188{
189 int rows = p->vrows;
190
191 ypos += p->yscroll;
192 return ypos < rows ? ypos : ypos - rows;
193}
194
195
196static inline int get_attribute(struct fb_info *info, u16 c)
197{
198 int attribute = 0;
199
200 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
201 if (attr_underline(c))
202 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
203 if (attr_reverse(c))
204 attribute |= FBCON_ATTRIBUTE_REVERSE;
205 if (attr_bold(c))
206 attribute |= FBCON_ATTRIBUTE_BOLD;
207 }
208
209 return attribute;
210}
211
212#define FBCON_SWAP(i,r,v) ({ \
213 typeof(r) _r = (r); \
214 typeof(v) _v = (v); \
215 (void) (&_r == &_v); \
216 (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
217
218#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
219extern void fbcon_set_rotate(struct fbcon_ops *ops);
220#else
221#define fbcon_set_rotate(x) do {} while(0)
222#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
223
171#endif /* _VIDEO_FBCON_H */ 224#endif /* _VIDEO_FBCON_H */
225
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
new file mode 100644
index 000000000000..680aabab73c5
--- /dev/null
+++ b/drivers/video/console/fbcon_ccw.c
@@ -0,0 +1,428 @@
1/*
2 * linux/drivers/video/console/fbcon_ccw.c -- Software Rotation - 270 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 270 degrees
23 */
24
25static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 int mod = vc->vc_font.height % 8;
31 u8 c, msk = ~(0xff << offset), msk1 = 0;
32
33 if (mod)
34 msk <<= (8 - mod);
35
36 if (offset > mod)
37 set_bit(FBCON_BIT(7), (void *)&msk1);
38
39 for (i = 0; i < vc->vc_font.width; i++) {
40 for (j = 0; j < width; j++) {
41 c = *src;
42
43 if (attribute & FBCON_ATTRIBUTE_UNDERLINE) {
44 if (j == width - 1)
45 c |= msk;
46
47 if (msk1 && j == width - 2)
48 c |= msk1;
49 }
50
51 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
52 *(dst - width) |= c;
53
54 if (attribute & FBCON_ATTRIBUTE_REVERSE)
55 c = ~c;
56 src++;
57 *dst++ = c;
58 }
59 }
60}
61
62
63static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
64 int sx, int dy, int dx, int height, int width)
65{
66 struct display *p = &fb_display[vc->vc_num];
67 struct fb_copyarea area;
68 u32 vyres = GETVYRES(p->scrollmode, info);
69
70 area.sx = sy * vc->vc_font.height;
71 area.sy = vyres - ((sx + width) * vc->vc_font.width);
72 area.dx = dy * vc->vc_font.height;
73 area.dy = vyres - ((dx + width) * vc->vc_font.width);
74 area.width = height * vc->vc_font.height;
75 area.height = width * vc->vc_font.width;
76
77 info->fbops->fb_copyarea(info, &area);
78}
79
80static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
81 int sx, int height, int width)
82{
83 struct display *p = &fb_display[vc->vc_num];
84 struct fb_fillrect region;
85 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
86 u32 vyres = GETVYRES(p->scrollmode, info);
87
88 region.color = attr_bgcol_ec(bgshift,vc);
89 region.dx = sy * vc->vc_font.height;
90 region.dy = vyres - ((sx + width) * vc->vc_font.width);
91 region.height = width * vc->vc_font.width;
92 region.width = height * vc->vc_font.height;
93 region.rop = ROP_COPY;
94
95 info->fbops->fb_fillrect(info, &region);
96}
97
98static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
99 const u16 *s, u32 attr, u32 cnt,
100 u32 d_pitch, u32 s_pitch, u32 cellsize,
101 struct fb_image *image, u8 *buf, u8 *dst)
102{
103 struct fbcon_ops *ops = info->fbcon_par;
104 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
105 u32 idx = (vc->vc_font.height + 7) >> 3;
106 u8 *src;
107
108 while (cnt--) {
109 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
110
111 if (attr) {
112 ccw_update_attr(buf, src, attr, vc);
113 src = buf;
114 }
115
116 if (likely(idx == 1))
117 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
118 vc->vc_font.width);
119 else
120 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
121 vc->vc_font.width);
122
123 dst += d_pitch * vc->vc_font.width;
124 }
125
126 info->fbops->fb_imageblit(info, image);
127}
128
129static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
130 const unsigned short *s, int count, int yy, int xx,
131 int fg, int bg)
132{
133 struct fb_image image;
134 struct display *p = &fb_display[vc->vc_num];
135 struct fbcon_ops *ops = info->fbcon_par;
136 u32 width = (vc->vc_font.height + 7)/8;
137 u32 cellsize = width * vc->vc_font.width;
138 u32 maxcnt = info->pixmap.size/cellsize;
139 u32 scan_align = info->pixmap.scan_align - 1;
140 u32 buf_align = info->pixmap.buf_align - 1;
141 u32 cnt, pitch, size;
142 u32 attribute = get_attribute(info, scr_readw(s));
143 u8 *dst, *buf = NULL;
144 u32 vyres = GETVYRES(p->scrollmode, info);
145
146 if (!ops->fontbuffer)
147 return;
148
149 image.fg_color = fg;
150 image.bg_color = bg;
151 image.dx = yy * vc->vc_font.height;
152 image.dy = vyres - ((xx + count) * vc->vc_font.width);
153 image.width = vc->vc_font.height;
154 image.depth = 1;
155
156 if (attribute) {
157 buf = kmalloc(cellsize, GFP_KERNEL);
158 if (!buf)
159 return;
160 }
161
162 s += count - 1;
163
164 while (count) {
165 if (count > maxcnt)
166 cnt = maxcnt;
167 else
168 cnt = count;
169
170 image.height = vc->vc_font.width * cnt;
171 pitch = ((image.width + 7) >> 3) + scan_align;
172 pitch &= ~scan_align;
173 size = pitch * image.height + buf_align;
174 size &= ~buf_align;
175 dst = fb_get_buffer_offset(info, &info->pixmap, size);
176 image.data = dst;
177 ccw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
178 width, cellsize, &image, buf, dst);
179 image.dy += image.height;
180 count -= cnt;
181 s -= cnt;
182 }
183
184 /* buf is always NULL except when in monochrome mode, so in this case
185 it's a gain to check buf against NULL even though kfree() handles
186 NULL pointers just fine */
187 if (unlikely(buf))
188 kfree(buf);
189
190}
191
192static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
193 int bottom_only)
194{
195 unsigned int cw = vc->vc_font.width;
196 unsigned int ch = vc->vc_font.height;
197 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
198 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
199 unsigned int bs = vc->vc_rows*ch;
200 struct fb_fillrect region;
201 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
202
203 region.color = attr_bgcol_ec(bgshift,vc);
204 region.rop = ROP_COPY;
205
206 if (rw && !bottom_only) {
207 region.dx = 0;
208 region.dy = info->var.yoffset;
209 region.height = rw;
210 region.width = info->var.xres_virtual;
211 info->fbops->fb_fillrect(info, &region);
212 }
213
214 if (bh) {
215 region.dx = info->var.xoffset + bs;
216 region.dy = 0;
217 region.height = info->var.yres_virtual;
218 region.width = bh;
219 info->fbops->fb_fillrect(info, &region);
220 }
221}
222
223static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
224 struct display *p, int mode, int softback_lines,
225 int fg, int bg)
226{
227 struct fb_cursor cursor;
228 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
229 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
230 int w = (vc->vc_font.height + 7) >> 3, c;
231 int y = real_y(p, vc->vc_y);
232 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
233 int err = 1, dx, dy;
234 char *src;
235 u32 vyres = GETVYRES(p->scrollmode, info);
236
237 if (!ops->fontbuffer)
238 return;
239
240 cursor.set = 0;
241
242 if (softback_lines) {
243 if (y + softback_lines >= vc->vc_rows) {
244 mode = CM_ERASE;
245 ops->cursor_flash = 0;
246 return;
247 } else
248 y += softback_lines;
249 }
250
251 c = scr_readw((u16 *) vc->vc_pos);
252 attribute = get_attribute(info, c);
253 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
254
255 if (ops->cursor_state.image.data != src ||
256 ops->cursor_reset) {
257 ops->cursor_state.image.data = src;
258 cursor.set |= FB_CUR_SETIMAGE;
259 }
260
261 if (attribute) {
262 u8 *dst;
263
264 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
265 if (!dst)
266 return;
267 kfree(ops->cursor_data);
268 ops->cursor_data = dst;
269 ccw_update_attr(dst, src, attribute, vc);
270 src = dst;
271 }
272
273 if (ops->cursor_state.image.fg_color != fg ||
274 ops->cursor_state.image.bg_color != bg ||
275 ops->cursor_reset) {
276 ops->cursor_state.image.fg_color = fg;
277 ops->cursor_state.image.bg_color = bg;
278 cursor.set |= FB_CUR_SETCMAP;
279 }
280
281 if (ops->cursor_state.image.height != vc->vc_font.width ||
282 ops->cursor_state.image.width != vc->vc_font.height ||
283 ops->cursor_reset) {
284 ops->cursor_state.image.height = vc->vc_font.width;
285 ops->cursor_state.image.width = vc->vc_font.height;
286 cursor.set |= FB_CUR_SETSIZE;
287 }
288
289 dx = y * vc->vc_font.height;
290 dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
291
292 if (ops->cursor_state.image.dx != dx ||
293 ops->cursor_state.image.dy != dy ||
294 ops->cursor_reset) {
295 ops->cursor_state.image.dx = dx;
296 ops->cursor_state.image.dy = dy;
297 cursor.set |= FB_CUR_SETPOS;
298 }
299
300 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
301 ops->cursor_reset) {
302 ops->cursor_state.hot.x = cursor.hot.y = 0;
303 cursor.set |= FB_CUR_SETHOT;
304 }
305
306 if (cursor.set & FB_CUR_SETSIZE ||
307 vc->vc_cursor_type != p->cursor_shape ||
308 ops->cursor_state.mask == NULL ||
309 ops->cursor_reset) {
310 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
311 int cur_height, size, i = 0;
312 int width = (vc->vc_font.width + 7)/8;
313
314 if (!mask)
315 return;
316
317 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
318
319 if (!tmp) {
320 kfree(mask);
321 return;
322 }
323
324 kfree(ops->cursor_state.mask);
325 ops->cursor_state.mask = mask;
326
327 p->cursor_shape = vc->vc_cursor_type;
328 cursor.set |= FB_CUR_SETSHAPE;
329
330 switch (p->cursor_shape & CUR_HWMASK) {
331 case CUR_NONE:
332 cur_height = 0;
333 break;
334 case CUR_UNDERLINE:
335 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
336 break;
337 case CUR_LOWER_THIRD:
338 cur_height = vc->vc_font.height/3;
339 break;
340 case CUR_LOWER_HALF:
341 cur_height = vc->vc_font.height >> 1;
342 break;
343 case CUR_TWO_THIRDS:
344 cur_height = (vc->vc_font.height << 1)/3;
345 break;
346 case CUR_BLOCK:
347 default:
348 cur_height = vc->vc_font.height;
349 break;
350 }
351
352 size = (vc->vc_font.height - cur_height) * width;
353 while (size--)
354 tmp[i++] = 0;
355 size = cur_height * width;
356 while (size--)
357 tmp[i++] = 0xff;
358 memset(mask, 0, w * vc->vc_font.width);
359 rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
360 kfree(tmp);
361 }
362
363 switch (mode) {
364 case CM_ERASE:
365 ops->cursor_state.enable = 0;
366 break;
367 case CM_DRAW:
368 case CM_MOVE:
369 default:
370 ops->cursor_state.enable = (use_sw) ? 0 : 1;
371 break;
372 }
373
374 cursor.image.data = src;
375 cursor.image.fg_color = ops->cursor_state.image.fg_color;
376 cursor.image.bg_color = ops->cursor_state.image.bg_color;
377 cursor.image.dx = ops->cursor_state.image.dx;
378 cursor.image.dy = ops->cursor_state.image.dy;
379 cursor.image.height = ops->cursor_state.image.height;
380 cursor.image.width = ops->cursor_state.image.width;
381 cursor.hot.x = ops->cursor_state.hot.x;
382 cursor.hot.y = ops->cursor_state.hot.y;
383 cursor.mask = ops->cursor_state.mask;
384 cursor.enable = ops->cursor_state.enable;
385 cursor.image.depth = 1;
386 cursor.rop = ROP_XOR;
387
388 if (info->fbops->fb_cursor)
389 err = info->fbops->fb_cursor(info, &cursor);
390
391 if (err)
392 soft_cursor(info, &cursor);
393
394 ops->cursor_reset = 0;
395}
396
397int ccw_update_start(struct fb_info *info)
398{
399 struct fbcon_ops *ops = info->fbcon_par;
400 struct display *p = &fb_display[ops->currcon];
401 u32 yoffset;
402 u32 vyres = GETVYRES(p->scrollmode, info);
403 int err;
404
405 yoffset = (vyres - info->var.yres) - ops->var.xoffset;
406 ops->var.xoffset = ops->var.yoffset;
407 ops->var.yoffset = yoffset;
408 err = fb_pan_display(info, &ops->var);
409 ops->var.xoffset = info->var.xoffset;
410 ops->var.yoffset = info->var.yoffset;
411 ops->var.vmode = info->var.vmode;
412 return err;
413}
414
415void fbcon_rotate_ccw(struct fbcon_ops *ops)
416{
417 ops->bmove = ccw_bmove;
418 ops->clear = ccw_clear;
419 ops->putcs = ccw_putcs;
420 ops->clear_margins = ccw_clear_margins;
421 ops->cursor = ccw_cursor;
422 ops->update_start = ccw_update_start;
423}
424EXPORT_SYMBOL(fbcon_rotate_ccw);
425
426MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
427MODULE_DESCRIPTION("Console Rotation (270 degrees) Support");
428MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
new file mode 100644
index 000000000000..6c6f3b6dd175
--- /dev/null
+++ b/drivers/video/console/fbcon_cw.c
@@ -0,0 +1,412 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 90 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 90 degrees
23 */
24
25static inline void cw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 u8 c, t = 0, msk = ~(0xff >> offset);
31
32 for (i = 0; i < vc->vc_font.width; i++) {
33 for (j = 0; j < width; j++) {
34 c = *src;
35 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && !j)
36 c |= msk;
37 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
38 c |= *(src-width);
39 if (attribute & FBCON_ATTRIBUTE_REVERSE)
40 c = ~c;
41 src++;
42 *dst++ = c;
43 t = c;
44 }
45 }
46}
47
48
49static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
50 int sx, int dy, int dx, int height, int width)
51{
52 struct display *p = &fb_display[vc->vc_num];
53 struct fb_copyarea area;
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sx = vxres - ((sy + height) * vc->vc_font.height);
57 area.sy = sx * vc->vc_font.width;
58 area.dx = vxres - ((dy + height) * vc->vc_font.height);
59 area.dy = dx * vc->vc_font.width;
60 area.width = height * vc->vc_font.height;
61 area.height = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vxres = GETVXRES(p->scrollmode, info);
73
74 region.color = attr_bgcol_ec(bgshift,vc);
75 region.dx = vxres - ((sy + height) * vc->vc_font.height);
76 region.dy = sx * vc->vc_font.width;
77 region.height = width * vc->vc_font.width;
78 region.width = height * vc->vc_font.height;
79 region.rop = ROP_COPY;
80
81 info->fbops->fb_fillrect(info, &region);
82}
83
84static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
85 const u16 *s, u32 attr, u32 cnt,
86 u32 d_pitch, u32 s_pitch, u32 cellsize,
87 struct fb_image *image, u8 *buf, u8 *dst)
88{
89 struct fbcon_ops *ops = info->fbcon_par;
90 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
91 u32 idx = (vc->vc_font.height + 7) >> 3;
92 u8 *src;
93
94 while (cnt--) {
95 src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
96
97 if (attr) {
98 cw_update_attr(buf, src, attr, vc);
99 src = buf;
100 }
101
102 if (likely(idx == 1))
103 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
104 vc->vc_font.width);
105 else
106 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
107 vc->vc_font.width);
108
109 dst += d_pitch * vc->vc_font.width;
110 }
111
112 info->fbops->fb_imageblit(info, image);
113}
114
115static void cw_putcs(struct vc_data *vc, struct fb_info *info,
116 const unsigned short *s, int count, int yy, int xx,
117 int fg, int bg)
118{
119 struct fb_image image;
120 struct display *p = &fb_display[vc->vc_num];
121 struct fbcon_ops *ops = info->fbcon_par;
122 u32 width = (vc->vc_font.height + 7)/8;
123 u32 cellsize = width * vc->vc_font.width;
124 u32 maxcnt = info->pixmap.size/cellsize;
125 u32 scan_align = info->pixmap.scan_align - 1;
126 u32 buf_align = info->pixmap.buf_align - 1;
127 u32 cnt, pitch, size;
128 u32 attribute = get_attribute(info, scr_readw(s));
129 u8 *dst, *buf = NULL;
130 u32 vxres = GETVXRES(p->scrollmode, info);
131
132 if (!ops->fontbuffer)
133 return;
134
135 image.fg_color = fg;
136 image.bg_color = bg;
137 image.dx = vxres - ((yy + 1) * vc->vc_font.height);
138 image.dy = xx * vc->vc_font.width;
139 image.width = vc->vc_font.height;
140 image.depth = 1;
141
142 if (attribute) {
143 buf = kmalloc(cellsize, GFP_KERNEL);
144 if (!buf)
145 return;
146 }
147
148 while (count) {
149 if (count > maxcnt)
150 cnt = maxcnt;
151 else
152 cnt = count;
153
154 image.height = vc->vc_font.width * cnt;
155 pitch = ((image.width + 7) >> 3) + scan_align;
156 pitch &= ~scan_align;
157 size = pitch * image.height + buf_align;
158 size &= ~buf_align;
159 dst = fb_get_buffer_offset(info, &info->pixmap, size);
160 image.data = dst;
161 cw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
162 width, cellsize, &image, buf, dst);
163 image.dy += image.height;
164 count -= cnt;
165 s += cnt;
166 }
167
168 /* buf is always NULL except when in monochrome mode, so in this case
169 it's a gain to check buf against NULL even though kfree() handles
170 NULL pointers just fine */
171 if (unlikely(buf))
172 kfree(buf);
173
174}
175
176static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
177 int bottom_only)
178{
179 unsigned int cw = vc->vc_font.width;
180 unsigned int ch = vc->vc_font.height;
181 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
182 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
183 unsigned int rs = info->var.yres - rw;
184 struct fb_fillrect region;
185 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
186
187 region.color = attr_bgcol_ec(bgshift,vc);
188 region.rop = ROP_COPY;
189
190 if (rw && !bottom_only) {
191 region.dx = 0;
192 region.dy = info->var.yoffset + rs;
193 region.height = rw;
194 region.width = info->var.xres_virtual;
195 info->fbops->fb_fillrect(info, &region);
196 }
197
198 if (bh) {
199 region.dx = info->var.xoffset;
200 region.dy = info->var.yoffset;
201 region.height = info->var.yres;
202 region.width = bh;
203 info->fbops->fb_fillrect(info, &region);
204 }
205}
206
207static void cw_cursor(struct vc_data *vc, struct fb_info *info,
208 struct display *p, int mode, int softback_lines,
209 int fg, int bg)
210{
211 struct fb_cursor cursor;
212 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
213 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
214 int w = (vc->vc_font.height + 7) >> 3, c;
215 int y = real_y(p, vc->vc_y);
216 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
217 int err = 1, dx, dy;
218 char *src;
219 u32 vxres = GETVXRES(p->scrollmode, info);
220
221 if (!ops->fontbuffer)
222 return;
223
224 cursor.set = 0;
225
226 if (softback_lines) {
227 if (y + softback_lines >= vc->vc_rows) {
228 mode = CM_ERASE;
229 ops->cursor_flash = 0;
230 return;
231 } else
232 y += softback_lines;
233 }
234
235 c = scr_readw((u16 *) vc->vc_pos);
236 attribute = get_attribute(info, c);
237 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
238
239 if (ops->cursor_state.image.data != src ||
240 ops->cursor_reset) {
241 ops->cursor_state.image.data = src;
242 cursor.set |= FB_CUR_SETIMAGE;
243 }
244
245 if (attribute) {
246 u8 *dst;
247
248 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
249 if (!dst)
250 return;
251 kfree(ops->cursor_data);
252 ops->cursor_data = dst;
253 cw_update_attr(dst, src, attribute, vc);
254 src = dst;
255 }
256
257 if (ops->cursor_state.image.fg_color != fg ||
258 ops->cursor_state.image.bg_color != bg ||
259 ops->cursor_reset) {
260 ops->cursor_state.image.fg_color = fg;
261 ops->cursor_state.image.bg_color = bg;
262 cursor.set |= FB_CUR_SETCMAP;
263 }
264
265 if (ops->cursor_state.image.height != vc->vc_font.width ||
266 ops->cursor_state.image.width != vc->vc_font.height ||
267 ops->cursor_reset) {
268 ops->cursor_state.image.height = vc->vc_font.width;
269 ops->cursor_state.image.width = vc->vc_font.height;
270 cursor.set |= FB_CUR_SETSIZE;
271 }
272
273 dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
274 dy = vc->vc_x * vc->vc_font.width;
275
276 if (ops->cursor_state.image.dx != dx ||
277 ops->cursor_state.image.dy != dy ||
278 ops->cursor_reset) {
279 ops->cursor_state.image.dx = dx;
280 ops->cursor_state.image.dy = dy;
281 cursor.set |= FB_CUR_SETPOS;
282 }
283
284 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
285 ops->cursor_reset) {
286 ops->cursor_state.hot.x = cursor.hot.y = 0;
287 cursor.set |= FB_CUR_SETHOT;
288 }
289
290 if (cursor.set & FB_CUR_SETSIZE ||
291 vc->vc_cursor_type != p->cursor_shape ||
292 ops->cursor_state.mask == NULL ||
293 ops->cursor_reset) {
294 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
295 int cur_height, size, i = 0;
296 int width = (vc->vc_font.width + 7)/8;
297
298 if (!mask)
299 return;
300
301 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
302
303 if (!tmp) {
304 kfree(mask);
305 return;
306 }
307
308 kfree(ops->cursor_state.mask);
309 ops->cursor_state.mask = mask;
310
311 p->cursor_shape = vc->vc_cursor_type;
312 cursor.set |= FB_CUR_SETSHAPE;
313
314 switch (p->cursor_shape & CUR_HWMASK) {
315 case CUR_NONE:
316 cur_height = 0;
317 break;
318 case CUR_UNDERLINE:
319 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
320 break;
321 case CUR_LOWER_THIRD:
322 cur_height = vc->vc_font.height/3;
323 break;
324 case CUR_LOWER_HALF:
325 cur_height = vc->vc_font.height >> 1;
326 break;
327 case CUR_TWO_THIRDS:
328 cur_height = (vc->vc_font.height << 1)/3;
329 break;
330 case CUR_BLOCK:
331 default:
332 cur_height = vc->vc_font.height;
333 break;
334 }
335
336 size = (vc->vc_font.height - cur_height) * width;
337 while (size--)
338 tmp[i++] = 0;
339 size = cur_height * width;
340 while (size--)
341 tmp[i++] = 0xff;
342 memset(mask, 0, w * vc->vc_font.width);
343 rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
344 kfree(tmp);
345 }
346
347 switch (mode) {
348 case CM_ERASE:
349 ops->cursor_state.enable = 0;
350 break;
351 case CM_DRAW:
352 case CM_MOVE:
353 default:
354 ops->cursor_state.enable = (use_sw) ? 0 : 1;
355 break;
356 }
357
358 cursor.image.data = src;
359 cursor.image.fg_color = ops->cursor_state.image.fg_color;
360 cursor.image.bg_color = ops->cursor_state.image.bg_color;
361 cursor.image.dx = ops->cursor_state.image.dx;
362 cursor.image.dy = ops->cursor_state.image.dy;
363 cursor.image.height = ops->cursor_state.image.height;
364 cursor.image.width = ops->cursor_state.image.width;
365 cursor.hot.x = ops->cursor_state.hot.x;
366 cursor.hot.y = ops->cursor_state.hot.y;
367 cursor.mask = ops->cursor_state.mask;
368 cursor.enable = ops->cursor_state.enable;
369 cursor.image.depth = 1;
370 cursor.rop = ROP_XOR;
371
372 if (info->fbops->fb_cursor)
373 err = info->fbops->fb_cursor(info, &cursor);
374
375 if (err)
376 soft_cursor(info, &cursor);
377
378 ops->cursor_reset = 0;
379}
380
381int cw_update_start(struct fb_info *info)
382{
383 struct fbcon_ops *ops = info->fbcon_par;
384 struct display *p = &fb_display[ops->currcon];
385 u32 vxres = GETVXRES(p->scrollmode, info);
386 u32 xoffset;
387 int err;
388
389 xoffset = vxres - (info->var.xres + ops->var.yoffset);
390 ops->var.yoffset = ops->var.xoffset;
391 ops->var.xoffset = xoffset;
392 err = fb_pan_display(info, &ops->var);
393 ops->var.xoffset = info->var.xoffset;
394 ops->var.yoffset = info->var.yoffset;
395 ops->var.vmode = info->var.vmode;
396 return err;
397}
398
399void fbcon_rotate_cw(struct fbcon_ops *ops)
400{
401 ops->bmove = cw_bmove;
402 ops->clear = cw_clear;
403 ops->putcs = cw_putcs;
404 ops->clear_margins = cw_clear_margins;
405 ops->cursor = cw_cursor;
406 ops->update_start = cw_update_start;
407}
408EXPORT_SYMBOL(fbcon_rotate_cw);
409
410MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
411MODULE_DESCRIPTION("Console Rotation (90 degrees) Support");
412MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c
new file mode 100644
index 000000000000..ec0dd8fe241c
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.c
@@ -0,0 +1,117 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.c -- Software Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
22 struct display *p)
23{
24 struct fbcon_ops *ops = info->fbcon_par;
25 int len, err = 0;
26 int s_cellsize, d_cellsize, i;
27 const u8 *src;
28 u8 *dst;
29
30 if (vc->vc_font.data == ops->fontdata &&
31 p->con_rotate == ops->cur_rotate)
32 goto finished;
33
34 src = ops->fontdata = vc->vc_font.data;
35 ops->cur_rotate = p->con_rotate;
36 len = (!p->userfont) ? 256 : FNTCHARCNT(src);
37 s_cellsize = ((vc->vc_font.width + 7)/8) *
38 vc->vc_font.height;
39 d_cellsize = s_cellsize;
40
41 if (ops->rotate == FB_ROTATE_CW ||
42 ops->rotate == FB_ROTATE_CCW)
43 d_cellsize = ((vc->vc_font.height + 7)/8) *
44 vc->vc_font.width;
45
46 if (info->fbops->fb_sync)
47 info->fbops->fb_sync(info);
48
49 if (ops->fd_size < d_cellsize * len) {
50 dst = kmalloc(d_cellsize * len, GFP_KERNEL);
51
52 if (dst == NULL) {
53 err = -ENOMEM;
54 goto finished;
55 }
56
57 ops->fd_size = d_cellsize * len;
58 kfree(ops->fontbuffer);
59 ops->fontbuffer = dst;
60 }
61
62 dst = ops->fontbuffer;
63 memset(dst, 0, ops->fd_size);
64
65 switch (ops->rotate) {
66 case FB_ROTATE_UD:
67 for (i = len; i--; ) {
68 rotate_ud(src, dst, vc->vc_font.width,
69 vc->vc_font.height);
70
71 src += s_cellsize;
72 dst += d_cellsize;
73 }
74 break;
75 case FB_ROTATE_CW:
76 for (i = len; i--; ) {
77 rotate_cw(src, dst, vc->vc_font.width,
78 vc->vc_font.height);
79 src += s_cellsize;
80 dst += d_cellsize;
81 }
82 break;
83 case FB_ROTATE_CCW:
84 for (i = len; i--; ) {
85 rotate_ccw(src, dst, vc->vc_font.width,
86 vc->vc_font.height);
87 src += s_cellsize;
88 dst += d_cellsize;
89 }
90 break;
91 }
92
93finished:
94 return err;
95}
96
97void fbcon_set_rotate(struct fbcon_ops *ops)
98{
99 ops->rotate_font = fbcon_rotate_font;
100
101 switch(ops->rotate) {
102 case FB_ROTATE_CW:
103 fbcon_rotate_cw(ops);
104 break;
105 case FB_ROTATE_UD:
106 fbcon_rotate_ud(ops);
107 break;
108 case FB_ROTATE_CCW:
109 fbcon_rotate_ccw(ops);
110 break;
111 }
112}
113EXPORT_SYMBOL(fbcon_set_rotate);
114
115MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
116MODULE_DESCRIPTION("Console Rotation Support");
117MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h
new file mode 100644
index 000000000000..90c672096c2e
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.h
@@ -0,0 +1,105 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#ifndef _FBCON_ROTATE_H
12#define _FBCON_ROTATE_H
13
14#define FNTCHARCNT(fd) (((int *)(fd))[-3])
15
16#define GETVYRES(s,i) ({ \
17 (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
18 (i)->var.yres : (i)->var.yres_virtual; })
19
20#define GETVXRES(s,i) ({ \
21 (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
22 (i)->var.xres : (i)->var.xres_virtual; })
23
24/*
25 * The bitmap is always big endian
26 */
27#if defined(__LITTLE_ENDIAN)
28#define FBCON_BIT(b) (7 - (b))
29#else
30#define FBCON_BIT(b) (b)
31#endif
32
33static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
34{
35 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
36
37 pat +=index;
38 return (test_bit(FBCON_BIT(bit), (void *)pat));
39}
40
41static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
42{
43 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
44
45 pat += index;
46 set_bit(FBCON_BIT(bit), (void *)pat);
47}
48
49static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
50{
51 int i, j;
52 int shift = width % 8;
53
54 width = (width + 7) & ~7;
55
56 for (i = 0; i < height; i++) {
57 for (j = 0; j < width; j++) {
58 if (pattern_test_bit(j, i, width, in))
59 pattern_set_bit(width - (1 + j + shift),
60 height - (1 + i),
61 width, out);
62 }
63
64 }
65}
66
67static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
68{
69 int i, j, h = height, w = width;
70 int shift = (8 - (height % 8)) & 7;
71
72 width = (width + 7) & ~7;
73 height = (height + 7) & ~7;
74
75 for (i = 0; i < h; i++) {
76 for (j = 0; j < w; j++) {
77 if (pattern_test_bit(j, i, width, in))
78 pattern_set_bit(height - 1 - i - shift, j,
79 height, out);
80
81 }
82 }
83}
84
85static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
86{
87 int i, j, h = height, w = width;
88 int shift = width % 8;
89
90 width = (width + 7) & ~7;
91 height = (height + 7) & ~7;
92
93 for (i = 0; i < h; i++) {
94 for (j = 0; j < w; j++) {
95 if (pattern_test_bit(j, i, width, in))
96 pattern_set_bit(i, width - 1 - j - shift,
97 height, out);
98 }
99 }
100}
101
102extern void fbcon_rotate_cw(struct fbcon_ops *ops);
103extern void fbcon_rotate_ud(struct fbcon_ops *ops);
104extern void fbcon_rotate_ccw(struct fbcon_ops *ops);
105#endif
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
new file mode 100644
index 000000000000..2e1d9d4249cd
--- /dev/null
+++ b/drivers/video/console/fbcon_ud.c
@@ -0,0 +1,454 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 180 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 180 degrees
23 */
24
25static inline void ud_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.width + 7) >> 3;
30 unsigned int cellsize = vc->vc_font.height * width;
31 u8 c;
32
33 offset = offset * width;
34
35 for (i = 0; i < cellsize; i++) {
36 c = src[i];
37 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i < offset)
38 c = 0xff;
39 if (attribute & FBCON_ATTRIBUTE_BOLD)
40 c |= c << 1;
41 if (attribute & FBCON_ATTRIBUTE_REVERSE)
42 c = ~c;
43 dst[i] = c;
44 }
45}
46
47
48static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
49 int sx, int dy, int dx, int height, int width)
50{
51 struct display *p = &fb_display[vc->vc_num];
52 struct fb_copyarea area;
53 u32 vyres = GETVYRES(p->scrollmode, info);
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sy = vyres - ((sy + height) * vc->vc_font.height);
57 area.sx = vxres - ((sx + width) * vc->vc_font.width);
58 area.dy = vyres - ((dy + height) * vc->vc_font.height);
59 area.dx = vxres - ((dx + width) * vc->vc_font.width);
60 area.height = height * vc->vc_font.height;
61 area.width = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vyres = GETVYRES(p->scrollmode, info);
73 u32 vxres = GETVXRES(p->scrollmode, info);
74
75 region.color = attr_bgcol_ec(bgshift,vc);
76 region.dy = vyres - ((sy + height) * vc->vc_font.height);
77 region.dx = vxres - ((sx + width) * vc->vc_font.width);
78 region.width = width * vc->vc_font.width;
79 region.height = height * vc->vc_font.height;
80 region.rop = ROP_COPY;
81
82 info->fbops->fb_fillrect(info, &region);
83}
84
85static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
86 const u16 *s, u32 attr, u32 cnt,
87 u32 d_pitch, u32 s_pitch, u32 cellsize,
88 struct fb_image *image, u8 *buf, u8 *dst)
89{
90 struct fbcon_ops *ops = info->fbcon_par;
91 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
92 u32 idx = vc->vc_font.width >> 3;
93 u8 *src;
94
95 while (cnt--) {
96 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
97
98 if (attr) {
99 ud_update_attr(buf, src, attr, vc);
100 src = buf;
101 }
102
103 if (likely(idx == 1))
104 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
105 image->height);
106 else
107 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
108 image->height);
109
110 dst += s_pitch;
111 }
112
113 info->fbops->fb_imageblit(info, image);
114}
115
116static inline void ud_putcs_unaligned(struct vc_data *vc,
117 struct fb_info *info, const u16 *s,
118 u32 attr, u32 cnt, u32 d_pitch,
119 u32 s_pitch, u32 cellsize,
120 struct fb_image *image, u8 *buf,
121 u8 *dst)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
125 u32 shift_low = 0, mod = vc->vc_font.width % 8;
126 u32 shift_high = 8;
127 u32 idx = vc->vc_font.width >> 3;
128 u8 *src;
129
130 while (cnt--) {
131 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
132
133 if (attr) {
134 ud_update_attr(buf, src, attr, vc);
135 src = buf;
136 }
137
138 fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
139 image->height, shift_high,
140 shift_low, mod);
141 shift_low += mod;
142 dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
143 shift_low &= 7;
144 shift_high = 8 - shift_low;
145 }
146
147 info->fbops->fb_imageblit(info, image);
148
149}
150
151static void ud_putcs(struct vc_data *vc, struct fb_info *info,
152 const unsigned short *s, int count, int yy, int xx,
153 int fg, int bg)
154{
155 struct fb_image image;
156 struct display *p = &fb_display[vc->vc_num];
157 struct fbcon_ops *ops = info->fbcon_par;
158 u32 width = (vc->vc_font.width + 7)/8;
159 u32 cellsize = width * vc->vc_font.height;
160 u32 maxcnt = info->pixmap.size/cellsize;
161 u32 scan_align = info->pixmap.scan_align - 1;
162 u32 buf_align = info->pixmap.buf_align - 1;
163 u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
164 u32 attribute = get_attribute(info, scr_readw(s));
165 u8 *dst, *buf = NULL;
166 u32 vyres = GETVYRES(p->scrollmode, info);
167 u32 vxres = GETVXRES(p->scrollmode, info);
168
169 if (!ops->fontbuffer)
170 return;
171
172 image.fg_color = fg;
173 image.bg_color = bg;
174 image.dy = vyres - ((yy * vc->vc_font.height) + vc->vc_font.height);
175 image.dx = vxres - ((xx + count) * vc->vc_font.width);
176 image.height = vc->vc_font.height;
177 image.depth = 1;
178
179 if (attribute) {
180 buf = kmalloc(cellsize, GFP_KERNEL);
181 if (!buf)
182 return;
183 }
184
185 s += count - 1;
186
187 while (count) {
188 if (count > maxcnt)
189 cnt = maxcnt;
190 else
191 cnt = count;
192
193 image.width = vc->vc_font.width * cnt;
194 pitch = ((image.width + 7) >> 3) + scan_align;
195 pitch &= ~scan_align;
196 size = pitch * image.height + buf_align;
197 size &= ~buf_align;
198 dst = fb_get_buffer_offset(info, &info->pixmap, size);
199 image.data = dst;
200
201 if (!mod)
202 ud_putcs_aligned(vc, info, s, attribute, cnt, pitch,
203 width, cellsize, &image, buf, dst);
204 else
205 ud_putcs_unaligned(vc, info, s, attribute, cnt, pitch,
206 width, cellsize, &image,
207 buf, dst);
208
209 image.dx += image.width;
210 count -= cnt;
211 s -= cnt;
212 xx += cnt;
213 }
214
215 /* buf is always NULL except when in monochrome mode, so in this case
216 it's a gain to check buf against NULL even though kfree() handles
217 NULL pointers just fine */
218 if (unlikely(buf))
219 kfree(buf);
220
221}
222
223static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
224 int bottom_only)
225{
226 unsigned int cw = vc->vc_font.width;
227 unsigned int ch = vc->vc_font.height;
228 unsigned int rw = info->var.xres - (vc->vc_cols*cw);
229 unsigned int bh = info->var.yres - (vc->vc_rows*ch);
230 struct fb_fillrect region;
231 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
232
233 region.color = attr_bgcol_ec(bgshift,vc);
234 region.rop = ROP_COPY;
235
236 if (rw && !bottom_only) {
237 region.dy = 0;
238 region.dx = info->var.xoffset;
239 region.width = rw;
240 region.height = info->var.yres_virtual;
241 info->fbops->fb_fillrect(info, &region);
242 }
243
244 if (bh) {
245 region.dy = info->var.yoffset;
246 region.dx = info->var.xoffset;
247 region.height = bh;
248 region.width = info->var.xres;
249 info->fbops->fb_fillrect(info, &region);
250 }
251}
252
253static void ud_cursor(struct vc_data *vc, struct fb_info *info,
254 struct display *p, int mode, int softback_lines,
255 int fg, int bg)
256{
257 struct fb_cursor cursor;
258 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
259 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
260 int w = (vc->vc_font.width + 7) >> 3, c;
261 int y = real_y(p, vc->vc_y);
262 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
263 int err = 1, dx, dy;
264 char *src;
265 u32 vyres = GETVYRES(p->scrollmode, info);
266 u32 vxres = GETVXRES(p->scrollmode, info);
267
268 if (!ops->fontbuffer)
269 return;
270
271 cursor.set = 0;
272
273 if (softback_lines) {
274 if (y + softback_lines >= vc->vc_rows) {
275 mode = CM_ERASE;
276 ops->cursor_flash = 0;
277 return;
278 } else
279 y += softback_lines;
280 }
281
282 c = scr_readw((u16 *) vc->vc_pos);
283 attribute = get_attribute(info, c);
284 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
285
286 if (ops->cursor_state.image.data != src ||
287 ops->cursor_reset) {
288 ops->cursor_state.image.data = src;
289 cursor.set |= FB_CUR_SETIMAGE;
290 }
291
292 if (attribute) {
293 u8 *dst;
294
295 dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
296 if (!dst)
297 return;
298 kfree(ops->cursor_data);
299 ops->cursor_data = dst;
300 ud_update_attr(dst, src, attribute, vc);
301 src = dst;
302 }
303
304 if (ops->cursor_state.image.fg_color != fg ||
305 ops->cursor_state.image.bg_color != bg ||
306 ops->cursor_reset) {
307 ops->cursor_state.image.fg_color = fg;
308 ops->cursor_state.image.bg_color = bg;
309 cursor.set |= FB_CUR_SETCMAP;
310 }
311
312 if (ops->cursor_state.image.height != vc->vc_font.height ||
313 ops->cursor_state.image.width != vc->vc_font.width ||
314 ops->cursor_reset) {
315 ops->cursor_state.image.height = vc->vc_font.height;
316 ops->cursor_state.image.width = vc->vc_font.width;
317 cursor.set |= FB_CUR_SETSIZE;
318 }
319
320 dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
321 dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
322
323 if (ops->cursor_state.image.dx != dx ||
324 ops->cursor_state.image.dy != dy ||
325 ops->cursor_reset) {
326 ops->cursor_state.image.dx = dx;
327 ops->cursor_state.image.dy = dy;
328 cursor.set |= FB_CUR_SETPOS;
329 }
330
331 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
332 ops->cursor_reset) {
333 ops->cursor_state.hot.x = cursor.hot.y = 0;
334 cursor.set |= FB_CUR_SETHOT;
335 }
336
337 if (cursor.set & FB_CUR_SETSIZE ||
338 vc->vc_cursor_type != p->cursor_shape ||
339 ops->cursor_state.mask == NULL ||
340 ops->cursor_reset) {
341 char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
342 int cur_height, size, i = 0;
343 u8 msk = 0xff;
344
345 if (!mask)
346 return;
347
348 kfree(ops->cursor_state.mask);
349 ops->cursor_state.mask = mask;
350
351 p->cursor_shape = vc->vc_cursor_type;
352 cursor.set |= FB_CUR_SETSHAPE;
353
354 switch (p->cursor_shape & CUR_HWMASK) {
355 case CUR_NONE:
356 cur_height = 0;
357 break;
358 case CUR_UNDERLINE:
359 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
360 break;
361 case CUR_LOWER_THIRD:
362 cur_height = vc->vc_font.height/3;
363 break;
364 case CUR_LOWER_HALF:
365 cur_height = vc->vc_font.height >> 1;
366 break;
367 case CUR_TWO_THIRDS:
368 cur_height = (vc->vc_font.height << 1)/3;
369 break;
370 case CUR_BLOCK:
371 default:
372 cur_height = vc->vc_font.height;
373 break;
374 }
375
376 size = cur_height * w;
377
378 while (size--)
379 mask[i++] = msk;
380
381 size = (vc->vc_font.height - cur_height) * w;
382
383 while (size--)
384 mask[i++] = ~msk;
385 }
386
387 switch (mode) {
388 case CM_ERASE:
389 ops->cursor_state.enable = 0;
390 break;
391 case CM_DRAW:
392 case CM_MOVE:
393 default:
394 ops->cursor_state.enable = (use_sw) ? 0 : 1;
395 break;
396 }
397
398 cursor.image.data = src;
399 cursor.image.fg_color = ops->cursor_state.image.fg_color;
400 cursor.image.bg_color = ops->cursor_state.image.bg_color;
401 cursor.image.dx = ops->cursor_state.image.dx;
402 cursor.image.dy = ops->cursor_state.image.dy;
403 cursor.image.height = ops->cursor_state.image.height;
404 cursor.image.width = ops->cursor_state.image.width;
405 cursor.hot.x = ops->cursor_state.hot.x;
406 cursor.hot.y = ops->cursor_state.hot.y;
407 cursor.mask = ops->cursor_state.mask;
408 cursor.enable = ops->cursor_state.enable;
409 cursor.image.depth = 1;
410 cursor.rop = ROP_XOR;
411
412 if (info->fbops->fb_cursor)
413 err = info->fbops->fb_cursor(info, &cursor);
414
415 if (err)
416 soft_cursor(info, &cursor);
417
418 ops->cursor_reset = 0;
419}
420
421int ud_update_start(struct fb_info *info)
422{
423 struct fbcon_ops *ops = info->fbcon_par;
424 struct display *p = &fb_display[ops->currcon];
425 u32 xoffset, yoffset;
426 u32 vyres = GETVYRES(p->scrollmode, info);
427 u32 vxres = GETVXRES(p->scrollmode, info);
428 int err;
429
430 xoffset = (vxres - info->var.xres) - ops->var.xoffset;
431 yoffset = (vyres - info->var.yres) - ops->var.yoffset;
432 ops->var.xoffset = xoffset;
433 ops->var.yoffset = yoffset;
434 err = fb_pan_display(info, &ops->var);
435 ops->var.xoffset = info->var.xoffset;
436 ops->var.yoffset = info->var.yoffset;
437 ops->var.vmode = info->var.vmode;
438 return err;
439}
440
441void fbcon_rotate_ud(struct fbcon_ops *ops)
442{
443 ops->bmove = ud_bmove;
444 ops->clear = ud_clear;
445 ops->putcs = ud_putcs;
446 ops->clear_margins = ud_clear_margins;
447 ops->cursor = ud_cursor;
448 ops->update_start = ud_update_start;
449}
450EXPORT_SYMBOL(fbcon_rotate_ud);
451
452MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
453MODULE_DESCRIPTION("Console Rotation (180 degrees) Support");
454MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 7f76e2c6a4a1..cb25324a5635 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -118,6 +118,18 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info,
118 info->tileops->fb_tilecursor(info, &cursor); 118 info->tileops->fb_tilecursor(info, &cursor);
119} 119}
120 120
121static int tile_update_start(struct fb_info *info)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 int err;
125
126 err = fb_pan_display(info, &ops->var);
127 ops->var.xoffset = info->var.xoffset;
128 ops->var.yoffset = info->var.yoffset;
129 ops->var.vmode = info->var.vmode;
130 return err;
131}
132
121void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, 133void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
122 struct display *p, struct fbcon_ops *ops) 134 struct display *p, struct fbcon_ops *ops)
123{ 135{
@@ -128,6 +140,7 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
128 ops->putcs = tile_putcs; 140 ops->putcs = tile_putcs;
129 ops->clear_margins = tile_clear_margins; 141 ops->clear_margins = tile_clear_margins;
130 ops->cursor = tile_cursor; 142 ops->cursor = tile_cursor;
143 ops->update_start = tile_update_start;
131 144
132 if (p) { 145 if (p) {
133 map.width = vc->vc_font.width; 146 map.width = vc->vc_font.width;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e2667ddab3f1..9f180096c896 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -14,6 +14,7 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16 16
17#include <linux/compat.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
19#include <linux/sched.h> 20#include <linux/sched.h>
@@ -323,9 +324,103 @@ static struct logo_data {
323 const struct linux_logo *logo; 324 const struct linux_logo *logo;
324} fb_logo; 325} fb_logo;
325 326
326int fb_prepare_logo(struct fb_info *info) 327static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
328{
329 u32 size = width * height, i;
330
331 out += size - 1;
332
333 for (i = size; i--; )
334 *out-- = *in++;
335}
336
337static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
338{
339 int i, j, w = width - 1;
340
341 for (i = 0; i < height; i++)
342 for (j = 0; j < width; j++)
343 out[height * j + w - i] = *in++;
344}
345
346static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
347{
348 int i, j, w = width - 1;
349
350 for (i = 0; i < height; i++)
351 for (j = 0; j < width; j++)
352 out[height * (w - j) + i] = *in++;
353}
354
355static void fb_rotate_logo(struct fb_info *info, u8 *dst,
356 struct fb_image *image, int rotate)
357{
358 u32 tmp;
359
360 if (rotate == FB_ROTATE_UD) {
361 image->dx = info->var.xres - image->width;
362 image->dy = info->var.yres - image->height;
363 fb_rotate_logo_ud(image->data, dst, image->width,
364 image->height);
365 } else if (rotate == FB_ROTATE_CW) {
366 tmp = image->width;
367 image->width = image->height;
368 image->height = tmp;
369 image->dx = info->var.xres - image->height;
370 fb_rotate_logo_cw(image->data, dst, image->width,
371 image->height);
372 } else if (rotate == FB_ROTATE_CCW) {
373 tmp = image->width;
374 image->width = image->height;
375 image->height = tmp;
376 image->dy = info->var.yres - image->width;
377 fb_rotate_logo_ccw(image->data, dst, image->width,
378 image->height);
379 }
380
381 image->data = dst;
382}
383
384static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
385 int rotate)
386{
387 int x;
388
389 if (rotate == FB_ROTATE_UR) {
390 for (x = 0; x < num_online_cpus() &&
391 x * (fb_logo.logo->width + 8) <=
392 info->var.xres - fb_logo.logo->width; x++) {
393 info->fbops->fb_imageblit(info, image);
394 image->dx += fb_logo.logo->width + 8;
395 }
396 } else if (rotate == FB_ROTATE_UD) {
397 for (x = 0; x < num_online_cpus() &&
398 x * (fb_logo.logo->width + 8) <=
399 info->var.xres - fb_logo.logo->width; x++) {
400 info->fbops->fb_imageblit(info, image);
401 image->dx -= fb_logo.logo->width + 8;
402 }
403 } else if (rotate == FB_ROTATE_CW) {
404 for (x = 0; x < num_online_cpus() &&
405 x * (fb_logo.logo->width + 8) <=
406 info->var.yres - fb_logo.logo->width; x++) {
407 info->fbops->fb_imageblit(info, image);
408 image->dy += fb_logo.logo->width + 8;
409 }
410 } else if (rotate == FB_ROTATE_CCW) {
411 for (x = 0; x < num_online_cpus() &&
412 x * (fb_logo.logo->width + 8) <=
413 info->var.yres - fb_logo.logo->width; x++) {
414 info->fbops->fb_imageblit(info, image);
415 image->dy -= fb_logo.logo->width + 8;
416 }
417 }
418}
419
420int fb_prepare_logo(struct fb_info *info, int rotate)
327{ 421{
328 int depth = fb_get_color_depth(&info->var, &info->fix); 422 int depth = fb_get_color_depth(&info->var, &info->fix);
423 int yres;
329 424
330 memset(&fb_logo, 0, sizeof(struct logo_data)); 425 memset(&fb_logo, 0, sizeof(struct logo_data));
331 426
@@ -358,10 +453,16 @@ int fb_prepare_logo(struct fb_info *info)
358 /* Return if no suitable logo was found */ 453 /* Return if no suitable logo was found */
359 fb_logo.logo = fb_find_logo(depth); 454 fb_logo.logo = fb_find_logo(depth);
360 455
361 if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { 456 if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
457 yres = info->var.yres;
458 else
459 yres = info->var.xres;
460
461 if (fb_logo.logo && fb_logo.logo->height > yres) {
362 fb_logo.logo = NULL; 462 fb_logo.logo = NULL;
363 return 0; 463 return 0;
364 } 464 }
465
365 /* What depth we asked for might be different from what we get */ 466 /* What depth we asked for might be different from what we get */
366 if (fb_logo.logo->type == LINUX_LOGO_CLUT224) 467 if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
367 fb_logo.depth = 8; 468 fb_logo.depth = 8;
@@ -372,12 +473,11 @@ int fb_prepare_logo(struct fb_info *info)
372 return fb_logo.logo->height; 473 return fb_logo.logo->height;
373} 474}
374 475
375int fb_show_logo(struct fb_info *info) 476int fb_show_logo(struct fb_info *info, int rotate)
376{ 477{
377 u32 *palette = NULL, *saved_pseudo_palette = NULL; 478 u32 *palette = NULL, *saved_pseudo_palette = NULL;
378 unsigned char *logo_new = NULL; 479 unsigned char *logo_new = NULL, *logo_rotate = NULL;
379 struct fb_image image; 480 struct fb_image image;
380 int x;
381 481
382 /* Return if the frame buffer is not mapped or suspended */ 482 /* Return if the frame buffer is not mapped or suspended */
383 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) 483 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
@@ -417,25 +517,30 @@ int fb_show_logo(struct fb_info *info)
417 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); 517 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth);
418 } 518 }
419 519
520 image.dx = 0;
521 image.dy = 0;
420 image.width = fb_logo.logo->width; 522 image.width = fb_logo.logo->width;
421 image.height = fb_logo.logo->height; 523 image.height = fb_logo.logo->height;
422 image.dy = 0;
423 524
424 for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && 525 if (rotate) {
425 x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { 526 logo_rotate = kmalloc(fb_logo.logo->width *
426 image.dx = x; 527 fb_logo.logo->height, GFP_KERNEL);
427 info->fbops->fb_imageblit(info, &image); 528 if (logo_rotate)
529 fb_rotate_logo(info, logo_rotate, &image, rotate);
428 } 530 }
429 531
532 fb_do_show_logo(info, &image, rotate);
533
430 kfree(palette); 534 kfree(palette);
431 if (saved_pseudo_palette != NULL) 535 if (saved_pseudo_palette != NULL)
432 info->pseudo_palette = saved_pseudo_palette; 536 info->pseudo_palette = saved_pseudo_palette;
433 kfree(logo_new); 537 kfree(logo_new);
538 kfree(logo_rotate);
434 return fb_logo.logo->height; 539 return fb_logo.logo->height;
435} 540}
436#else 541#else
437int fb_prepare_logo(struct fb_info *info) { return 0; } 542int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
438int fb_show_logo(struct fb_info *info) { return 0; } 543int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
439#endif /* CONFIG_LOGO */ 544#endif /* CONFIG_LOGO */
440 545
441static int fbmem_read_proc(char *buf, char **start, off_t offset, 546static int fbmem_read_proc(char *buf, char **start, off_t offset,
@@ -829,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
829} 934}
830 935
831#ifdef CONFIG_COMPAT 936#ifdef CONFIG_COMPAT
937struct fb_fix_screeninfo32 {
938 char id[16];
939 compat_caddr_t smem_start;
940 u32 smem_len;
941 u32 type;
942 u32 type_aux;
943 u32 visual;
944 u16 xpanstep;
945 u16 ypanstep;
946 u16 ywrapstep;
947 u32 line_length;
948 compat_caddr_t mmio_start;
949 u32 mmio_len;
950 u32 accel;
951 u16 reserved[3];
952};
953
954struct fb_cmap32 {
955 u32 start;
956 u32 len;
957 compat_caddr_t red;
958 compat_caddr_t green;
959 compat_caddr_t blue;
960 compat_caddr_t transp;
961};
962
963static int fb_getput_cmap(struct inode *inode, struct file *file,
964 unsigned int cmd, unsigned long arg)
965{
966 struct fb_cmap_user __user *cmap;
967 struct fb_cmap32 __user *cmap32;
968 __u32 data;
969 int err;
970
971 cmap = compat_alloc_user_space(sizeof(*cmap));
972 cmap32 = compat_ptr(arg);
973
974 if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
975 return -EFAULT;
976
977 if (get_user(data, &cmap32->red) ||
978 put_user(compat_ptr(data), &cmap->red) ||
979 get_user(data, &cmap32->green) ||
980 put_user(compat_ptr(data), &cmap->green) ||
981 get_user(data, &cmap32->blue) ||
982 put_user(compat_ptr(data), &cmap->blue) ||
983 get_user(data, &cmap32->transp) ||
984 put_user(compat_ptr(data), &cmap->transp))
985 return -EFAULT;
986
987 err = fb_ioctl(inode, file, cmd, (unsigned long) cmap);
988
989 if (!err) {
990 if (copy_in_user(&cmap32->start,
991 &cmap->start,
992 2 * sizeof(__u32)))
993 err = -EFAULT;
994 }
995 return err;
996}
997
998static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
999 struct fb_fix_screeninfo32 __user *fix32)
1000{
1001 __u32 data;
1002 int err;
1003
1004 err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
1005
1006 data = (__u32) (unsigned long) fix->smem_start;
1007 err |= put_user(data, &fix32->smem_start);
1008
1009 err |= put_user(fix->smem_len, &fix32->smem_len);
1010 err |= put_user(fix->type, &fix32->type);
1011 err |= put_user(fix->type_aux, &fix32->type_aux);
1012 err |= put_user(fix->visual, &fix32->visual);
1013 err |= put_user(fix->xpanstep, &fix32->xpanstep);
1014 err |= put_user(fix->ypanstep, &fix32->ypanstep);
1015 err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
1016 err |= put_user(fix->line_length, &fix32->line_length);
1017
1018 data = (__u32) (unsigned long) fix->mmio_start;
1019 err |= put_user(data, &fix32->mmio_start);
1020
1021 err |= put_user(fix->mmio_len, &fix32->mmio_len);
1022 err |= put_user(fix->accel, &fix32->accel);
1023 err |= copy_to_user(fix32->reserved, fix->reserved,
1024 sizeof(fix->reserved));
1025
1026 return err;
1027}
1028
1029static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
1030 unsigned int cmd, unsigned long arg)
1031{
1032 mm_segment_t old_fs;
1033 struct fb_fix_screeninfo fix;
1034 struct fb_fix_screeninfo32 __user *fix32;
1035 int err;
1036
1037 fix32 = compat_ptr(arg);
1038
1039 old_fs = get_fs();
1040 set_fs(KERNEL_DS);
1041 err = fb_ioctl(inode, file, cmd, (unsigned long) &fix);
1042 set_fs(old_fs);
1043
1044 if (!err)
1045 err = do_fscreeninfo_to_user(&fix, fix32);
1046
1047 return err;
1048}
1049
832static long 1050static long
833fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1051fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
834{ 1052{
835 int fbidx = iminor(file->f_dentry->d_inode); 1053 struct inode *inode = file->f_dentry->d_inode;
1054 int fbidx = iminor(inode);
836 struct fb_info *info = registered_fb[fbidx]; 1055 struct fb_info *info = registered_fb[fbidx];
837 struct fb_ops *fb = info->fbops; 1056 struct fb_ops *fb = info->fbops;
838 long ret; 1057 long ret = -ENOIOCTLCMD;
839 1058
840 if (fb->fb_compat_ioctl == NULL)
841 return -ENOIOCTLCMD;
842 lock_kernel(); 1059 lock_kernel();
843 ret = fb->fb_compat_ioctl(file, cmd, arg, info); 1060 switch(cmd) {
1061 case FBIOGET_VSCREENINFO:
1062 case FBIOPUT_VSCREENINFO:
1063 case FBIOPAN_DISPLAY:
1064 case FBIOGET_CON2FBMAP:
1065 case FBIOPUT_CON2FBMAP:
1066 arg = (unsigned long) compat_ptr(arg);
1067 case FBIOBLANK:
1068 ret = fb_ioctl(inode, file, cmd, arg);
1069 break;
1070
1071 case FBIOGET_FSCREENINFO:
1072 ret = fb_get_fscreeninfo(inode, file, cmd, arg);
1073 break;
1074
1075 case FBIOGETCMAP:
1076 case FBIOPUTCMAP:
1077 ret = fb_getput_cmap(inode, file, cmd, arg);
1078 break;
1079
1080 default:
1081 if (fb->fb_compat_ioctl)
1082 ret = fb->fb_compat_ioctl(file, cmd, arg, info);
1083 break;
1084 }
844 unlock_kernel(); 1085 unlock_kernel();
845 return ret; 1086 return ret;
846} 1087}
@@ -1215,6 +1456,28 @@ int fb_new_modelist(struct fb_info *info)
1215 return err; 1456 return err;
1216} 1457}
1217 1458
1459/**
1460 * fb_con_duit - user<->fbcon passthrough
1461 * @info: struct fb_info
1462 * @event: notification event to be passed to fbcon
1463 * @data: private data
1464 *
1465 * DESCRIPTION
1466 * This function is an fbcon-user event passing channel
1467 * which bypasses fbdev. This is hopefully temporary
1468 * until a user interface for fbcon is created
1469 */
1470int fb_con_duit(struct fb_info *info, int event, void *data)
1471{
1472 struct fb_event evnt;
1473
1474 evnt.info = info;
1475 evnt.data = data;
1476
1477 return notifier_call_chain(&fb_notifier_list, event, &evnt);
1478}
1479EXPORT_SYMBOL(fb_con_duit);
1480
1218static char *video_options[FB_MAX]; 1481static char *video_options[FB_MAX];
1219static int ofonly; 1482static int ofonly;
1220 1483
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 007c8e9b2b39..08dac9580d15 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -213,6 +213,70 @@ static ssize_t show_bpp(struct class_device *class_device, char *buf)
213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); 213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
214} 214}
215 215
216static ssize_t store_rotate(struct class_device *class_device, const char *buf,
217 size_t count)
218{
219 struct fb_info *fb_info = class_get_devdata(class_device);
220 struct fb_var_screeninfo var;
221 char **last = NULL;
222 int err;
223
224 var = fb_info->var;
225 var.rotate = simple_strtoul(buf, last, 0);
226
227 if ((err = activate(fb_info, &var)))
228 return err;
229
230 return count;
231}
232
233
234static ssize_t show_rotate(struct class_device *class_device, char *buf)
235{
236 struct fb_info *fb_info = class_get_devdata(class_device);
237
238 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
239}
240
241static ssize_t store_con_rotate(struct class_device *class_device,
242 const char *buf, size_t count)
243{
244 struct fb_info *fb_info = class_get_devdata(class_device);
245 int rotate;
246 char **last = NULL;
247
248 acquire_console_sem();
249 rotate = simple_strtoul(buf, last, 0);
250 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate);
251 release_console_sem();
252 return count;
253}
254
255static ssize_t store_con_rotate_all(struct class_device *class_device,
256 const char *buf, size_t count)
257{
258 struct fb_info *fb_info = class_get_devdata(class_device);
259 int rotate;
260 char **last = NULL;
261
262 acquire_console_sem();
263 rotate = simple_strtoul(buf, last, 0);
264 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate);
265 release_console_sem();
266 return count;
267}
268
269static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
270{
271 struct fb_info *fb_info = class_get_devdata(class_device);
272 int rotate;
273
274 acquire_console_sem();
275 rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL);
276 release_console_sem();
277 return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
278}
279
216static ssize_t store_virtual(struct class_device *class_device, 280static ssize_t store_virtual(struct class_device *class_device,
217 const char * buf, size_t count) 281 const char * buf, size_t count)
218{ 282{
@@ -440,6 +504,9 @@ static struct class_device_attribute class_device_attrs[] = {
440 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), 504 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
441 __ATTR(name, S_IRUGO, show_name, NULL), 505 __ATTR(name, S_IRUGO, show_name, NULL),
442 __ATTR(stride, S_IRUGO, show_stride, NULL), 506 __ATTR(stride, S_IRUGO, show_stride, NULL),
507 __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
508 __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
509 __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
443}; 510};
444 511
445int fb_init_class_device(struct fb_info *fb_info) 512int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 0799b999b314..427689e584da 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -122,7 +122,6 @@
122#include <linux/pci.h> 122#include <linux/pci.h>
123#include <linux/vmalloc.h> 123#include <linux/vmalloc.h>
124#include <linux/pagemap.h> 124#include <linux/pagemap.h>
125#include <linux/version.h>
126 125
127#include <asm/io.h> 126#include <asm/io.h>
128 127
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index ac94c2e5ff85..624c4bc96f0d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -34,7 +34,6 @@
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/pagemap.h> 36#include <linux/pagemap.h>
37#include <linux/version.h>
38 37
39#include <asm/io.h> 38#include <asm/io.h>
40 39
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 1789a52d776a..1da2f84bdc25 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -251,6 +251,10 @@ static const struct fb_videomode modedb[] = {
251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, 251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
253 FB_VMODE_NONINTERLACED 253 FB_VMODE_NONINTERLACED
254 }, {
255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
256 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
254 }, 258 },
255}; 259};
256 260
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index f0dfb35e3191..09e2f2841901 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1315,10 +1315,14 @@ static void savagefb_set_fix(struct fb_info *info)
1315 info->fix.line_length = info->var.xres_virtual * 1315 info->fix.line_length = info->var.xres_virtual *
1316 info->var.bits_per_pixel / 8; 1316 info->var.bits_per_pixel / 8;
1317 1317
1318 if (info->var.bits_per_pixel == 8) 1318 if (info->var.bits_per_pixel == 8) {
1319 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 1319 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1320 else 1320 info->fix.xpanstep = 4;
1321 } else {
1321 info->fix.visual = FB_VISUAL_TRUECOLOR; 1322 info->fix.visual = FB_VISUAL_TRUECOLOR;
1323 info->fix.xpanstep = 2;
1324 }
1325
1322} 1326}
1323 1327
1324#if defined(CONFIG_FB_SAVAGE_ACCEL) 1328#if defined(CONFIG_FB_SAVAGE_ACCEL)
@@ -1363,7 +1367,6 @@ static int savagefb_set_par (struct fb_info *info)
1363 par->minClock = 10000; 1367 par->minClock = 10000;
1364 1368
1365 savagefb_set_par_int (par); 1369 savagefb_set_par_int (par);
1366 savagefb_update_start (par, var);
1367 fb_set_cmap (&info->cmap, info); 1370 fb_set_cmap (&info->cmap, info);
1368 savagefb_set_fix(info); 1371 savagefb_set_fix(info);
1369 savagefb_set_clip(info); 1372 savagefb_set_clip(info);
@@ -1873,7 +1876,6 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1873 1876
1874 info->fix.type = FB_TYPE_PACKED_PIXELS; 1877 info->fix.type = FB_TYPE_PACKED_PIXELS;
1875 info->fix.type_aux = 0; 1878 info->fix.type_aux = 0;
1876 info->fix.xpanstep = 2;
1877 info->fix.ypanstep = 1; 1879 info->fix.ypanstep = 1;
1878 info->fix.ywrapstep = 0; 1880 info->fix.ywrapstep = 0;
1879 info->fix.accel = id->driver_data; 1881 info->fix.accel = id->driver_data;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 690bb6fe8281..226ae8a88482 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -21,6 +21,7 @@
21#include <linux/fb.h> 21#include <linux/fb.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26#include <video/vga.h> 27#include <video/vga.h>
@@ -51,35 +52,33 @@
51 * card parameters 52 * card parameters
52 */ 53 */
53 54
54static struct fb_info vga16fb; 55struct vga16fb_par {
55
56static struct vga16fb_par {
57 /* structure holding original VGA register settings when the 56 /* structure holding original VGA register settings when the
58 screen is blanked */ 57 screen is blanked */
59 struct { 58 struct {
60 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */ 59 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
61 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */ 60 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
62 unsigned char CrtMiscIO; /* Miscellaneous register */ 61 unsigned char CrtMiscIO; /* Miscellaneous register */
63 unsigned char HorizontalTotal; /* CRT-Controller:00h */ 62 unsigned char HorizontalTotal; /* CRT-Controller:00h */
64 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */ 63 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
65 unsigned char StartHorizRetrace; /* CRT-Controller:04h */ 64 unsigned char StartHorizRetrace;/* CRT-Controller:04h */
66 unsigned char EndHorizRetrace; /* CRT-Controller:05h */ 65 unsigned char EndHorizRetrace; /* CRT-Controller:05h */
67 unsigned char Overflow; /* CRT-Controller:07h */ 66 unsigned char Overflow; /* CRT-Controller:07h */
68 unsigned char StartVertRetrace; /* CRT-Controller:10h */ 67 unsigned char StartVertRetrace; /* CRT-Controller:10h */
69 unsigned char EndVertRetrace; /* CRT-Controller:11h */ 68 unsigned char EndVertRetrace; /* CRT-Controller:11h */
70 unsigned char ModeControl; /* CRT-Controller:17h */ 69 unsigned char ModeControl; /* CRT-Controller:17h */
71 unsigned char ClockingMode; /* Seq-Controller:01h */ 70 unsigned char ClockingMode; /* Seq-Controller:01h */
72 } vga_state; 71 } vga_state;
73 struct vgastate state; 72 struct vgastate state;
74 atomic_t ref_count; 73 atomic_t ref_count;
75 int palette_blanked, vesa_blanked, mode, isVGA; 74 int palette_blanked, vesa_blanked, mode, isVGA;
76 u8 misc, pel_msk, vss, clkdiv; 75 u8 misc, pel_msk, vss, clkdiv;
77 u8 crtc[VGA_CRT_C]; 76 u8 crtc[VGA_CRT_C];
78} vga16_par; 77};
79 78
80/* --------------------------------------------------------------------- */ 79/* --------------------------------------------------------------------- */
81 80
82static struct fb_var_screeninfo vga16fb_defined = { 81static struct fb_var_screeninfo vga16fb_defined __initdata = {
83 .xres = 640, 82 .xres = 640,
84 .yres = 480, 83 .yres = 480,
85 .xres_virtual = 640, 84 .xres_virtual = 640,
@@ -205,7 +204,7 @@ static inline void setindex(int index)
205static void vga16fb_pan_var(struct fb_info *info, 204static void vga16fb_pan_var(struct fb_info *info,
206 struct fb_var_screeninfo *var) 205 struct fb_var_screeninfo *var)
207{ 206{
208 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 207 struct vga16fb_par *par = info->par;
209 u32 xoffset, pos; 208 u32 xoffset, pos;
210 209
211 xoffset = var->xoffset; 210 xoffset = var->xoffset;
@@ -300,7 +299,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
300 299
301static int vga16fb_open(struct fb_info *info, int user) 300static int vga16fb_open(struct fb_info *info, int user)
302{ 301{
303 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 302 struct vga16fb_par *par = info->par;
304 int cnt = atomic_read(&par->ref_count); 303 int cnt = atomic_read(&par->ref_count);
305 304
306 if (!cnt) { 305 if (!cnt) {
@@ -315,7 +314,7 @@ static int vga16fb_open(struct fb_info *info, int user)
315 314
316static int vga16fb_release(struct fb_info *info, int user) 315static int vga16fb_release(struct fb_info *info, int user)
317{ 316{
318 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 317 struct vga16fb_par *par = info->par;
319 int cnt = atomic_read(&par->ref_count); 318 int cnt = atomic_read(&par->ref_count);
320 319
321 if (!cnt) 320 if (!cnt)
@@ -330,7 +329,7 @@ static int vga16fb_release(struct fb_info *info, int user)
330static int vga16fb_check_var(struct fb_var_screeninfo *var, 329static int vga16fb_check_var(struct fb_var_screeninfo *var,
331 struct fb_info *info) 330 struct fb_info *info)
332{ 331{
333 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 332 struct vga16fb_par *par = info->par;
334 u32 xres, right, hslen, left, xtotal; 333 u32 xres, right, hslen, left, xtotal;
335 u32 yres, lower, vslen, upper, ytotal; 334 u32 yres, lower, vslen, upper, ytotal;
336 u32 vxres, xoffset, vyres, yoffset; 335 u32 vxres, xoffset, vyres, yoffset;
@@ -535,7 +534,7 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var,
535 534
536static int vga16fb_set_par(struct fb_info *info) 535static int vga16fb_set_par(struct fb_info *info)
537{ 536{
538 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 537 struct vga16fb_par *par = info->par;
539 u8 gdc[VGA_GFX_C]; 538 u8 gdc[VGA_GFX_C];
540 u8 seq[VGA_SEQ_C]; 539 u8 seq[VGA_SEQ_C];
541 u8 atc[VGA_ATT_C]; 540 u8 atc[VGA_ATT_C];
@@ -677,7 +676,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
677 unsigned blue, unsigned transp, 676 unsigned blue, unsigned transp,
678 struct fb_info *info) 677 struct fb_info *info)
679{ 678{
680 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 679 struct vga16fb_par *par = info->par;
681 int gray; 680 int gray;
682 681
683 /* 682 /*
@@ -850,7 +849,7 @@ static void vga_pal_blank(void)
850/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ 849/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
851static int vga16fb_blank(int blank, struct fb_info *info) 850static int vga16fb_blank(int blank, struct fb_info *info)
852{ 851{
853 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 852 struct vga16fb_par *par = info->par;
854 853
855 switch (blank) { 854 switch (blank) {
856 case FB_BLANK_UNBLANK: /* Unblank */ 855 case FB_BLANK_UNBLANK: /* Unblank */
@@ -1201,7 +1200,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im
1201{ 1200{
1202 char __iomem *where = info->screen_base + (image->dx/8) + 1201 char __iomem *where = info->screen_base + (image->dx/8) +
1203 image->dy * info->fix.line_length; 1202 image->dy * info->fix.line_length;
1204 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1203 struct vga16fb_par *par = info->par;
1205 char *cdat = (char *) image->data; 1204 char *cdat = (char *) image->data;
1206 char __iomem *dst; 1205 char __iomem *dst;
1207 int x, y; 1206 int x, y;
@@ -1266,7 +1265,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima
1266 /* 1265 /*
1267 * Draw logo 1266 * Draw logo
1268 */ 1267 */
1269 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1268 struct vga16fb_par *par = info->par;
1270 char __iomem *where = 1269 char __iomem *where =
1271 info->screen_base + image->dy * info->fix.line_length + 1270 info->screen_base + image->dy * info->fix.line_length +
1272 image->dx/8; 1271 image->dx/8;
@@ -1343,89 +1342,141 @@ static int vga16fb_setup(char *options)
1343} 1342}
1344#endif 1343#endif
1345 1344
1346static int __init vga16fb_init(void) 1345static int __init vga16fb_probe(struct device *device)
1347{ 1346{
1347 struct platform_device *dev = to_platform_device(device);
1348 struct fb_info *info;
1349 struct vga16fb_par *par;
1348 int i; 1350 int i;
1349 int ret; 1351 int ret = 0;
1350#ifndef MODULE
1351 char *option = NULL;
1352 1352
1353 if (fb_get_options("vga16fb", &option))
1354 return -ENODEV;
1355
1356 vga16fb_setup(option);
1357#endif
1358 printk(KERN_DEBUG "vga16fb: initializing\n"); 1353 printk(KERN_DEBUG "vga16fb: initializing\n");
1354 info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev);
1355
1356 if (!info) {
1357 ret = -ENOMEM;
1358 goto err_fb_alloc;
1359 }
1359 1360
1360 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ 1361 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
1362 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS);
1361 1363
1362 vga16fb.screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); 1364 if (!info->screen_base) {
1363 if (!vga16fb.screen_base) {
1364 printk(KERN_ERR "vga16fb: unable to map device\n"); 1365 printk(KERN_ERR "vga16fb: unable to map device\n");
1365 ret = -ENOMEM; 1366 ret = -ENOMEM;
1366 goto err_ioremap; 1367 goto err_ioremap;
1367 } 1368 }
1368 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
1369 1369
1370 vga16_par.isVGA = ORIG_VIDEO_ISVGA; 1370 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
1371 vga16_par.palette_blanked = 0; 1371 par = info->par;
1372 vga16_par.vesa_blanked = 0;
1373 1372
1374 i = vga16_par.isVGA? 6 : 2; 1373 par->isVGA = ORIG_VIDEO_ISVGA;
1374 par->palette_blanked = 0;
1375 par->vesa_blanked = 0;
1376
1377 i = par->isVGA? 6 : 2;
1375 1378
1376 vga16fb_defined.red.length = i; 1379 vga16fb_defined.red.length = i;
1377 vga16fb_defined.green.length = i; 1380 vga16fb_defined.green.length = i;
1378 vga16fb_defined.blue.length = i; 1381 vga16fb_defined.blue.length = i;
1379 1382
1380 /* name should not depend on EGA/VGA */ 1383 /* name should not depend on EGA/VGA */
1381 vga16fb.fbops = &vga16fb_ops; 1384 info->fbops = &vga16fb_ops;
1382 vga16fb.var = vga16fb_defined; 1385 info->var = vga16fb_defined;
1383 vga16fb.fix = vga16fb_fix; 1386 info->fix = vga16fb_fix;
1384 vga16fb.par = &vga16_par; 1387 info->flags = FBINFO_FLAG_DEFAULT |
1385 vga16fb.flags = FBINFO_FLAG_DEFAULT |
1386 FBINFO_HWACCEL_YPAN; 1388 FBINFO_HWACCEL_YPAN;
1387 1389
1388 i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16; 1390 i = (info->var.bits_per_pixel == 8) ? 256 : 16;
1389 ret = fb_alloc_cmap(&vga16fb.cmap, i, 0); 1391 ret = fb_alloc_cmap(&info->cmap, i, 0);
1390 if (ret) { 1392 if (ret) {
1391 printk(KERN_ERR "vga16fb: unable to allocate colormap\n"); 1393 printk(KERN_ERR "vga16fb: unable to allocate colormap\n");
1392 ret = -ENOMEM; 1394 ret = -ENOMEM;
1393 goto err_alloc_cmap; 1395 goto err_alloc_cmap;
1394 } 1396 }
1395 1397
1396 if (vga16fb_check_var(&vga16fb.var, &vga16fb)) { 1398 if (vga16fb_check_var(&info->var, info)) {
1397 printk(KERN_ERR "vga16fb: unable to validate variable\n"); 1399 printk(KERN_ERR "vga16fb: unable to validate variable\n");
1398 ret = -EINVAL; 1400 ret = -EINVAL;
1399 goto err_check_var; 1401 goto err_check_var;
1400 } 1402 }
1401 1403
1402 vga16fb_update_fix(&vga16fb); 1404 vga16fb_update_fix(info);
1403 1405
1404 if (register_framebuffer(&vga16fb) < 0) { 1406 if (register_framebuffer(info) < 0) {
1405 printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); 1407 printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
1406 ret = -EINVAL; 1408 ret = -EINVAL;
1407 goto err_check_var; 1409 goto err_check_var;
1408 } 1410 }
1409 1411
1410 printk(KERN_INFO "fb%d: %s frame buffer device\n", 1412 printk(KERN_INFO "fb%d: %s frame buffer device\n",
1411 vga16fb.node, vga16fb.fix.id); 1413 info->node, info->fix.id);
1414 dev_set_drvdata(device, info);
1412 1415
1413 return 0; 1416 return 0;
1414 1417
1415 err_check_var: 1418 err_check_var:
1416 fb_dealloc_cmap(&vga16fb.cmap); 1419 fb_dealloc_cmap(&info->cmap);
1417 err_alloc_cmap: 1420 err_alloc_cmap:
1418 iounmap(vga16fb.screen_base); 1421 iounmap(info->screen_base);
1419 err_ioremap: 1422 err_ioremap:
1423 framebuffer_release(info);
1424 err_fb_alloc:
1425 return ret;
1426}
1427
1428static int vga16fb_remove(struct device *device)
1429{
1430 struct fb_info *info = dev_get_drvdata(device);
1431
1432 if (info) {
1433 unregister_framebuffer(info);
1434 iounmap(info->screen_base);
1435 fb_dealloc_cmap(&info->cmap);
1436 /* XXX unshare VGA regions */
1437 framebuffer_release(info);
1438 }
1439
1440 return 0;
1441}
1442
1443static struct device_driver vga16fb_driver = {
1444 .name = "vga16fb",
1445 .bus = &platform_bus_type,
1446 .probe = vga16fb_probe,
1447 .remove = vga16fb_remove,
1448};
1449
1450static struct platform_device vga16fb_device = {
1451 .name = "vga16fb",
1452};
1453
1454static int __init vga16fb_init(void)
1455{
1456 int ret;
1457#ifndef MODULE
1458 char *option = NULL;
1459
1460 if (fb_get_options("vga16fb", &option))
1461 return -ENODEV;
1462
1463 vga16fb_setup(option);
1464#endif
1465 ret = driver_register(&vga16fb_driver);
1466
1467 if (!ret) {
1468 ret = platform_device_register(&vga16fb_device);
1469 if (ret)
1470 driver_unregister(&vga16fb_driver);
1471 }
1472
1420 return ret; 1473 return ret;
1421} 1474}
1422 1475
1423static void __exit vga16fb_exit(void) 1476static void __exit vga16fb_exit(void)
1424{ 1477{
1425 unregister_framebuffer(&vga16fb); 1478 platform_device_unregister(&vga16fb_device);
1426 iounmap(vga16fb.screen_base); 1479 driver_unregister(&vga16fb_driver);
1427 fb_dealloc_cmap(&vga16fb.cmap);
1428 /* XXX unshare VGA regions */
1429} 1480}
1430 1481
1431MODULE_LICENSE("GPL"); 1482MODULE_LICENSE("GPL");
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index ca92940f3943..d9e01daee630 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -485,11 +485,6 @@ int restore_vga (struct vgastate *state)
485 return 0; 485 return 0;
486} 486}
487 487
488#ifdef MODULE
489int init_module(void) { return 0; };
490void cleanup_module(void) {};
491#endif
492
493EXPORT_SYMBOL(save_vga); 488EXPORT_SYMBOL(save_vga);
494EXPORT_SYMBOL(restore_vga); 489EXPORT_SYMBOL(restore_vga);
495 490
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index bbc3cc63854f..89c849da8504 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -32,7 +32,6 @@
32#include <linux/string.h> 32#include <linux/string.h>
33#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
34#include <linux/inet.h> 34#include <linux/inet.h>
35#include <linux/version.h>
36#include <linux/list.h> 35#include <linux/list.h>
37#include <asm/uaccess.h> 36#include <asm/uaccess.h>
38#include <linux/idr.h> 37#include <linux/idr.h>
diff --git a/fs/Kconfig b/fs/Kconfig
index 7d6ae369ce44..d5255e627b5f 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1601,9 +1601,10 @@ config CIFS
1601 PC operating systems. The CIFS protocol is fully supported by 1601 PC operating systems. The CIFS protocol is fully supported by
1602 file servers such as Windows 2000 (including Windows 2003, NT 4 1602 file servers such as Windows 2000 (including Windows 2003, NT 4
1603 and Windows XP) as well by Samba (which provides excellent CIFS 1603 and Windows XP) as well by Samba (which provides excellent CIFS
1604 server support for Linux and many other operating systems). Currently 1604 server support for Linux and many other operating systems). Limited
1605 you must use the smbfs client filesystem to access older SMB servers 1605 support for Windows ME and similar servers is provided as well.
1606 such as Windows 9x and OS/2. 1606 You must use the smbfs client filesystem to access older SMB servers
1607 such as OS/2 and DOS.
1607 1608
1608 The intent of the cifs module is to provide an advanced 1609 The intent of the cifs module is to provide an advanced
1609 network file system client for mounting to CIFS compliant servers, 1610 network file system client for mounting to CIFS compliant servers,
@@ -1614,7 +1615,7 @@ config CIFS
1614 cifs if running only a (Samba) server. It is possible to enable both 1615 cifs if running only a (Samba) server. It is possible to enable both
1615 smbfs and cifs (e.g. if you are using CIFS for accessing Windows 2003 1616 smbfs and cifs (e.g. if you are using CIFS for accessing Windows 2003
1616 and Samba 3 servers, and smbfs for accessing old servers). If you need 1617 and Samba 3 servers, and smbfs for accessing old servers). If you need
1617 to mount to Samba or Windows 2003 servers from this machine, say Y. 1618 to mount to Samba or Windows from this machine, say Y.
1618 1619
1619config CIFS_STATS 1620config CIFS_STATS
1620 bool "CIFS statistics" 1621 bool "CIFS statistics"
@@ -1623,8 +1624,22 @@ config CIFS_STATS
1623 Enabling this option will cause statistics for each server share 1624 Enabling this option will cause statistics for each server share
1624 mounted by the cifs client to be displayed in /proc/fs/cifs/Stats 1625 mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
1625 1626
1627config CIFS_STATS2
1628 bool "CIFS extended statistics"
1629 depends on CIFS_STATS
1630 help
1631 Enabling this option will allow more detailed statistics on SMB
1632 request timing to be displayed in /proc/fs/cifs/DebugData and also
1633 allow optional logging of slow responses to dmesg (depending on the
1634 value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
1635 These additional statistics may have a minor effect on performance
1636 and memory utilization.
1637
1638 Unless you are a developer or are doing network performance analysis
1639 or tuning, say N.
1640
1626config CIFS_XATTR 1641config CIFS_XATTR
1627 bool "CIFS extended attributes (EXPERIMENTAL)" 1642 bool "CIFS extended attributes"
1628 depends on CIFS 1643 depends on CIFS
1629 help 1644 help
1630 Extended attributes are name:value pairs associated with inodes by 1645 Extended attributes are name:value pairs associated with inodes by
@@ -1636,11 +1651,11 @@ config CIFS_XATTR
1636 prefaced by the user namespace prefix. The system namespace 1651 prefaced by the user namespace prefix. The system namespace
1637 (used by some filesystems to store ACLs) is not supported at 1652 (used by some filesystems to store ACLs) is not supported at
1638 this time. 1653 this time.
1639 1654
1640 If unsure, say N. 1655 If unsure, say N.
1641 1656
1642config CIFS_POSIX 1657config CIFS_POSIX
1643 bool "CIFS POSIX Extensions (EXPERIMENTAL)" 1658 bool "CIFS POSIX Extensions"
1644 depends on CIFS_XATTR 1659 depends on CIFS_XATTR
1645 help 1660 help
1646 Enabling this option will cause the cifs client to attempt to 1661 Enabling this option will cause the cifs client to attempt to
@@ -1653,10 +1668,28 @@ config CIFS_POSIX
1653 1668
1654config CIFS_EXPERIMENTAL 1669config CIFS_EXPERIMENTAL
1655 bool "CIFS Experimental Features (EXPERIMENTAL)" 1670 bool "CIFS Experimental Features (EXPERIMENTAL)"
1656 depends on CIFS 1671 depends on CIFS && EXPERIMENTAL
1672 help
1673 Enables cifs features under testing. These features are
1674 experimental and currently include support for writepages
1675 (multipage writebehind performance improvements) and directory
1676 change notification ie fcntl(F_DNOTIFY) as well as some security
1677 improvements. Some also depend on setting at runtime the
1678 pseudo-file /proc/fs/cifs/Experimental (which is disabled by
1679 default). See the file fs/cifs/README for more details.
1680
1681 If unsure, say N.
1682
1683config CIFS_UPCALL
1684 bool "CIFS Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
1685 depends on CIFS_EXPERIMENTAL
1686 select CONNECTOR
1657 help 1687 help
1658 Enables cifs features under testing. These features 1688 Enables an upcall mechanism for CIFS which will be used to contact
1659 are highly experimental. If unsure, say N. 1689 userspace helper utilities to provide SPNEGO packaged Kerberos
1690 tickets which are needed to mount to certain secure servers
1691 (for which more secure Kerberos authentication is required). If
1692 unsure, say N.
1660 1693
1661config NCP_FS 1694config NCP_FS
1662 tristate "NCP file system support (to mount NetWare volumes)" 1695 tristate "NCP file system support (to mount NetWare volumes)"
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index fd528433de43..f6cd01352cc8 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -12,7 +12,6 @@
12#define ADFS_NDA_PUBLIC_READ (1 << 5) 12#define ADFS_NDA_PUBLIC_READ (1 << 5)
13#define ADFS_NDA_PUBLIC_WRITE (1 << 6) 13#define ADFS_NDA_PUBLIC_WRITE (1 << 6)
14 14
15#include <linux/version.h>
16#include "dir_f.h" 15#include "dir_f.h"
17 16
18struct buffer_head; 17struct buffer_head;
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 8ae0db6cd69c..2568eb41cb3a 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -150,7 +150,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
150 150
151 /* if the binary is not readable than enforce mm->dumpable=0 151 /* if the binary is not readable than enforce mm->dumpable=0
152 regardless of the interpreter's permissions */ 152 regardless of the interpreter's permissions */
153 if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL)) 153 if (file_permission(bprm->file, MAY_READ))
154 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; 154 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
155 155
156 allow_write_access(bprm->file); 156 allow_write_access(bprm->file);
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 5bab24f59053..eab3750cf304 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -2,7 +2,7 @@ Version 1.39
2------------ 2------------
3Defer close of a file handle slightly if pending writes depend on that file handle 3Defer close of a file handle slightly if pending writes depend on that file handle
4(this reduces the EBADF bad file handle errors that can be logged under heavy 4(this reduces the EBADF bad file handle errors that can be logged under heavy
5stress on writes). 5stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
6 6
7Version 1.38 7Version 1.38
8------------ 8------------
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 99a096d3f84d..4e12053f0806 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -74,10 +74,11 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len,
74 cERROR(1, 74 cERROR(1,
75 ("cifs_strtoUCS: char2uni returned %d", 75 ("cifs_strtoUCS: char2uni returned %d",
76 charlen)); 76 charlen));
77 to[i] = cpu_to_le16(0x003f); /* a question mark */ 77 /* A question mark */
78 to[i] = (wchar_t)cpu_to_le16(0x003f);
78 charlen = 1; 79 charlen = 1;
79 } else 80 } else
80 to[i] = cpu_to_le16(to[i]); 81 to[i] = (wchar_t)cpu_to_le16(to[i]);
81 82
82 } 83 }
83 84
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 877095a1192a..682b0235ad9a 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -405,6 +405,7 @@ static struct quotactl_ops cifs_quotactl_ops = {
405}; 405};
406#endif 406#endif
407 407
408#ifdef CONFIG_CIFS_EXPERIMENTAL
408static void cifs_umount_begin(struct super_block * sblock) 409static void cifs_umount_begin(struct super_block * sblock)
409{ 410{
410 struct cifs_sb_info *cifs_sb; 411 struct cifs_sb_info *cifs_sb;
@@ -422,16 +423,18 @@ static void cifs_umount_begin(struct super_block * sblock)
422 tcon->tidStatus = CifsExiting; 423 tcon->tidStatus = CifsExiting;
423 up(&tcon->tconSem); 424 up(&tcon->tconSem);
424 425
426 /* cancel_brl_requests(tcon); */
427 /* cancel_notify_requests(tcon); */
425 if(tcon->ses && tcon->ses->server) 428 if(tcon->ses && tcon->ses->server)
426 { 429 {
427 cERROR(1,("wake up tasks now - umount begin not complete")); 430 cFYI(1,("wake up tasks now - umount begin not complete"));
428 wake_up_all(&tcon->ses->server->request_q); 431 wake_up_all(&tcon->ses->server->request_q);
429 } 432 }
430/* BB FIXME - finish add checks for tidStatus BB */ 433/* BB FIXME - finish add checks for tidStatus BB */
431 434
432 return; 435 return;
433} 436}
434 437#endif
435 438
436static int cifs_remount(struct super_block *sb, int *flags, char *data) 439static int cifs_remount(struct super_block *sb, int *flags, char *data)
437{ 440{
@@ -450,7 +453,9 @@ struct super_operations cifs_super_ops = {
450 unless later we add lazy close of inodes or unless the kernel forgets to call 453 unless later we add lazy close of inodes or unless the kernel forgets to call
451 us with the same number of releases (closes) as opens */ 454 us with the same number of releases (closes) as opens */
452 .show_options = cifs_show_options, 455 .show_options = cifs_show_options,
453/* .umount_begin = cifs_umount_begin, */ /* BB finish in the future */ 456#ifdef CONFIG_CIFS_EXPERIMENTAL
457 .umount_begin = cifs_umount_begin,
458#endif
454 .remount_fs = cifs_remount, 459 .remount_fs = cifs_remount,
455}; 460};
456 461
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index d301149b1bb0..1b73f4f4c5ce 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -242,11 +242,11 @@ extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
242 const int netfid, const unsigned int count, 242 const int netfid, const unsigned int count,
243 const __u64 offset, unsigned int *nbytes, 243 const __u64 offset, unsigned int *nbytes,
244 struct kvec *iov, const int nvec, const int long_op); 244 struct kvec *iov, const int nvec, const int long_op);
245#endif /* CONFIG_CIFS_EXPERIMENTAL */
245extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 246extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
246 const unsigned char *searchName, __u64 * inode_number, 247 const unsigned char *searchName, __u64 * inode_number,
247 const struct nls_table *nls_codepage, 248 const struct nls_table *nls_codepage,
248 int remap_special_chars); 249 int remap_special_chars);
249#endif /* CONFIG_CIFS_EXPERIMENTAL */
250extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, 250extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
251 const struct nls_table * codepage); 251 const struct nls_table * codepage);
252extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, 252extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 9312bfc56682..a53c596e1082 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2959,7 +2959,6 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
2959 return rc; 2959 return rc;
2960} 2960}
2961 2961
2962#ifdef CONFIG_CIFS_EXPERIMENTAL
2963int 2962int
2964CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 2963CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
2965 const unsigned char *searchName, 2964 const unsigned char *searchName,
@@ -3053,7 +3052,6 @@ GetInodeNumOut:
3053 goto GetInodeNumberRetry; 3052 goto GetInodeNumberRetry;
3054 return rc; 3053 return rc;
3055} 3054}
3056#endif /* CIFS_EXPERIMENTAL */
3057 3055
3058int 3056int
3059CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 3057CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
diff --git a/fs/cifs/cn_cifs.h b/fs/cifs/cn_cifs.h
new file mode 100644
index 000000000000..ea59ccac2eb1
--- /dev/null
+++ b/fs/cifs/cn_cifs.h
@@ -0,0 +1,37 @@
1/*
2 * fs/cifs/cn_cifs.h
3 *
4 * Copyright (c) International Business Machines Corp., 2002
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef _CN_CIFS_H
23#define _CN_CIFS_H
24#ifdef CONFIG_CIFS_UPCALL
25#include <linux/types.h>
26#include <linux/connector.h>
27
28struct cifs_upcall {
29 char signature[4]; /* CIFS */
30 enum command {
31 CIFS_GET_IP = 0x00000001, /* get ip address for hostname */
32 CIFS_GET_SECBLOB = 0x00000002, /* get SPNEGO wrapped blob */
33 } command;
34 /* union cifs upcall data follows */
35};
36#endif /* CIFS_UPCALL */
37#endif /* _CN_CIFS_H */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 450ab75d6546..2cb620716bc1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -42,6 +42,7 @@
42#include "ntlmssp.h" 42#include "ntlmssp.h"
43#include "nterr.h" 43#include "nterr.h"
44#include "rfc1002pdu.h" 44#include "rfc1002pdu.h"
45#include "cn_cifs.h"
45 46
46#define CIFS_PORT 445 47#define CIFS_PORT 445
47#define RFC1001_PORT 139 48#define RFC1001_PORT 139
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 912d401600f6..923d071163b2 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -283,7 +283,6 @@ int cifs_get_inode_info(struct inode **pinode,
283 there Windows server or network appliances for which 283 there Windows server or network appliances for which
284 IndexNumber field is not guaranteed unique? */ 284 IndexNumber field is not guaranteed unique? */
285 285
286#ifdef CONFIG_CIFS_EXPERIMENTAL
287 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ 286 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
288 int rc1 = 0; 287 int rc1 = 0;
289 __u64 inode_num; 288 __u64 inode_num;
@@ -299,7 +298,6 @@ int cifs_get_inode_info(struct inode **pinode,
299 } else /* do we need cast or hash to ino? */ 298 } else /* do we need cast or hash to ino? */
300 (*pinode)->i_ino = inode_num; 299 (*pinode)->i_ino = inode_num;
301 } /* else ino incremented to unique num in new_inode*/ 300 } /* else ino incremented to unique num in new_inode*/
302#endif /* CIFS_EXPERIMENTAL */
303 insert_inode_hash(*pinode); 301 insert_inode_hash(*pinode);
304 } 302 }
305 inode = *pinode; 303 inode = *pinode;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 4909754ea84a..26300fccb4fc 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -840,146 +840,6 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
840 return err ? -EFAULT : 0; 840 return err ? -EFAULT : 0;
841} 841}
842 842
843struct fb_fix_screeninfo32 {
844 char id[16];
845 compat_caddr_t smem_start;
846 u32 smem_len;
847 u32 type;
848 u32 type_aux;
849 u32 visual;
850 u16 xpanstep;
851 u16 ypanstep;
852 u16 ywrapstep;
853 u32 line_length;
854 compat_caddr_t mmio_start;
855 u32 mmio_len;
856 u32 accel;
857 u16 reserved[3];
858};
859
860struct fb_cmap32 {
861 u32 start;
862 u32 len;
863 compat_caddr_t red;
864 compat_caddr_t green;
865 compat_caddr_t blue;
866 compat_caddr_t transp;
867};
868
869static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
870{
871 struct fb_cmap_user __user *cmap;
872 struct fb_cmap32 __user *cmap32;
873 __u32 data;
874 int err;
875
876 cmap = compat_alloc_user_space(sizeof(*cmap));
877 cmap32 = compat_ptr(arg);
878
879 if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
880 return -EFAULT;
881
882 if (get_user(data, &cmap32->red) ||
883 put_user(compat_ptr(data), &cmap->red) ||
884 get_user(data, &cmap32->green) ||
885 put_user(compat_ptr(data), &cmap->green) ||
886 get_user(data, &cmap32->blue) ||
887 put_user(compat_ptr(data), &cmap->blue) ||
888 get_user(data, &cmap32->transp) ||
889 put_user(compat_ptr(data), &cmap->transp))
890 return -EFAULT;
891
892 err = sys_ioctl(fd, cmd, (unsigned long) cmap);
893
894 if (!err) {
895 if (copy_in_user(&cmap32->start,
896 &cmap->start,
897 2 * sizeof(__u32)))
898 err = -EFAULT;
899 }
900 return err;
901}
902
903static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
904 struct fb_fix_screeninfo32 __user *fix32)
905{
906 __u32 data;
907 int err;
908
909 err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
910
911 data = (__u32) (unsigned long) fix->smem_start;
912 err |= put_user(data, &fix32->smem_start);
913
914 err |= put_user(fix->smem_len, &fix32->smem_len);
915 err |= put_user(fix->type, &fix32->type);
916 err |= put_user(fix->type_aux, &fix32->type_aux);
917 err |= put_user(fix->visual, &fix32->visual);
918 err |= put_user(fix->xpanstep, &fix32->xpanstep);
919 err |= put_user(fix->ypanstep, &fix32->ypanstep);
920 err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
921 err |= put_user(fix->line_length, &fix32->line_length);
922
923 data = (__u32) (unsigned long) fix->mmio_start;
924 err |= put_user(data, &fix32->mmio_start);
925
926 err |= put_user(fix->mmio_len, &fix32->mmio_len);
927 err |= put_user(fix->accel, &fix32->accel);
928 err |= copy_to_user(fix32->reserved, fix->reserved,
929 sizeof(fix->reserved));
930
931 return err;
932}
933
934static int fb_get_fscreeninfo(unsigned int fd, unsigned int cmd, unsigned long arg)
935{
936 mm_segment_t old_fs;
937 struct fb_fix_screeninfo fix;
938 struct fb_fix_screeninfo32 __user *fix32;
939 int err;
940
941 fix32 = compat_ptr(arg);
942
943 old_fs = get_fs();
944 set_fs(KERNEL_DS);
945 err = sys_ioctl(fd, cmd, (unsigned long) &fix);
946 set_fs(old_fs);
947
948 if (!err)
949 err = do_fscreeninfo_to_user(&fix, fix32);
950
951 return err;
952}
953
954static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
955{
956 int err;
957
958 switch (cmd) {
959 case FBIOGET_FSCREENINFO:
960 err = fb_get_fscreeninfo(fd,cmd, arg);
961 break;
962
963 case FBIOGETCMAP:
964 case FBIOPUTCMAP:
965 err = fb_getput_cmap(fd, cmd, arg);
966 break;
967
968 default:
969 do {
970 static int count;
971 if (++count <= 20)
972 printk("%s: Unknown fb ioctl cmd fd(%d) "
973 "cmd(%08x) arg(%08lx)\n",
974 __FUNCTION__, fd, cmd, arg);
975 } while(0);
976 err = -ENOSYS;
977 break;
978 };
979
980 return err;
981}
982
983static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 843static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
984{ 844{
985 mm_segment_t old_fs = get_fs(); 845 mm_segment_t old_fs = get_fs();
@@ -2953,10 +2813,7 @@ HANDLE_IOCTL(BLKGETSIZE, w_long)
2953HANDLE_IOCTL(0x1260, broken_blkgetsize) 2813HANDLE_IOCTL(0x1260, broken_blkgetsize)
2954HANDLE_IOCTL(BLKFRAGET, w_long) 2814HANDLE_IOCTL(BLKFRAGET, w_long)
2955HANDLE_IOCTL(BLKSECTGET, w_long) 2815HANDLE_IOCTL(BLKSECTGET, w_long)
2956HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
2957HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) 2816HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
2958HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
2959HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
2960HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans) 2817HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
2961HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) 2818HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
2962HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) 2819HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
@@ -3051,6 +2908,16 @@ HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
3051COMPATIBLE_IOCTL(TIOCGLTC) 2908COMPATIBLE_IOCTL(TIOCGLTC)
3052COMPATIBLE_IOCTL(TIOCSLTC) 2909COMPATIBLE_IOCTL(TIOCSLTC)
3053#endif 2910#endif
2911#ifdef TIOCSTART
2912/*
2913 * For these two we have defintions in ioctls.h and/or termios.h on
2914 * some architectures but no actual implemention. Some applications
2915 * like bash call them if they are defined in the headers, so we provide
2916 * entries here to avoid syslog message spew.
2917 */
2918COMPATIBLE_IOCTL(TIOCSTART)
2919COMPATIBLE_IOCTL(TIOCSTOP)
2920#endif
3054/* Usbdevfs */ 2921/* Usbdevfs */
3055HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control) 2922HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
3056HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk) 2923HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
diff --git a/fs/exec.c b/fs/exec.c
index 5a4e3acc2e9f..c466fec5de20 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -135,7 +135,7 @@ asmlinkage long sys_uselib(const char __user * library)
135 if (!S_ISREG(nd.dentry->d_inode->i_mode)) 135 if (!S_ISREG(nd.dentry->d_inode->i_mode))
136 goto exit; 136 goto exit;
137 137
138 error = permission(nd.dentry->d_inode, MAY_READ | MAY_EXEC, &nd); 138 error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
139 if (error) 139 if (error)
140 goto exit; 140 goto exit;
141 141
@@ -495,7 +495,7 @@ struct file *open_exec(const char *name)
495 file = ERR_PTR(-EACCES); 495 file = ERR_PTR(-EACCES);
496 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && 496 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
497 S_ISREG(inode->i_mode)) { 497 S_ISREG(inode->i_mode)) {
498 int err = permission(inode, MAY_EXEC, &nd); 498 int err = vfs_permission(&nd, MAY_EXEC);
499 if (!err && !(inode->i_mode & 0111)) 499 if (!err && !(inode->i_mode & 0111))
500 err = -EACCES; 500 err = -EACCES;
501 file = ERR_PTR(err); 501 file = ERR_PTR(err);
@@ -896,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm)
896 flush_thread(); 896 flush_thread();
897 897
898 if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 898 if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
899 permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) || 899 file_permission(bprm->file, MAY_READ) ||
900 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { 900 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
901 suid_keys(current); 901 suid_keys(current);
902 current->mm->dumpable = suid_dumpable; 902 current->mm->dumpable = suid_dumpable;
diff --git a/fs/ext2/CHANGES b/fs/ext2/CHANGES
deleted file mode 100644
index aa5aaf0e5911..000000000000
--- a/fs/ext2/CHANGES
+++ /dev/null
@@ -1,157 +0,0 @@
1Changes from version 0.5a to version 0.5b
2=========================================
3 - Now that we have sysctl(), the immutable flag cannot be changed when
4 the system is running at security level > 0.
5 - Some cleanups in the code.
6 - More consistency checks on directories.
7 - The ext2.diff patch from Tom May <ftom@netcom.com> has been
8 integrated. This patch replaces expensive "/" and "%" with
9 cheap ">>" and "&" where possible.
10
11Changes from version 0.5 to version 0.5a
12========================================
13 - Zero the partial block following the end of the file when a file
14 is truncated.
15 - Dates updated in the copyright.
16 - More checks when the filesystem is mounted: the count of blocks,
17 fragments, and inodes per group is checked against the block size.
18 - The buffers used by the error routines are now static variables, to
19 avoid using space on the kernel stack, as requested by Linus.
20 - Some cleanups in the error messages (some versions of syslog contain
21 a bug which truncates an error message if it contains '\n').
22 - Check that no data can be written to a file past the 2GB limit.
23 - The famous readdir() bug has been fixed by Stephen Tweedie.
24 - Added a revision level in the superblock.
25 - Full support for O_SYNC flag of the open system call.
26 - New mount options: `resuid=#uid' and `resgid=#gid'. `resuid' causes
27 ext2fs to consider user #uid like root for the reserved blocks.
28 `resgid' acts the same way with group #gid. New fields in the
29 superblock contain default values for resuid and resgid and can
30 be modified by tune2fs.
31 Idea comes from Rene Cougnenc <cougnenc@renux.frmug.fr.net>.
32 - New mount options: `bsddf' and `minixdf'. `bsddf' causes ext2fs
33 to remove the blocks used for FS structures from the total block
34 count in statfs. With `minixdf', ext2fs mimics Minix behavior
35 in statfs (i.e. it returns the total number of blocks on the
36 partition). This is intended to make bde happy :-)
37 - New file attributes:
38 - Immutable files cannot be modified. Data cannot be written to
39 these files. They cannot be removed, renamed and new links cannot
40 be created. Even root cannot modify the files. He has to remove
41 the immutable attribute first.
42 - Append-only files: can only be written in append-mode when writing.
43 They cannot be removed, renamed and new links cannot be created.
44 Note: files may only be added to an append-only directory.
45 - No-dump files: the attribute is not used by the kernel. My port
46 of dump uses it to avoid backing up files which are not important.
47 - New check in ext2_check_dir_entry: the inode number is checked.
48 - Support for big file systems: the copy of the FS descriptor is now
49 dynamically allocated (previous versions used a fixed size array).
50 This allows to mount 2GB+ FS.
51 - Reorganization of the ext2_inode structure to allow other operating
52 systems to create specific fields if they use ext2fs as their native
53 file system. Currently, ext2fs is only implemented in Linux but
54 will soon be part of Gnu Hurd and of Masix.
55
56Changes from version 0.4b to version 0.5
57========================================
58 - New superblock fields: s_lastcheck and s_checkinterval added
59 by Uwe Ohse <uwe@tirka.gun.de> to implement timedependent checks
60 of the file system
61 - Real random numbers for secure rm added by Pierre del Perugia
62 <delperug@gla.ecoledoc.ibp.fr>
63 - The mount warnings related to the state of a fs are not printed
64 if the fs is mounted read-only, idea by Nick Holloway
65 <alfie@dcs.warwick.ac.uk>
66
67Changes from version 0.4a to version 0.4b
68=========================================
69 - Copyrights changed to include the name of my laboratory.
70 - Clean up of balloc.c and ialloc.c.
71 - More consistency checks.
72 - Block preallocation added by Stephen Tweedie.
73 - Direct reads of directories disallowed.
74 - Readahead implemented in readdir by Stephen Tweedie.
75 - Bugs in block and inodes allocation fixed.
76 - Readahead implemented in ext2_find_entry by Chip Salzenberg.
77 - New mount options:
78 `check=none|normal|strict'
79 `debug'
80 `errors=continue|remount-ro|panic'
81 `grpid', `bsdgroups'
82 `nocheck'
83 `nogrpid', `sysvgroups'
84 - truncate() now tries to deallocate contiguous blocks in a single call
85 to ext2_free_blocks().
86 - lots of cosmetic changes.
87
88Changes from version 0.4 to version 0.4a
89========================================
90 - the `sync' option support is now complete. Version 0.4 was not
91 supporting it when truncating a file. I have tested the synchronous
92 writes and they work but they make the system very slow :-( I have
93 to work again on this to make it faster.
94 - when detecting an error on a mounted filesystem, version 0.4 used
95 to try to write a flag in the super block even if the filesystem had
96 been mounted read-only. This is fixed.
97 - the `sb=#' option now causes the kernel code to use the filesystem
98 descriptors located at block #+1. Version 0.4 used the superblock
99 backup located at block # but used the main copy of the descriptors.
100 - a new file attribute `S' is supported. This attribute causes
101 synchronous writes but is applied to a file not to the entire file
102 system (thanks to Michael Kraehe <kraehe@bakunin.north.de> for
103 suggesting it).
104 - the directory cache is inhibited by default. The cache management
105 code seems to be buggy and I have to look at it carefully before
106 using it again.
107 - deleting a file with the `s' attribute (secure deletion) causes its
108 blocks to be overwritten with random values not with zeros (thanks to
109 Michael A. Griffith <grif@cs.ucr.edu> for suggesting it).
110 - lots of cosmetic changes have been made.
111
112Changes from version 0.3 to version 0.4
113=======================================
114 - Three new mount options are supported: `check', `sync' and `sb=#'.
115 `check' tells the kernel code to make more consistency checks
116 when the file system is mounted. Currently, the kernel code checks
117 that the blocks and inodes bitmaps are consistent with the free
118 blocks and inodes counts. More checks will be added in future
119 releases.
120 `sync' tells the kernel code to use synchronous writes when updating
121 an inode, a bitmap, a directory entry or an indirect block. This
122 can make the file system much slower but can be a big win for files
123 recovery in case of a crash (and we can now say to the BSD folks
124 that Linux also supports synchronous updates :-).
125 `sb=#' tells the kernel code to use an alternate super block instead
126 of its master copy. `#' is the number of the block (counted in
127 1024 bytes blocks) which contains the alternate super block.
128 An ext2 file system typically contains backups of the super block
129 at blocks 8193, 16385, and so on.
130 - I have change the meaning of the valid flag used by e2fsck. it
131 now contains the state of the file system. If the kernel code
132 detects an inconsistency while the file system is mounted, it flags
133 it as erroneous and e2fsck will detect that on next run.
134 - The super block now contains a mount counter. This counter is
135 incremented each time the file system is mounted read/write. When
136 this counter becomes bigger than a maximal mount counts (also stored
137 in the super block), e2fsck checks the file system, even if it had
138 been unmounted cleanly, and resets this counter to 0.
139 - File attributes are now supported. One can associate a set of
140 attributes to a file. Three attributes are defined:
141 `c': the file is marked for automatic compression,
142 `s': the file is marked for secure deletion: when the file is
143 deleted, its blocks are zeroed and written back to the disk,
144 `u': the file is marked for undeletion: when the file is deleted,
145 its contents are saved to allow a future undeletion.
146 Currently, only the `s' attribute is implemented in the kernel
147 code. Support for the other attributes will be added in a future
148 release.
149 - a few bugs related to times updates have been fixed by Bruce
150 Evans and me.
151 - a bug related to the links count of deleted inodes has been fixed.
152 Previous versions used to keep the links count set to 1 when a file
153 was deleted. The new version now sets links_count to 0 when deleting
154 the last link.
155 - a race condition when deallocating an inode has been fixed by
156 Stephen Tweedie.
157
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 6591abef64d0..bb6908066494 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -624,76 +624,3 @@ unsigned long ext2_bg_num_gdb(struct super_block *sb, int group)
624 return EXT2_SB(sb)->s_gdb_count; 624 return EXT2_SB(sb)->s_gdb_count;
625} 625}
626 626
627#ifdef CONFIG_EXT2_CHECK
628/* Called at mount-time, super-block is locked */
629void ext2_check_blocks_bitmap (struct super_block * sb)
630{
631 struct buffer_head *bitmap_bh = NULL;
632 struct ext2_super_block * es;
633 unsigned long desc_count, bitmap_count, x, j;
634 unsigned long desc_blocks;
635 struct ext2_group_desc * desc;
636 int i;
637
638 es = EXT2_SB(sb)->s_es;
639 desc_count = 0;
640 bitmap_count = 0;
641 desc = NULL;
642 for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
643 desc = ext2_get_group_desc (sb, i, NULL);
644 if (!desc)
645 continue;
646 desc_count += le16_to_cpu(desc->bg_free_blocks_count);
647 brelse(bitmap_bh);
648 bitmap_bh = read_block_bitmap(sb, i);
649 if (!bitmap_bh)
650 continue;
651
652 if (ext2_bg_has_super(sb, i) &&
653 !ext2_test_bit(0, bitmap_bh->b_data))
654 ext2_error(sb, __FUNCTION__,
655 "Superblock in group %d is marked free", i);
656
657 desc_blocks = ext2_bg_num_gdb(sb, i);
658 for (j = 0; j < desc_blocks; j++)
659 if (!ext2_test_bit(j + 1, bitmap_bh->b_data))
660 ext2_error(sb, __FUNCTION__,
661 "Descriptor block #%ld in group "
662 "%d is marked free", j, i);
663
664 if (!block_in_use(le32_to_cpu(desc->bg_block_bitmap),
665 sb, bitmap_bh->b_data))
666 ext2_error(sb, "ext2_check_blocks_bitmap",
667 "Block bitmap for group %d is marked free",
668 i);
669
670 if (!block_in_use(le32_to_cpu(desc->bg_inode_bitmap),
671 sb, bitmap_bh->b_data))
672 ext2_error(sb, "ext2_check_blocks_bitmap",
673 "Inode bitmap for group %d is marked free",
674 i);
675
676 for (j = 0; j < EXT2_SB(sb)->s_itb_per_group; j++)
677 if (!block_in_use(le32_to_cpu(desc->bg_inode_table) + j,
678 sb, bitmap_bh->b_data))
679 ext2_error (sb, "ext2_check_blocks_bitmap",
680 "Block #%ld of the inode table in "
681 "group %d is marked free", j, i);
682
683 x = ext2_count_free(bitmap_bh, sb->s_blocksize);
684 if (le16_to_cpu(desc->bg_free_blocks_count) != x)
685 ext2_error (sb, "ext2_check_blocks_bitmap",
686 "Wrong free blocks count for group %d, "
687 "stored = %d, counted = %lu", i,
688 le16_to_cpu(desc->bg_free_blocks_count), x);
689 bitmap_count += x;
690 }
691 if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
692 ext2_error (sb, "ext2_check_blocks_bitmap",
693 "Wrong free blocks count in super block, "
694 "stored = %lu, counted = %lu",
695 (unsigned long)le32_to_cpu(es->s_free_blocks_count),
696 bitmap_count);
697 brelse(bitmap_bh);
698}
699#endif
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index e2d6208633a7..74714af4ae69 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -700,43 +700,3 @@ unsigned long ext2_count_dirs (struct super_block * sb)
700 return count; 700 return count;
701} 701}
702 702
703#ifdef CONFIG_EXT2_CHECK
704/* Called at mount-time, super-block is locked */
705void ext2_check_inodes_bitmap (struct super_block * sb)
706{
707 struct ext2_super_block * es = EXT2_SB(sb)->s_es;
708 unsigned long desc_count = 0, bitmap_count = 0;
709 struct buffer_head *bitmap_bh = NULL;
710 int i;
711
712 for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
713 struct ext2_group_desc *desc;
714 unsigned x;
715
716 desc = ext2_get_group_desc(sb, i, NULL);
717 if (!desc)
718 continue;
719 desc_count += le16_to_cpu(desc->bg_free_inodes_count);
720 brelse(bitmap_bh);
721 bitmap_bh = read_inode_bitmap(sb, i);
722 if (!bitmap_bh)
723 continue;
724
725 x = ext2_count_free(bitmap_bh, EXT2_INODES_PER_GROUP(sb) / 8);
726 if (le16_to_cpu(desc->bg_free_inodes_count) != x)
727 ext2_error (sb, "ext2_check_inodes_bitmap",
728 "Wrong free inodes count in group %d, "
729 "stored = %d, counted = %lu", i,
730 le16_to_cpu(desc->bg_free_inodes_count), x);
731 bitmap_count += x;
732 }
733 brelse(bitmap_bh);
734 if (percpu_counter_read(&EXT2_SB(sb)->s_freeinodes_counter) !=
735 bitmap_count)
736 ext2_error(sb, "ext2_check_inodes_bitmap",
737 "Wrong free inodes count in super block, "
738 "stored = %lu, counted = %lu",
739 (unsigned long)le32_to_cpu(es->s_free_inodes_count),
740 bitmap_count);
741}
742#endif
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 3c0c7c6a5b44..e4ed4b31a433 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -281,7 +281,7 @@ static unsigned long get_sb_block(void **data)
281enum { 281enum {
282 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, 282 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
283 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, 283 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic,
284 Opt_err_ro, Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, 284 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
285 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr, 285 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
286 Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota, 286 Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
287 Opt_usrquota, Opt_grpquota 287 Opt_usrquota, Opt_grpquota
@@ -303,7 +303,6 @@ static match_table_t tokens = {
303 {Opt_nouid32, "nouid32"}, 303 {Opt_nouid32, "nouid32"},
304 {Opt_nocheck, "check=none"}, 304 {Opt_nocheck, "check=none"},
305 {Opt_nocheck, "nocheck"}, 305 {Opt_nocheck, "nocheck"},
306 {Opt_check, "check"},
307 {Opt_debug, "debug"}, 306 {Opt_debug, "debug"},
308 {Opt_oldalloc, "oldalloc"}, 307 {Opt_oldalloc, "oldalloc"},
309 {Opt_orlov, "orlov"}, 308 {Opt_orlov, "orlov"},
@@ -376,13 +375,6 @@ static int parse_options (char * options,
376 case Opt_nouid32: 375 case Opt_nouid32:
377 set_opt (sbi->s_mount_opt, NO_UID32); 376 set_opt (sbi->s_mount_opt, NO_UID32);
378 break; 377 break;
379 case Opt_check:
380#ifdef CONFIG_EXT2_CHECK
381 set_opt (sbi->s_mount_opt, CHECK);
382#else
383 printk("EXT2 Check option not supported\n");
384#endif
385 break;
386 case Opt_nocheck: 378 case Opt_nocheck:
387 clear_opt (sbi->s_mount_opt, CHECK); 379 clear_opt (sbi->s_mount_opt, CHECK);
388 break; 380 break;
@@ -503,12 +495,6 @@ static int ext2_setup_super (struct super_block * sb,
503 EXT2_BLOCKS_PER_GROUP(sb), 495 EXT2_BLOCKS_PER_GROUP(sb),
504 EXT2_INODES_PER_GROUP(sb), 496 EXT2_INODES_PER_GROUP(sb),
505 sbi->s_mount_opt); 497 sbi->s_mount_opt);
506#ifdef CONFIG_EXT2_CHECK
507 if (test_opt (sb, CHECK)) {
508 ext2_check_blocks_bitmap (sb);
509 ext2_check_inodes_bitmap (sb);
510 }
511#endif
512 return res; 498 return res;
513} 499}
514 500
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 7992d21e0e09..ae1148c24c53 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -1517,76 +1517,3 @@ unsigned long ext3_bg_num_gdb(struct super_block *sb, int group)
1517 return EXT3_SB(sb)->s_gdb_count; 1517 return EXT3_SB(sb)->s_gdb_count;
1518} 1518}
1519 1519
1520#ifdef CONFIG_EXT3_CHECK
1521/* Called at mount-time, super-block is locked */
1522void ext3_check_blocks_bitmap (struct super_block * sb)
1523{
1524 struct ext3_super_block *es;
1525 unsigned long desc_count, bitmap_count, x, j;
1526 unsigned long desc_blocks;
1527 struct buffer_head *bitmap_bh = NULL;
1528 struct ext3_group_desc *gdp;
1529 int i;
1530
1531 es = EXT3_SB(sb)->s_es;
1532 desc_count = 0;
1533 bitmap_count = 0;
1534 gdp = NULL;
1535 for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
1536 gdp = ext3_get_group_desc (sb, i, NULL);
1537 if (!gdp)
1538 continue;
1539 desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
1540 brelse(bitmap_bh);
1541 bitmap_bh = read_block_bitmap(sb, i);
1542 if (bitmap_bh == NULL)
1543 continue;
1544
1545 if (ext3_bg_has_super(sb, i) &&
1546 !ext3_test_bit(0, bitmap_bh->b_data))
1547 ext3_error(sb, __FUNCTION__,
1548 "Superblock in group %d is marked free", i);
1549
1550 desc_blocks = ext3_bg_num_gdb(sb, i);
1551 for (j = 0; j < desc_blocks; j++)
1552 if (!ext3_test_bit(j + 1, bitmap_bh->b_data))
1553 ext3_error(sb, __FUNCTION__,
1554 "Descriptor block #%ld in group "
1555 "%d is marked free", j, i);
1556
1557 if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap),
1558 sb, bitmap_bh->b_data))
1559 ext3_error (sb, "ext3_check_blocks_bitmap",
1560 "Block bitmap for group %d is marked free",
1561 i);
1562
1563 if (!block_in_use (le32_to_cpu(gdp->bg_inode_bitmap),
1564 sb, bitmap_bh->b_data))
1565 ext3_error (sb, "ext3_check_blocks_bitmap",
1566 "Inode bitmap for group %d is marked free",
1567 i);
1568
1569 for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++)
1570 if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j,
1571 sb, bitmap_bh->b_data))
1572 ext3_error (sb, "ext3_check_blocks_bitmap",
1573 "Block #%d of the inode table in "
1574 "group %d is marked free", j, i);
1575
1576 x = ext3_count_free(bitmap_bh, sb->s_blocksize);
1577 if (le16_to_cpu(gdp->bg_free_blocks_count) != x)
1578 ext3_error (sb, "ext3_check_blocks_bitmap",
1579 "Wrong free blocks count for group %d, "
1580 "stored = %d, counted = %lu", i,
1581 le16_to_cpu(gdp->bg_free_blocks_count), x);
1582 bitmap_count += x;
1583 }
1584 brelse(bitmap_bh);
1585 if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
1586 ext3_error (sb, "ext3_check_blocks_bitmap",
1587 "Wrong free blocks count in super block, "
1588 "stored = %lu, counted = %lu",
1589 (unsigned long)le32_to_cpu(es->s_free_blocks_count),
1590 bitmap_count);
1591}
1592#endif
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index df3f517c54ac..9e4a24376210 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -756,44 +756,3 @@ unsigned long ext3_count_dirs (struct super_block * sb)
756 return count; 756 return count;
757} 757}
758 758
759#ifdef CONFIG_EXT3_CHECK
760/* Called at mount-time, super-block is locked */
761void ext3_check_inodes_bitmap (struct super_block * sb)
762{
763 struct ext3_super_block * es;
764 unsigned long desc_count, bitmap_count, x;
765 struct buffer_head *bitmap_bh = NULL;
766 struct ext3_group_desc * gdp;
767 int i;
768
769 es = EXT3_SB(sb)->s_es;
770 desc_count = 0;
771 bitmap_count = 0;
772 gdp = NULL;
773 for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
774 gdp = ext3_get_group_desc (sb, i, NULL);
775 if (!gdp)
776 continue;
777 desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
778 brelse(bitmap_bh);
779 bitmap_bh = read_inode_bitmap(sb, i);
780 if (!bitmap_bh)
781 continue;
782
783 x = ext3_count_free(bitmap_bh, EXT3_INODES_PER_GROUP(sb) / 8);
784 if (le16_to_cpu(gdp->bg_free_inodes_count) != x)
785 ext3_error (sb, "ext3_check_inodes_bitmap",
786 "Wrong free inodes count in group %d, "
787 "stored = %d, counted = %lu", i,
788 le16_to_cpu(gdp->bg_free_inodes_count), x);
789 bitmap_count += x;
790 }
791 brelse(bitmap_bh);
792 if (le32_to_cpu(es->s_free_inodes_count) != bitmap_count)
793 ext3_error (sb, "ext3_check_inodes_bitmap",
794 "Wrong free inodes count in super block, "
795 "stored = %lu, counted = %lu",
796 (unsigned long)le32_to_cpu(es->s_free_inodes_count),
797 bitmap_count);
798}
799#endif
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index f594989ccb7a..4e6730622d90 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -625,7 +625,7 @@ static struct export_operations ext3_export_ops = {
625enum { 625enum {
626 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, 626 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
627 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, 627 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
628 Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, 628 Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
629 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, 629 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
630 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, 630 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh,
631 Opt_commit, Opt_journal_update, Opt_journal_inum, 631 Opt_commit, Opt_journal_update, Opt_journal_inum,
@@ -652,7 +652,6 @@ static match_table_t tokens = {
652 {Opt_nouid32, "nouid32"}, 652 {Opt_nouid32, "nouid32"},
653 {Opt_nocheck, "nocheck"}, 653 {Opt_nocheck, "nocheck"},
654 {Opt_nocheck, "check=none"}, 654 {Opt_nocheck, "check=none"},
655 {Opt_check, "check"},
656 {Opt_debug, "debug"}, 655 {Opt_debug, "debug"},
657 {Opt_oldalloc, "oldalloc"}, 656 {Opt_oldalloc, "oldalloc"},
658 {Opt_orlov, "orlov"}, 657 {Opt_orlov, "orlov"},
@@ -773,14 +772,6 @@ static int parse_options (char * options, struct super_block *sb,
773 case Opt_nouid32: 772 case Opt_nouid32:
774 set_opt (sbi->s_mount_opt, NO_UID32); 773 set_opt (sbi->s_mount_opt, NO_UID32);
775 break; 774 break;
776 case Opt_check:
777#ifdef CONFIG_EXT3_CHECK
778 set_opt (sbi->s_mount_opt, CHECK);
779#else
780 printk(KERN_ERR
781 "EXT3 Check option not supported\n");
782#endif
783 break;
784 case Opt_nocheck: 775 case Opt_nocheck:
785 clear_opt (sbi->s_mount_opt, CHECK); 776 clear_opt (sbi->s_mount_opt, CHECK);
786 break; 777 break;
@@ -1115,12 +1106,6 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
1115 } else { 1106 } else {
1116 printk("internal journal\n"); 1107 printk("internal journal\n");
1117 } 1108 }
1118#ifdef CONFIG_EXT3_CHECK
1119 if (test_opt (sb, CHECK)) {
1120 ext3_check_blocks_bitmap (sb);
1121 ext3_check_inodes_bitmap (sb);
1122 }
1123#endif
1124 return res; 1109 return res;
1125} 1110}
1126 1111
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index e2effe2dc9b2..a0f9b9fe1307 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -846,7 +846,7 @@ static match_table_t vfat_tokens = {
846 {Opt_err, NULL} 846 {Opt_err, NULL}
847}; 847};
848 848
849static int parse_options(char *options, int is_vfat, int *debug, 849static int parse_options(char *options, int is_vfat, int silent, int *debug,
850 struct fat_mount_options *opts) 850 struct fat_mount_options *opts)
851{ 851{
852 char *p; 852 char *p;
@@ -1008,8 +1008,11 @@ static int parse_options(char *options, int is_vfat, int *debug,
1008 break; 1008 break;
1009 /* unknown option */ 1009 /* unknown option */
1010 default: 1010 default:
1011 printk(KERN_ERR "FAT: Unrecognized mount option \"%s\" " 1011 if (!silent) {
1012 "or missing value\n", p); 1012 printk(KERN_ERR
1013 "FAT: Unrecognized mount option \"%s\" "
1014 "or missing value\n", p);
1015 }
1013 return -EINVAL; 1016 return -EINVAL;
1014 } 1017 }
1015 } 1018 }
@@ -1091,7 +1094,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
1091 sb->s_export_op = &fat_export_ops; 1094 sb->s_export_op = &fat_export_ops;
1092 sbi->dir_ops = fs_dir_inode_ops; 1095 sbi->dir_ops = fs_dir_inode_ops;
1093 1096
1094 error = parse_options(data, isvfat, &debug, &sbi->options); 1097 error = parse_options(data, isvfat, silent, &debug, &sbi->options);
1095 if (error) 1098 if (error)
1096 goto out_fail; 1099 goto out_fail;
1097 1100
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index aae019aadf88..cc5dcd52e23d 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -9,7 +9,6 @@
9#ifndef _LINUX_HFS_FS_H 9#ifndef _LINUX_HFS_FS_H
10#define _LINUX_HFS_FS_H 10#define _LINUX_HFS_FS_H
11 11
12#include <linux/version.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 3f680c5675bf..d499393a8ae7 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/pagemap.h> 14#include <linux/pagemap.h>
15#include <linux/version.h>
16#include <linux/mpage.h> 15#include <linux/mpage.h>
17 16
18#include "hfs_fs.h" 17#include "hfs_fs.h"
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index b85abc6e6f83..930cd9212de8 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -13,7 +13,6 @@
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/swap.h> 15#include <linux/swap.h>
16#include <linux/version.h>
17 16
18#include "hfsplus_fs.h" 17#include "hfsplus_fs.h"
19#include "hfsplus_raw.h" 18#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 7bda76667a4a..50c8f44b6c66 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -13,7 +13,6 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/random.h> 15#include <linux/random.h>
16#include <linux/version.h>
17 16
18#include "hfsplus_fs.h" 17#include "hfsplus_fs.h"
19#include "hfsplus_raw.h" 18#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index e7235ca79a95..e3ff56a03011 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -11,7 +11,6 @@
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/fs.h> 12#include <linux/fs.h>
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/version.h>
15 14
16#include "hfsplus_fs.h" 15#include "hfsplus_fs.h"
17#include "hfsplus_raw.h" 16#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 2bc0cdd30e56..c60e5635498d 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -11,7 +11,6 @@
11#define _LINUX_HFSPLUS_FS_H 11#define _LINUX_HFSPLUS_FS_H
12 12
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/version.h>
15#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
16#include "hfsplus_raw.h" 15#include "hfsplus_raw.h"
17 16
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index f205773ddfbe..fc98583cf045 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -11,7 +11,6 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/fs.h> 12#include <linux/fs.h>
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/version.h>
15#include <linux/mpage.h> 14#include <linux/mpage.h>
16 15
17#include "hfsplus_fs.h" 16#include "hfsplus_fs.h"
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 452fc1fdbd32..0ce1c455ae55 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -14,7 +14,6 @@
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/version.h>
18#include <linux/vfs.h> 17#include <linux/vfs.h>
19#include <linux/nls.h> 18#include <linux/nls.h>
20 19
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index 0c51d6338b0b..95455e839231 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -12,7 +12,6 @@
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/cdrom.h> 13#include <linux/cdrom.h>
14#include <linux/genhd.h> 14#include <linux/genhd.h>
15#include <linux/version.h>
16#include <asm/unaligned.h> 15#include <asm/unaligned.h>
17 16
18#include "hfsplus_fs.h" 17#include "hfsplus_fs.h"
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index a33fb1d91373..4684eb7d48c6 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -8,7 +8,6 @@
8 8
9#include <linux/stddef.h> 9#include <linux/stddef.h>
10#include <linux/fs.h> 10#include <linux/fs.h>
11#include <linux/version.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/slab.h> 13#include <linux/slab.h>
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index ab144dabd870..7c995ac4081b 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -114,11 +114,8 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
114 ssize_t retval; 114 ssize_t retval;
115 115
116 retval = generic_file_write(file, buf, count, ppos); 116 retval = generic_file_write(file, buf, count, ppos);
117 if (retval > 0) { 117 if (retval > 0)
118 struct inode *inode = file->f_dentry->d_inode; 118 hpfs_i(file->f_dentry->d_inode)->i_dirty = 1;
119 inode->i_mtime = CURRENT_TIME_SEC;
120 hpfs_i(inode)->i_dirty = 1;
121 }
122 return retval; 119 return retval;
123} 120}
124 121
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index e026c807e6b3..64983ab55586 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -63,7 +63,7 @@ static void huge_pagevec_release(struct pagevec *pvec)
63 * 63 *
64 * Result is in bytes to be compatible with is_hugepage_mem_enough() 64 * Result is in bytes to be compatible with is_hugepage_mem_enough()
65 */ 65 */
66unsigned long 66static unsigned long
67huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma) 67huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma)
68{ 68{
69 int i; 69 int i;
diff --git a/fs/inotify.c b/fs/inotify.c
index 9fbaebfdf40b..bf7ce1d2412b 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -372,7 +372,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd)
372 if (error) 372 if (error)
373 return error; 373 return error;
374 /* you can only watch an inode if you have read permissions on it */ 374 /* you can only watch an inode if you have read permissions on it */
375 error = permission(nd->dentry->d_inode, MAY_READ, NULL); 375 error = vfs_permission(nd, MAY_READ);
376 if (error) 376 if (error)
377 path_release(nd); 377 path_release(nd);
378 return error; 378 return error;
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 1abe7343f920..4abbe8604302 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -827,6 +827,7 @@ static int jfs_link(struct dentry *old_dentry,
827 /* update object inode */ 827 /* update object inode */
828 ip->i_nlink++; /* for new link */ 828 ip->i_nlink++; /* for new link */
829 ip->i_ctime = CURRENT_TIME; 829 ip->i_ctime = CURRENT_TIME;
830 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
830 mark_inode_dirty(dir); 831 mark_inode_dirty(dir);
831 atomic_inc(&ip->i_count); 832 atomic_inc(&ip->i_count);
832 833
@@ -1024,6 +1025,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
1024 insert_inode_hash(ip); 1025 insert_inode_hash(ip);
1025 mark_inode_dirty(ip); 1026 mark_inode_dirty(ip);
1026 1027
1028 dip->i_ctime = dip->i_mtime = CURRENT_TIME;
1029 mark_inode_dirty(dip);
1027 /* 1030 /*
1028 * commit update of parent directory and link object 1031 * commit update of parent directory and link object
1029 */ 1032 */
diff --git a/fs/namei.c b/fs/namei.c
index b3f8a1966c9c..6dbbd42d8b95 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -256,6 +256,38 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
256 return security_inode_permission(inode, mask, nd); 256 return security_inode_permission(inode, mask, nd);
257} 257}
258 258
259/**
260 * vfs_permission - check for access rights to a given path
261 * @nd: lookup result that describes the path
262 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
263 *
264 * Used to check for read/write/execute permissions on a path.
265 * We use "fsuid" for this, letting us set arbitrary permissions
266 * for filesystem access without changing the "normal" uids which
267 * are used for other things.
268 */
269int vfs_permission(struct nameidata *nd, int mask)
270{
271 return permission(nd->dentry->d_inode, mask, nd);
272}
273
274/**
275 * file_permission - check for additional access rights to a given file
276 * @file: file to check access rights for
277 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
278 *
279 * Used to check for read/write/execute permissions on an already opened
280 * file.
281 *
282 * Note:
283 * Do not use this function in new code. All access checks should
284 * be done using vfs_permission().
285 */
286int file_permission(struct file *file, int mask)
287{
288 return permission(file->f_dentry->d_inode, mask, NULL);
289}
290
259/* 291/*
260 * get_write_access() gets write permission for a file. 292 * get_write_access() gets write permission for a file.
261 * put_write_access() releases this write permission. 293 * put_write_access() releases this write permission.
@@ -765,9 +797,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
765 797
766 nd->flags |= LOOKUP_CONTINUE; 798 nd->flags |= LOOKUP_CONTINUE;
767 err = exec_permission_lite(inode, nd); 799 err = exec_permission_lite(inode, nd);
768 if (err == -EAGAIN) { 800 if (err == -EAGAIN)
769 err = permission(inode, MAY_EXEC, nd); 801 err = vfs_permission(nd, MAY_EXEC);
770 }
771 if (err) 802 if (err)
772 break; 803 break;
773 804
@@ -1109,8 +1140,9 @@ int path_lookup_open(const char *name, unsigned int lookup_flags,
1109 * @open_flags: open intent flags 1140 * @open_flags: open intent flags
1110 * @create_mode: create intent flags 1141 * @create_mode: create intent flags
1111 */ 1142 */
1112int path_lookup_create(const char *name, unsigned int lookup_flags, 1143static int path_lookup_create(const char *name, unsigned int lookup_flags,
1113 struct nameidata *nd, int open_flags, int create_mode) 1144 struct nameidata *nd, int open_flags,
1145 int create_mode)
1114{ 1146{
1115 return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd, 1147 return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd,
1116 open_flags, create_mode); 1148 open_flags, create_mode);
@@ -1173,9 +1205,9 @@ out:
1173 return dentry; 1205 return dentry;
1174} 1206}
1175 1207
1176struct dentry * lookup_hash(struct qstr *name, struct dentry * base) 1208struct dentry * lookup_hash(struct nameidata *nd)
1177{ 1209{
1178 return __lookup_hash(name, base, NULL); 1210 return __lookup_hash(&nd->last, nd->dentry, nd);
1179} 1211}
1180 1212
1181/* SMP-safe */ 1213/* SMP-safe */
@@ -1199,7 +1231,7 @@ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
1199 } 1231 }
1200 this.hash = end_name_hash(hash); 1232 this.hash = end_name_hash(hash);
1201 1233
1202 return lookup_hash(&this, base); 1234 return __lookup_hash(&this, base, NULL);
1203access: 1235access:
1204 return ERR_PTR(-EACCES); 1236 return ERR_PTR(-EACCES);
1205} 1237}
@@ -1407,7 +1439,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1407 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) 1439 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
1408 return -EISDIR; 1440 return -EISDIR;
1409 1441
1410 error = permission(inode, acc_mode, nd); 1442 error = vfs_permission(nd, acc_mode);
1411 if (error) 1443 if (error)
1412 return error; 1444 return error;
1413 1445
@@ -1532,7 +1564,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1532 dir = nd->dentry; 1564 dir = nd->dentry;
1533 nd->flags &= ~LOOKUP_PARENT; 1565 nd->flags &= ~LOOKUP_PARENT;
1534 down(&dir->d_inode->i_sem); 1566 down(&dir->d_inode->i_sem);
1535 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1567 path.dentry = lookup_hash(nd);
1536 path.mnt = nd->mnt; 1568 path.mnt = nd->mnt;
1537 1569
1538do_last: 1570do_last:
@@ -1634,7 +1666,7 @@ do_link:
1634 } 1666 }
1635 dir = nd->dentry; 1667 dir = nd->dentry;
1636 down(&dir->d_inode->i_sem); 1668 down(&dir->d_inode->i_sem);
1637 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1669 path.dentry = lookup_hash(nd);
1638 path.mnt = nd->mnt; 1670 path.mnt = nd->mnt;
1639 __putname(nd->last.name); 1671 __putname(nd->last.name);
1640 goto do_last; 1672 goto do_last;
@@ -1666,7 +1698,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
1666 /* 1698 /*
1667 * Do the final lookup. 1699 * Do the final lookup.
1668 */ 1700 */
1669 dentry = lookup_hash(&nd->last, nd->dentry); 1701 dentry = lookup_hash(nd);
1670 if (IS_ERR(dentry)) 1702 if (IS_ERR(dentry))
1671 goto fail; 1703 goto fail;
1672 1704
@@ -1901,7 +1933,7 @@ asmlinkage long sys_rmdir(const char __user * pathname)
1901 goto exit1; 1933 goto exit1;
1902 } 1934 }
1903 down(&nd.dentry->d_inode->i_sem); 1935 down(&nd.dentry->d_inode->i_sem);
1904 dentry = lookup_hash(&nd.last, nd.dentry); 1936 dentry = lookup_hash(&nd);
1905 error = PTR_ERR(dentry); 1937 error = PTR_ERR(dentry);
1906 if (!IS_ERR(dentry)) { 1938 if (!IS_ERR(dentry)) {
1907 error = vfs_rmdir(nd.dentry->d_inode, dentry); 1939 error = vfs_rmdir(nd.dentry->d_inode, dentry);
@@ -1970,7 +2002,7 @@ asmlinkage long sys_unlink(const char __user * pathname)
1970 if (nd.last_type != LAST_NORM) 2002 if (nd.last_type != LAST_NORM)
1971 goto exit1; 2003 goto exit1;
1972 down(&nd.dentry->d_inode->i_sem); 2004 down(&nd.dentry->d_inode->i_sem);
1973 dentry = lookup_hash(&nd.last, nd.dentry); 2005 dentry = lookup_hash(&nd);
1974 error = PTR_ERR(dentry); 2006 error = PTR_ERR(dentry);
1975 if (!IS_ERR(dentry)) { 2007 if (!IS_ERR(dentry)) {
1976 /* Why not before? Because we want correct error value */ 2008 /* Why not before? Because we want correct error value */
@@ -2313,7 +2345,7 @@ static inline int do_rename(const char * oldname, const char * newname)
2313 2345
2314 trap = lock_rename(new_dir, old_dir); 2346 trap = lock_rename(new_dir, old_dir);
2315 2347
2316 old_dentry = lookup_hash(&oldnd.last, old_dir); 2348 old_dentry = lookup_hash(&oldnd);
2317 error = PTR_ERR(old_dentry); 2349 error = PTR_ERR(old_dentry);
2318 if (IS_ERR(old_dentry)) 2350 if (IS_ERR(old_dentry))
2319 goto exit3; 2351 goto exit3;
@@ -2333,7 +2365,7 @@ static inline int do_rename(const char * oldname, const char * newname)
2333 error = -EINVAL; 2365 error = -EINVAL;
2334 if (old_dentry == trap) 2366 if (old_dentry == trap)
2335 goto exit4; 2367 goto exit4;
2336 new_dentry = lookup_hash(&newnd.last, new_dir); 2368 new_dentry = lookup_hash(&newnd);
2337 error = PTR_ERR(new_dentry); 2369 error = PTR_ERR(new_dentry);
2338 if (IS_ERR(new_dentry)) 2370 if (IS_ERR(new_dentry))
2339 goto exit4; 2371 goto exit4;
@@ -2536,6 +2568,8 @@ EXPORT_SYMBOL(path_lookup);
2536EXPORT_SYMBOL(path_release); 2568EXPORT_SYMBOL(path_release);
2537EXPORT_SYMBOL(path_walk); 2569EXPORT_SYMBOL(path_walk);
2538EXPORT_SYMBOL(permission); 2570EXPORT_SYMBOL(permission);
2571EXPORT_SYMBOL(vfs_permission);
2572EXPORT_SYMBOL(file_permission);
2539EXPORT_SYMBOL(unlock_rename); 2573EXPORT_SYMBOL(unlock_rename);
2540EXPORT_SYMBOL(vfs_create); 2574EXPORT_SYMBOL(vfs_create);
2541EXPORT_SYMBOL(vfs_follow_link); 2575EXPORT_SYMBOL(vfs_follow_link);
diff --git a/fs/namespace.c b/fs/namespace.c
index caa9187f67e5..2019899f2ab8 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -637,7 +637,7 @@ static int mount_is_safe(struct nameidata *nd)
637 if (current->uid != nd->dentry->d_inode->i_uid) 637 if (current->uid != nd->dentry->d_inode->i_uid)
638 return -EPERM; 638 return -EPERM;
639 } 639 }
640 if (permission(nd->dentry->d_inode, MAY_WRITE, nd)) 640 if (vfs_permission(nd, MAY_WRITE))
641 return -EPERM; 641 return -EPERM;
642 return 0; 642 return 0;
643#endif 643#endif
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 88df79356a1f..fd3efdca5ae3 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -30,11 +30,13 @@
30#define NCP_PACKET_SIZE_INTERNAL 65536 30#define NCP_PACKET_SIZE_INTERNAL 65536
31 31
32static int 32static int
33ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info __user *arg) 33ncp_get_fs_info(struct ncp_server * server, struct file *file,
34 struct ncp_fs_info __user *arg)
34{ 35{
36 struct inode *inode = file->f_dentry->d_inode;
35 struct ncp_fs_info info; 37 struct ncp_fs_info info;
36 38
37 if ((permission(inode, MAY_WRITE, NULL) != 0) 39 if ((file_permission(file, MAY_WRITE) != 0)
38 && (current->uid != server->m.mounted_uid)) { 40 && (current->uid != server->m.mounted_uid)) {
39 return -EACCES; 41 return -EACCES;
40 } 42 }
@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in
58} 60}
59 61
60static int 62static int
61ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2 __user * arg) 63ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
64 struct ncp_fs_info_v2 __user * arg)
62{ 65{
66 struct inode *inode = file->f_dentry->d_inode;
63 struct ncp_fs_info_v2 info2; 67 struct ncp_fs_info_v2 info2;
64 68
65 if ((permission(inode, MAY_WRITE, NULL) != 0) 69 if ((file_permission(file, MAY_WRITE) != 0)
66 && (current->uid != server->m.mounted_uid)) { 70 && (current->uid != server->m.mounted_uid)) {
67 return -EACCES; 71 return -EACCES;
68 } 72 }
@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
190 switch (cmd) { 194 switch (cmd) {
191 case NCP_IOC_NCPREQUEST: 195 case NCP_IOC_NCPREQUEST:
192 196
193 if ((permission(inode, MAY_WRITE, NULL) != 0) 197 if ((file_permission(filp, MAY_WRITE) != 0)
194 && (current->uid != server->m.mounted_uid)) { 198 && (current->uid != server->m.mounted_uid)) {
195 return -EACCES; 199 return -EACCES;
196 } 200 }
@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
245 return ncp_conn_logged_in(inode->i_sb); 249 return ncp_conn_logged_in(inode->i_sb);
246 250
247 case NCP_IOC_GET_FS_INFO: 251 case NCP_IOC_GET_FS_INFO:
248 return ncp_get_fs_info(server, inode, argp); 252 return ncp_get_fs_info(server, filp, argp);
249 253
250 case NCP_IOC_GET_FS_INFO_V2: 254 case NCP_IOC_GET_FS_INFO_V2:
251 return ncp_get_fs_info_v2(server, inode, argp); 255 return ncp_get_fs_info_v2(server, filp, argp);
252 256
253 case NCP_IOC_GETMOUNTUID2: 257 case NCP_IOC_GETMOUNTUID2:
254 { 258 {
255 unsigned long tmp = server->m.mounted_uid; 259 unsigned long tmp = server->m.mounted_uid;
256 260
257 if ( (permission(inode, MAY_READ, NULL) != 0) 261 if ((file_permission(filp, MAY_READ) != 0)
258 && (current->uid != server->m.mounted_uid)) 262 && (current->uid != server->m.mounted_uid))
259 { 263 {
260 return -EACCES; 264 return -EACCES;
@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
268 { 272 {
269 struct ncp_setroot_ioctl sr; 273 struct ncp_setroot_ioctl sr;
270 274
271 if ( (permission(inode, MAY_READ, NULL) != 0) 275 if ((file_permission(filp, MAY_READ) != 0)
272 && (current->uid != server->m.mounted_uid)) 276 && (current->uid != server->m.mounted_uid))
273 { 277 {
274 return -EACCES; 278 return -EACCES;
@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
343 347
344#ifdef CONFIG_NCPFS_PACKET_SIGNING 348#ifdef CONFIG_NCPFS_PACKET_SIGNING
345 case NCP_IOC_SIGN_INIT: 349 case NCP_IOC_SIGN_INIT:
346 if ((permission(inode, MAY_WRITE, NULL) != 0) 350 if ((file_permission(filp, MAY_WRITE) != 0)
347 && (current->uid != server->m.mounted_uid)) 351 && (current->uid != server->m.mounted_uid))
348 { 352 {
349 return -EACCES; 353 return -EACCES;
@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
366 return 0; 370 return 0;
367 371
368 case NCP_IOC_SIGN_WANTED: 372 case NCP_IOC_SIGN_WANTED:
369 if ( (permission(inode, MAY_READ, NULL) != 0) 373 if ((file_permission(filp, MAY_READ) != 0)
370 && (current->uid != server->m.mounted_uid)) 374 && (current->uid != server->m.mounted_uid))
371 { 375 {
372 return -EACCES; 376 return -EACCES;
@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
379 { 383 {
380 int newstate; 384 int newstate;
381 385
382 if ( (permission(inode, MAY_WRITE, NULL) != 0) 386 if ((file_permission(filp, MAY_WRITE) != 0)
383 && (current->uid != server->m.mounted_uid)) 387 && (current->uid != server->m.mounted_uid))
384 { 388 {
385 return -EACCES; 389 return -EACCES;
@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
400 404
401#ifdef CONFIG_NCPFS_IOCTL_LOCKING 405#ifdef CONFIG_NCPFS_IOCTL_LOCKING
402 case NCP_IOC_LOCKUNLOCK: 406 case NCP_IOC_LOCKUNLOCK:
403 if ( (permission(inode, MAY_WRITE, NULL) != 0) 407 if ((file_permission(filp, MAY_WRITE) != 0)
404 && (current->uid != server->m.mounted_uid)) 408 && (current->uid != server->m.mounted_uid))
405 { 409 {
406 return -EACCES; 410 return -EACCES;
@@ -605,7 +609,7 @@ outrel:
605#endif /* CONFIG_NCPFS_NLS */ 609#endif /* CONFIG_NCPFS_NLS */
606 610
607 case NCP_IOC_SETDENTRYTTL: 611 case NCP_IOC_SETDENTRYTTL:
608 if ((permission(inode, MAY_WRITE, NULL) != 0) && 612 if ((file_permission(filp, MAY_WRITE) != 0) &&
609 (current->uid != server->m.mounted_uid)) 613 (current->uid != server->m.mounted_uid))
610 return -EACCES; 614 return -EACCES;
611 { 615 {
@@ -635,7 +639,7 @@ outrel:
635 so we have this out of switch */ 639 so we have this out of switch */
636 if (cmd == NCP_IOC_GETMOUNTUID) { 640 if (cmd == NCP_IOC_GETMOUNTUID) {
637 __kernel_uid_t uid = 0; 641 __kernel_uid_t uid = 0;
638 if ((permission(inode, MAY_READ, NULL) != 0) 642 if ((file_permission(filp, MAY_READ) != 0)
639 && (current->uid != server->m.mounted_uid)) { 643 && (current->uid != server->m.mounted_uid)) {
640 return -EACCES; 644 return -EACCES;
641 } 645 }
diff --git a/fs/open.c b/fs/open.c
index 6e8136751e9a..f53a5b9ffb7d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -240,7 +240,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
240 if (!S_ISREG(inode->i_mode)) 240 if (!S_ISREG(inode->i_mode))
241 goto dput_and_out; 241 goto dput_and_out;
242 242
243 error = permission(inode,MAY_WRITE,&nd); 243 error = vfs_permission(&nd, MAY_WRITE);
244 if (error) 244 if (error)
245 goto dput_and_out; 245 goto dput_and_out;
246 246
@@ -394,7 +394,7 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
394 goto dput_and_out; 394 goto dput_and_out;
395 395
396 if (current->fsuid != inode->i_uid && 396 if (current->fsuid != inode->i_uid &&
397 (error = permission(inode,MAY_WRITE,&nd)) != 0) 397 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
398 goto dput_and_out; 398 goto dput_and_out;
399 } 399 }
400 down(&inode->i_sem); 400 down(&inode->i_sem);
@@ -447,7 +447,7 @@ long do_utimes(char __user * filename, struct timeval * times)
447 goto dput_and_out; 447 goto dput_and_out;
448 448
449 if (current->fsuid != inode->i_uid && 449 if (current->fsuid != inode->i_uid &&
450 (error = permission(inode,MAY_WRITE,&nd)) != 0) 450 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
451 goto dput_and_out; 451 goto dput_and_out;
452 } 452 }
453 down(&inode->i_sem); 453 down(&inode->i_sem);
@@ -506,7 +506,7 @@ asmlinkage long sys_access(const char __user * filename, int mode)
506 506
507 res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); 507 res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
508 if (!res) { 508 if (!res) {
509 res = permission(nd.dentry->d_inode, mode, &nd); 509 res = vfs_permission(&nd, mode);
510 /* SuS v2 requires we report a read only fs too */ 510 /* SuS v2 requires we report a read only fs too */
511 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) 511 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
512 && !special_file(nd.dentry->d_inode->i_mode)) 512 && !special_file(nd.dentry->d_inode->i_mode))
@@ -530,7 +530,7 @@ asmlinkage long sys_chdir(const char __user * filename)
530 if (error) 530 if (error)
531 goto out; 531 goto out;
532 532
533 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); 533 error = vfs_permission(&nd, MAY_EXEC);
534 if (error) 534 if (error)
535 goto dput_and_out; 535 goto dput_and_out;
536 536
@@ -563,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
563 if (!S_ISDIR(inode->i_mode)) 563 if (!S_ISDIR(inode->i_mode))
564 goto out_putf; 564 goto out_putf;
565 565
566 error = permission(inode, MAY_EXEC, NULL); 566 error = file_permission(file, MAY_EXEC);
567 if (!error) 567 if (!error)
568 set_fs_pwd(current->fs, mnt, dentry); 568 set_fs_pwd(current->fs, mnt, dentry);
569out_putf: 569out_putf:
@@ -581,7 +581,7 @@ asmlinkage long sys_chroot(const char __user * filename)
581 if (error) 581 if (error)
582 goto out; 582 goto out;
583 583
584 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); 584 error = vfs_permission(&nd, MAY_EXEC);
585 if (error) 585 if (error)
586 goto dput_and_out; 586 goto dput_and_out;
587 587
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index c20babd6216d..7892a865b58a 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -251,12 +251,12 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl
251 blocks_to_allocate, 251 blocks_to_allocate,
252 blocks_to_allocate); 252 blocks_to_allocate);
253 if (res != CARRY_ON) { 253 if (res != CARRY_ON) {
254 res = -ENOSPC; 254 res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
255 pathrelse(&path); 255 pathrelse(&path);
256 goto error_exit; 256 goto error_exit;
257 } 257 }
258 } else { 258 } else {
259 res = -ENOSPC; 259 res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
260 pathrelse(&path); 260 pathrelse(&path);
261 goto error_exit; 261 goto error_exit;
262 } 262 }
diff --git a/fs/udf/file.c b/fs/udf/file.c
index bb40d63f328f..01f520c71dc1 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -186,7 +186,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
186{ 186{
187 int result = -EINVAL; 187 int result = -EINVAL;
188 188
189 if ( permission(inode, MAY_READ, NULL) != 0 ) 189 if ( file_permission(filp, MAY_READ) != 0 )
190 { 190 {
191 udf_debug("no permission to access inode %lu\n", 191 udf_debug("no permission to access inode %lu\n",
192 inode->i_ino); 192 inode->i_ino);
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 44fed10af0dd..d8e21ba0cccc 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -72,7 +72,6 @@
72#include <linux/init.h> 72#include <linux/init.h>
73#include <linux/list.h> 73#include <linux/list.h>
74#include <linux/proc_fs.h> 74#include <linux/proc_fs.h>
75#include <linux/version.h>
76#include <linux/sort.h> 75#include <linux/sort.h>
77 76
78#include <asm/page.h> 77#include <asm/page.h>
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index 99b50d2bda9b..1a48dbb902a7 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -17,12 +17,5 @@
17 */ 17 */
18#ifndef __XFS_H__ 18#ifndef __XFS_H__
19#define __XFS_H__ 19#define __XFS_H__
20
21#include <linux/version.h>
22#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
23#include <linux-2.6/xfs_linux.h> 20#include <linux-2.6/xfs_linux.h>
24#else
25#include <linux-2.4/xfs_linux.h>
26#endif
27
28#endif /* __XFS_H__ */ 21#endif /* __XFS_H__ */
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 5a5c7a63e80b..864bf6955689 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -18,6 +18,7 @@
18#ifndef __XFS_DMAPI_H__ 18#ifndef __XFS_DMAPI_H__
19#define __XFS_DMAPI_H__ 19#define __XFS_DMAPI_H__
20 20
21#include <linux/version.h>
21/* Values used to define the on-disk version of dm_attrname_t. All 22/* Values used to define the on-disk version of dm_attrname_t. All
22 * on-disk attribute names start with the 8-byte string "SGI_DMI_". 23 * on-disk attribute names start with the 8-byte string "SGI_DMI_".
23 * 24 *
diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
index 68934a25931f..6126afe27380 100644
--- a/include/asm-alpha/ide.h
+++ b/include/asm-alpha/ide.h
@@ -15,10 +15,6 @@
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17 17
18#ifndef MAX_HWIFS
19#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
20#endif
21
22#define IDE_ARCH_OBSOLETE_DEFAULTS 18#define IDE_ARCH_OBSOLETE_DEFAULTS
23 19
24static inline int ide_default_irq(unsigned long base) 20static inline int ide_default_irq(unsigned long base)
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index 55d85eea8c1a..cfb413c845f7 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -44,5 +44,6 @@ extern unsigned int processor_id;
44#include "ixdp425.h" 44#include "ixdp425.h"
45#include "coyote.h" 45#include "coyote.h"
46#include "prpmc1100.h" 46#include "prpmc1100.h"
47#include "nslu2.h"
47 48
48#endif /* _ASM_ARCH_HARDWARE_H */ 49#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
index ca808281c7f9..2cf4930372bc 100644
--- a/include/asm-arm/arch-ixp4xx/irqs.h
+++ b/include/asm-arm/arch-ixp4xx/irqs.h
@@ -93,4 +93,11 @@
93#define IRQ_COYOTE_PCI_SLOT1 IRQ_IXP4XX_GPIO11 93#define IRQ_COYOTE_PCI_SLOT1 IRQ_IXP4XX_GPIO11
94#define IRQ_COYOTE_IDE IRQ_IXP4XX_GPIO5 94#define IRQ_COYOTE_IDE IRQ_IXP4XX_GPIO5
95 95
96/*
97 * NSLU2 board IRQs
98 */
99#define IRQ_NSLU2_PCI_INTA IRQ_IXP4XX_GPIO11
100#define IRQ_NSLU2_PCI_INTB IRQ_IXP4XX_GPIO10
101#define IRQ_NSLU2_PCI_INTC IRQ_IXP4XX_GPIO9
102
96#endif 103#endif
diff --git a/include/asm-arm/arch-ixp4xx/nslu2.h b/include/asm-arm/arch-ixp4xx/nslu2.h
new file mode 100644
index 000000000000..b8b347a559c7
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/nslu2.h
@@ -0,0 +1,96 @@
1/*
2 * include/asm-arm/arch-ixp4xx/nslu2.h
3 *
4 * NSLU2 platform specific definitions
5 *
6 * Author: Mark Rakes <mrakes AT mac.com>
7 * Maintainers: http://www.nslu2-linux.org
8 *
9 * based on ixdp425.h:
10 * Copyright 2004 (c) MontaVista, Software, Inc.
11 *
12 * This file is licensed under the terms of the GNU General Public
13 * License version 2. This program is licensed "as is" without any
14 * warranty of any kind, whether express or implied.
15 */
16
17#ifndef __ASM_ARCH_HARDWARE_H__
18#error "Do not include this directly, instead #include <asm/hardware.h>"
19#endif
20
21#define NSLU2_FLASH_BASE IXP4XX_EXP_BUS_CS0_BASE_PHYS
22#define NSLU2_FLASH_SIZE IXP4XX_EXP_BUS_CSX_REGION_SIZE
23
24#define NSLU2_SDA_PIN 7
25#define NSLU2_SCL_PIN 6
26
27/*
28 * NSLU2 PCI IRQs
29 */
30#define NSLU2_PCI_MAX_DEV 3
31#define NSLU2_PCI_IRQ_LINES 3
32
33
34/* PCI controller GPIO to IRQ pin mappings */
35#define NSLU2_PCI_INTA_PIN 11
36#define NSLU2_PCI_INTB_PIN 10
37#define NSLU2_PCI_INTC_PIN 9
38#define NSLU2_PCI_INTD_PIN 8
39
40
41/* NSLU2 Timer */
42#define NSLU2_FREQ 66000000
43#define NSLU2_CLOCK_TICK_RATE (((NSLU2_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
44#define NSLU2_CLOCK_TICKS_PER_USEC ((NSLU2_CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
45
46/* GPIO */
47
48#define NSLU2_GPIO0 0
49#define NSLU2_GPIO1 1
50#define NSLU2_GPIO2 2
51#define NSLU2_GPIO3 3
52#define NSLU2_GPIO4 4
53#define NSLU2_GPIO5 5
54#define NSLU2_GPIO6 6
55#define NSLU2_GPIO7 7
56#define NSLU2_GPIO8 8
57#define NSLU2_GPIO9 9
58#define NSLU2_GPIO10 10
59#define NSLU2_GPIO11 11
60#define NSLU2_GPIO12 12
61#define NSLU2_GPIO13 13
62#define NSLU2_GPIO14 14
63#define NSLU2_GPIO15 15
64
65/* Buttons */
66
67#define NSLU2_PB_GPIO NSLU2_GPIO5
68#define NSLU2_PO_GPIO NSLU2_GPIO8 /* power off */
69#define NSLU2_RB_GPIO NSLU2_GPIO12
70
71#define NSLU2_PB_IRQ IRQ_IXP4XX_GPIO5
72#define NSLU2_RB_IRQ IRQ_IXP4XX_GPIO12
73
74#define NSLU2_PB_BM (1L << NSLU2_PB_GPIO)
75#define NSLU2_PO_BM (1L << NSLU2_PO_GPIO)
76#define NSLU2_RB_BM (1L << NSLU2_RB_GPIO)
77
78/* Buzzer */
79
80#define NSLU2_GPIO_BUZZ 4
81#define NSLU2_BZ_BM (1L << NSLU2_GPIO_BUZZ)
82/* LEDs */
83
84#define NSLU2_LED_RED NSLU2_GPIO0
85#define NSLU2_LED_GRN NSLU2_GPIO1
86
87#define NSLU2_LED_RED_BM (1L << NSLU2_LED_RED)
88#define NSLU2_LED_GRN_BM (1L << NSLU2_LED_GRN)
89
90#define NSLU2_LED_DISK1 NSLU2_GPIO2
91#define NSLU2_LED_DISK2 NSLU2_GPIO3
92
93#define NSLU2_LED_DISK1_BM (1L << NSLU2_GPIO2)
94#define NSLU2_LED_DISK2_BM (1L << NSLU2_GPIO3)
95
96
diff --git a/include/asm-arm/arch-omap/board-h4.h b/include/asm-arm/arch-omap/board-h4.h
index d64ee9211eed..33ea29a41654 100644
--- a/include/asm-arm/arch-omap/board-h4.h
+++ b/include/asm-arm/arch-omap/board-h4.h
@@ -34,5 +34,11 @@
34#define OMAP24XX_ETHR_START 0x08000300 34#define OMAP24XX_ETHR_START 0x08000300
35#define OMAP24XX_ETHR_GPIO_IRQ 92 35#define OMAP24XX_ETHR_GPIO_IRQ 92
36 36
37#define H4_CS0_BASE 0x04000000
38
39#define H4_CS0_BASE 0x04000000
40
41#define H4_CS0_BASE 0x04000000
42
37#endif /* __ASM_ARCH_OMAP_H4_H */ 43#endif /* __ASM_ARCH_OMAP_H4_H */
38 44
diff --git a/include/asm-arm/arch-omap/board-innovator.h b/include/asm-arm/arch-omap/board-innovator.h
index 79574e0ed13d..b3cf33441f6e 100644
--- a/include/asm-arm/arch-omap/board-innovator.h
+++ b/include/asm-arm/arch-omap/board-innovator.h
@@ -26,7 +26,7 @@
26#ifndef __ASM_ARCH_OMAP_INNOVATOR_H 26#ifndef __ASM_ARCH_OMAP_INNOVATOR_H
27#define __ASM_ARCH_OMAP_INNOVATOR_H 27#define __ASM_ARCH_OMAP_INNOVATOR_H
28 28
29#if defined (CONFIG_ARCH_OMAP1510) 29#if defined (CONFIG_ARCH_OMAP15XX)
30 30
31#ifndef OMAP_SDRAM_DEVICE 31#ifndef OMAP_SDRAM_DEVICE
32#define OMAP_SDRAM_DEVICE D256M_1X16_4B 32#define OMAP_SDRAM_DEVICE D256M_1X16_4B
@@ -44,7 +44,7 @@ void fpga_write(unsigned char val, int reg);
44unsigned char fpga_read(int reg); 44unsigned char fpga_read(int reg);
45#endif 45#endif
46 46
47#endif /* CONFIG_ARCH_OMAP1510 */ 47#endif /* CONFIG_ARCH_OMAP15XX */
48 48
49#if defined (CONFIG_ARCH_OMAP16XX) 49#if defined (CONFIG_ARCH_OMAP16XX)
50 50
diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h
new file mode 100644
index 000000000000..740c297eb11c
--- /dev/null
+++ b/include/asm-arm/arch-omap/clock.h
@@ -0,0 +1,91 @@
1/*
2 * linux/include/asm-arm/arch-omap/clock.h
3 *
4 * Copyright (C) 2004 - 2005 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ARCH_ARM_OMAP_CLOCK_H
14#define __ARCH_ARM_OMAP_CLOCK_H
15
16struct module;
17
18struct clk {
19 struct list_head node;
20 struct module *owner;
21 const char *name;
22 struct clk *parent;
23 unsigned long rate;
24 __u32 flags;
25 void __iomem *enable_reg;
26 __u8 enable_bit;
27 __u8 rate_offset;
28 __u8 src_offset;
29 __s8 usecount;
30 void (*recalc)(struct clk *);
31 int (*set_rate)(struct clk *, unsigned long);
32 long (*round_rate)(struct clk *, unsigned long);
33 void (*init)(struct clk *);
34 int (*enable)(struct clk *);
35 void (*disable)(struct clk *);
36};
37
38struct clk_functions {
39 int (*clk_enable)(struct clk *clk);
40 void (*clk_disable)(struct clk *clk);
41 int (*clk_use)(struct clk *clk);
42 void (*clk_unuse)(struct clk *clk);
43 long (*clk_round_rate)(struct clk *clk, unsigned long rate);
44 int (*clk_set_rate)(struct clk *clk, unsigned long rate);
45 int (*clk_set_parent)(struct clk *clk, struct clk *parent);
46 struct clk * (*clk_get_parent)(struct clk *clk);
47 void (*clk_allow_idle)(struct clk *clk);
48 void (*clk_deny_idle)(struct clk *clk);
49};
50
51extern unsigned int mpurate;
52extern struct list_head clocks;
53extern spinlock_t clockfw_lock;
54
55extern int clk_init(struct clk_functions * custom_clocks);
56extern int clk_register(struct clk *clk);
57extern void clk_unregister(struct clk *clk);
58extern void propagate_rate(struct clk *clk);
59extern void followparent_recalc(struct clk * clk);
60extern void clk_allow_idle(struct clk *clk);
61extern void clk_deny_idle(struct clk *clk);
62
63/* Clock flags */
64#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */
65#define RATE_FIXED (1 << 1) /* Fixed clock rate */
66#define RATE_PROPAGATES (1 << 2) /* Program children too */
67#define VIRTUAL_CLOCK (1 << 3) /* Composite clock from table */
68#define ALWAYS_ENABLED (1 << 4) /* Clock cannot be disabled */
69#define ENABLE_REG_32BIT (1 << 5) /* Use 32-bit access */
70#define VIRTUAL_IO_ADDRESS (1 << 6) /* Clock in virtual address */
71#define CLOCK_IDLE_CONTROL (1 << 7)
72#define CLOCK_NO_IDLE_PARENT (1 << 8)
73#define DELAYED_APP (1 << 9) /* Delay application of clock */
74#define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
75#define CM_MPU_SEL1 (1 << 11) /* Domain divider/source */
76#define CM_DSP_SEL1 (1 << 12)
77#define CM_GFX_SEL1 (1 << 13)
78#define CM_MODEM_SEL1 (1 << 14)
79#define CM_CORE_SEL1 (1 << 15) /* Sets divider for many */
80#define CM_CORE_SEL2 (1 << 16) /* sets parent for GPT */
81#define CM_WKUP_SEL1 (1 << 17)
82#define CM_PLL_SEL1 (1 << 18)
83#define CM_PLL_SEL2 (1 << 19)
84#define CM_SYSCLKOUT_SEL1 (1 << 20)
85#define CLOCK_IN_OMAP730 (1 << 21)
86#define CLOCK_IN_OMAP1510 (1 << 22)
87#define CLOCK_IN_OMAP16XX (1 << 23)
88#define CLOCK_IN_OMAP242X (1 << 24)
89#define CLOCK_IN_OMAP243X (1 << 25)
90
91#endif
diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h
index 2a676b4f13b5..08d58abd8218 100644
--- a/include/asm-arm/arch-omap/common.h
+++ b/include/asm-arm/arch-omap/common.h
@@ -31,6 +31,6 @@ struct sys_timer;
31 31
32extern void omap_map_common_io(void); 32extern void omap_map_common_io(void);
33extern struct sys_timer omap_timer; 33extern struct sys_timer omap_timer;
34extern void omap_serial_init(int ports[]); 34extern void omap_serial_init(void);
35 35
36#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ 36#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/cpu.h b/include/asm-arm/arch-omap/cpu.h
index 1119e2b53e72..ec7eb675d922 100644
--- a/include/asm-arm/arch-omap/cpu.h
+++ b/include/asm-arm/arch-omap/cpu.h
@@ -28,12 +28,7 @@
28 28
29extern unsigned int system_rev; 29extern unsigned int system_rev;
30 30
31#define OMAP_DIE_ID_0 0xfffe1800 31#define omap2_cpu_rev() ((system_rev >> 8) & 0x0f)
32#define OMAP_DIE_ID_1 0xfffe1804
33#define OMAP_PRODUCTION_ID_0 0xfffe2000
34#define OMAP_PRODUCTION_ID_1 0xfffe2004
35#define OMAP32_ID_0 0xfffed400
36#define OMAP32_ID_1 0xfffed404
37 32
38/* 33/*
39 * Test if multicore OMAP support is needed 34 * Test if multicore OMAP support is needed
@@ -50,7 +45,7 @@ extern unsigned int system_rev;
50# define OMAP_NAME omap730 45# define OMAP_NAME omap730
51# endif 46# endif
52#endif 47#endif
53#ifdef CONFIG_ARCH_OMAP1510 48#ifdef CONFIG_ARCH_OMAP15XX
54# ifdef OMAP_NAME 49# ifdef OMAP_NAME
55# undef MULTI_OMAP1 50# undef MULTI_OMAP1
56# define MULTI_OMAP1 51# define MULTI_OMAP1
@@ -79,9 +74,11 @@ extern unsigned int system_rev;
79 * Macros to group OMAP into cpu classes. 74 * Macros to group OMAP into cpu classes.
80 * These can be used in most places. 75 * These can be used in most places.
81 * cpu_is_omap7xx(): True for OMAP730 76 * cpu_is_omap7xx(): True for OMAP730
82 * cpu_is_omap15xx(): True for OMAP1510 and OMAP5910 77 * cpu_is_omap15xx(): True for OMAP1510, OMAP5910 and OMAP310
83 * cpu_is_omap16xx(): True for OMAP1610, OMAP5912 and OMAP1710 78 * cpu_is_omap16xx(): True for OMAP1610, OMAP5912 and OMAP1710
84 * cpu_is_omap24xx(): True for OMAP2420 79 * cpu_is_omap24xx(): True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
80 * cpu_is_omap242x(): True for OMAP2420, OMAP2422, OMAP2423
81 * cpu_is_omap243x(): True for OMAP2430
85 */ 82 */
86#define GET_OMAP_CLASS (system_rev & 0xff) 83#define GET_OMAP_CLASS (system_rev & 0xff)
87 84
@@ -91,22 +88,35 @@ static inline int is_omap ##class (void) \
91 return (GET_OMAP_CLASS == (id)) ? 1 : 0; \ 88 return (GET_OMAP_CLASS == (id)) ? 1 : 0; \
92} 89}
93 90
91#define GET_OMAP_SUBCLASS ((system_rev >> 20) & 0x0fff)
92
93#define IS_OMAP_SUBCLASS(subclass, id) \
94static inline int is_omap ##subclass (void) \
95{ \
96 return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \
97}
98
94IS_OMAP_CLASS(7xx, 0x07) 99IS_OMAP_CLASS(7xx, 0x07)
95IS_OMAP_CLASS(15xx, 0x15) 100IS_OMAP_CLASS(15xx, 0x15)
96IS_OMAP_CLASS(16xx, 0x16) 101IS_OMAP_CLASS(16xx, 0x16)
97IS_OMAP_CLASS(24xx, 0x24) 102IS_OMAP_CLASS(24xx, 0x24)
98 103
104IS_OMAP_SUBCLASS(242x, 0x242)
105IS_OMAP_SUBCLASS(243x, 0x243)
106
99#define cpu_is_omap7xx() 0 107#define cpu_is_omap7xx() 0
100#define cpu_is_omap15xx() 0 108#define cpu_is_omap15xx() 0
101#define cpu_is_omap16xx() 0 109#define cpu_is_omap16xx() 0
102#define cpu_is_omap24xx() 0 110#define cpu_is_omap24xx() 0
111#define cpu_is_omap242x() 0
112#define cpu_is_omap243x() 0
103 113
104#if defined(MULTI_OMAP1) 114#if defined(MULTI_OMAP1)
105# if defined(CONFIG_ARCH_OMAP730) 115# if defined(CONFIG_ARCH_OMAP730)
106# undef cpu_is_omap7xx 116# undef cpu_is_omap7xx
107# define cpu_is_omap7xx() is_omap7xx() 117# define cpu_is_omap7xx() is_omap7xx()
108# endif 118# endif
109# if defined(CONFIG_ARCH_OMAP1510) 119# if defined(CONFIG_ARCH_OMAP15XX)
110# undef cpu_is_omap15xx 120# undef cpu_is_omap15xx
111# define cpu_is_omap15xx() is_omap15xx() 121# define cpu_is_omap15xx() is_omap15xx()
112# endif 122# endif
@@ -119,7 +129,7 @@ IS_OMAP_CLASS(24xx, 0x24)
119# undef cpu_is_omap7xx 129# undef cpu_is_omap7xx
120# define cpu_is_omap7xx() 1 130# define cpu_is_omap7xx() 1
121# endif 131# endif
122# if defined(CONFIG_ARCH_OMAP1510) 132# if defined(CONFIG_ARCH_OMAP15XX)
123# undef cpu_is_omap15xx 133# undef cpu_is_omap15xx
124# define cpu_is_omap15xx() 1 134# define cpu_is_omap15xx() 1
125# endif 135# endif
@@ -129,13 +139,18 @@ IS_OMAP_CLASS(24xx, 0x24)
129# endif 139# endif
130# if defined(CONFIG_ARCH_OMAP24XX) 140# if defined(CONFIG_ARCH_OMAP24XX)
131# undef cpu_is_omap24xx 141# undef cpu_is_omap24xx
142# undef cpu_is_omap242x
143# undef cpu_is_omap243x
132# define cpu_is_omap24xx() 1 144# define cpu_is_omap24xx() 1
145# define cpu_is_omap242x() is_omap242x()
146# define cpu_is_omap243x() is_omap243x()
133# endif 147# endif
134#endif 148#endif
135 149
136/* 150/*
137 * Macros to detect individual cpu types. 151 * Macros to detect individual cpu types.
138 * These are only rarely needed. 152 * These are only rarely needed.
153 * cpu_is_omap330(): True for OMAP330
139 * cpu_is_omap730(): True for OMAP730 154 * cpu_is_omap730(): True for OMAP730
140 * cpu_is_omap1510(): True for OMAP1510 155 * cpu_is_omap1510(): True for OMAP1510
141 * cpu_is_omap1610(): True for OMAP1610 156 * cpu_is_omap1610(): True for OMAP1610
@@ -144,6 +159,9 @@ IS_OMAP_CLASS(24xx, 0x24)
144 * cpu_is_omap1621(): True for OMAP1621 159 * cpu_is_omap1621(): True for OMAP1621
145 * cpu_is_omap1710(): True for OMAP1710 160 * cpu_is_omap1710(): True for OMAP1710
146 * cpu_is_omap2420(): True for OMAP2420 161 * cpu_is_omap2420(): True for OMAP2420
162 * cpu_is_omap2422(): True for OMAP2422
163 * cpu_is_omap2423(): True for OMAP2423
164 * cpu_is_omap2430(): True for OMAP2430
147 */ 165 */
148#define GET_OMAP_TYPE ((system_rev >> 16) & 0xffff) 166#define GET_OMAP_TYPE ((system_rev >> 16) & 0xffff)
149 167
@@ -153,6 +171,7 @@ static inline int is_omap ##type (void) \
153 return (GET_OMAP_TYPE == (id)) ? 1 : 0; \ 171 return (GET_OMAP_TYPE == (id)) ? 1 : 0; \
154} 172}
155 173
174IS_OMAP_TYPE(310, 0x0310)
156IS_OMAP_TYPE(730, 0x0730) 175IS_OMAP_TYPE(730, 0x0730)
157IS_OMAP_TYPE(1510, 0x1510) 176IS_OMAP_TYPE(1510, 0x1510)
158IS_OMAP_TYPE(1610, 0x1610) 177IS_OMAP_TYPE(1610, 0x1610)
@@ -161,7 +180,11 @@ IS_OMAP_TYPE(5912, 0x1611)
161IS_OMAP_TYPE(1621, 0x1621) 180IS_OMAP_TYPE(1621, 0x1621)
162IS_OMAP_TYPE(1710, 0x1710) 181IS_OMAP_TYPE(1710, 0x1710)
163IS_OMAP_TYPE(2420, 0x2420) 182IS_OMAP_TYPE(2420, 0x2420)
183IS_OMAP_TYPE(2422, 0x2422)
184IS_OMAP_TYPE(2423, 0x2423)
185IS_OMAP_TYPE(2430, 0x2430)
164 186
187#define cpu_is_omap310() 0
165#define cpu_is_omap730() 0 188#define cpu_is_omap730() 0
166#define cpu_is_omap1510() 0 189#define cpu_is_omap1510() 0
167#define cpu_is_omap1610() 0 190#define cpu_is_omap1610() 0
@@ -170,31 +193,33 @@ IS_OMAP_TYPE(2420, 0x2420)
170#define cpu_is_omap1621() 0 193#define cpu_is_omap1621() 0
171#define cpu_is_omap1710() 0 194#define cpu_is_omap1710() 0
172#define cpu_is_omap2420() 0 195#define cpu_is_omap2420() 0
196#define cpu_is_omap2422() 0
197#define cpu_is_omap2423() 0
198#define cpu_is_omap2430() 0
173 199
174#if defined(MULTI_OMAP1) 200#if defined(MULTI_OMAP1)
175# if defined(CONFIG_ARCH_OMAP730) 201# if defined(CONFIG_ARCH_OMAP730)
176# undef cpu_is_omap730 202# undef cpu_is_omap730
177# define cpu_is_omap730() is_omap730() 203# define cpu_is_omap730() is_omap730()
178# endif 204# endif
179# if defined(CONFIG_ARCH_OMAP1510)
180# undef cpu_is_omap1510
181# define cpu_is_omap1510() is_omap1510()
182# endif
183#else 205#else
184# if defined(CONFIG_ARCH_OMAP730) 206# if defined(CONFIG_ARCH_OMAP730)
185# undef cpu_is_omap730 207# undef cpu_is_omap730
186# define cpu_is_omap730() 1 208# define cpu_is_omap730() 1
187# endif 209# endif
188# if defined(CONFIG_ARCH_OMAP1510)
189# undef cpu_is_omap1510
190# define cpu_is_omap1510() 1
191# endif
192#endif 210#endif
193 211
194/* 212/*
195 * Whether we have MULTI_OMAP1 or not, we still need to distinguish 213 * Whether we have MULTI_OMAP1 or not, we still need to distinguish
196 * between 1611B/5912 and 1710. 214 * between 330 vs. 1510 and 1611B/5912 vs. 1710.
197 */ 215 */
216#if defined(CONFIG_ARCH_OMAP15XX)
217# undef cpu_is_omap310
218# undef cpu_is_omap1510
219# define cpu_is_omap310() is_omap310()
220# define cpu_is_omap1510() is_omap1510()
221#endif
222
198#if defined(CONFIG_ARCH_OMAP16XX) 223#if defined(CONFIG_ARCH_OMAP16XX)
199# undef cpu_is_omap1610 224# undef cpu_is_omap1610
200# undef cpu_is_omap1611 225# undef cpu_is_omap1611
@@ -208,9 +233,20 @@ IS_OMAP_TYPE(2420, 0x2420)
208# define cpu_is_omap1710() is_omap1710() 233# define cpu_is_omap1710() is_omap1710()
209#endif 234#endif
210 235
211#if defined(CONFIG_ARCH_OMAP2420) 236#if defined(CONFIG_ARCH_OMAP24XX)
212# undef cpu_is_omap2420 237# undef cpu_is_omap2420
213# define cpu_is_omap2420() 1 238# undef cpu_is_omap2422
239# undef cpu_is_omap2423
240# undef cpu_is_omap2430
241# define cpu_is_omap2420() is_omap2420()
242# define cpu_is_omap2422() is_omap2422()
243# define cpu_is_omap2423() is_omap2423()
244# define cpu_is_omap2430() is_omap2430()
214#endif 245#endif
215 246
247/* Macros to detect if we have OMAP1 or OMAP2 */
248#define cpu_class_is_omap1() (cpu_is_omap730() || cpu_is_omap15xx() || \
249 cpu_is_omap16xx())
250#define cpu_class_is_omap2() cpu_is_omap24xx()
251
216#endif 252#endif
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index 04ebef5c6e95..ccbcb580a5c1 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -22,9 +22,109 @@
22#define __ASM_ARCH_DMA_H 22#define __ASM_ARCH_DMA_H
23 23
24#define MAX_DMA_ADDRESS 0xffffffff 24#define MAX_DMA_ADDRESS 0xffffffff
25#define MAX_DMA_CHANNELS 0
26
27/* Hardware registers for omap1 */
28#define OMAP_DMA_BASE (0xfffed800)
29#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400)
30#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404)
31#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408)
32#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442)
33#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444)
34#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446)
35#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448)
36#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a)
37#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c)
38#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e)
39#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450)
40#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452)
41#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454)
42#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456)
43#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458)
44#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a)
45#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460)
46#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480)
47#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482)
48#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0)
49
50/* Hardware registers for omap2 */
51#define OMAP24XX_DMA_BASE (L4_24XX_BASE + 0x56000)
52#define OMAP_DMA4_REVISION (OMAP24XX_DMA_BASE + 0x00)
53#define OMAP_DMA4_GCR_REG (OMAP24XX_DMA_BASE + 0x78)
54#define OMAP_DMA4_IRQSTATUS_L0 (OMAP24XX_DMA_BASE + 0x08)
55#define OMAP_DMA4_IRQSTATUS_L1 (OMAP24XX_DMA_BASE + 0x0c)
56#define OMAP_DMA4_IRQSTATUS_L2 (OMAP24XX_DMA_BASE + 0x10)
57#define OMAP_DMA4_IRQSTATUS_L3 (OMAP24XX_DMA_BASE + 0x14)
58#define OMAP_DMA4_IRQENABLE_L0 (OMAP24XX_DMA_BASE + 0x18)
59#define OMAP_DMA4_IRQENABLE_L1 (OMAP24XX_DMA_BASE + 0x1c)
60#define OMAP_DMA4_IRQENABLE_L2 (OMAP24XX_DMA_BASE + 0x20)
61#define OMAP_DMA4_IRQENABLE_L3 (OMAP24XX_DMA_BASE + 0x24)
62#define OMAP_DMA4_SYSSTATUS (OMAP24XX_DMA_BASE + 0x28)
63#define OMAP_DMA4_CAPS_0 (OMAP24XX_DMA_BASE + 0x64)
64#define OMAP_DMA4_CAPS_2 (OMAP24XX_DMA_BASE + 0x6c)
65#define OMAP_DMA4_CAPS_3 (OMAP24XX_DMA_BASE + 0x70)
66#define OMAP_DMA4_CAPS_4 (OMAP24XX_DMA_BASE + 0x74)
67
68#ifdef CONFIG_ARCH_OMAP1
25 69
26#define OMAP_LOGICAL_DMA_CH_COUNT 17 70#define OMAP_LOGICAL_DMA_CH_COUNT 17
27 71
72/* Common channel specific registers for omap1 */
73#define OMAP_DMA_CSDP_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x00)
74#define OMAP_DMA_CCR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x02)
75#define OMAP_DMA_CICR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x04)
76#define OMAP_DMA_CSR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x06)
77#define OMAP_DMA_CEN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x10)
78#define OMAP_DMA_CFN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x12)
79#define OMAP_DMA_CSFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x14)
80#define OMAP_DMA_CSEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x16)
81#define OMAP_DMA_CSAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x18)
82#define OMAP_DMA_CDAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
83#define OMAP_DMA_CDEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
84#define OMAP_DMA_CDFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
85#define OMAP_DMA_CLNK_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x28)
86
87#else
88
89#define OMAP_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
90
91/* Common channel specific registers for omap2 */
92#define OMAP_DMA_CCR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x80)
93#define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x84)
94#define OMAP_DMA_CICR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x88)
95#define OMAP_DMA_CSR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x8c)
96#define OMAP_DMA_CSDP_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x90)
97#define OMAP_DMA_CEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x94)
98#define OMAP_DMA_CFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x98)
99#define OMAP_DMA_CSEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa4)
100#define OMAP_DMA_CSFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa8)
101#define OMAP_DMA_CDEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xac)
102#define OMAP_DMA_CDFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb0)
103#define OMAP_DMA_CSAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb4)
104#define OMAP_DMA_CDAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb8)
105
106#endif
107
108/* Channel specific registers only on omap1 */
109#define OMAP1_DMA_CSSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x08)
110#define OMAP1_DMA_CSSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
111#define OMAP1_DMA_CDSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
112#define OMAP1_DMA_CDSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
113#define OMAP1_DMA_COLOR_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x20)
114#define OMAP1_DMA_CCR2_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x24)
115#define OMAP1_DMA_COLOR_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x22)
116#define OMAP1_DMA_LCH_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
117
118/* Channel specific registers only on omap2 */
119#define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x9c)
120#define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa0)
121#define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xbc)
122#define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc0)
123#define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc4)
124
125/*----------------------------------------------------------------------------*/
126
127/* DMA channels for omap1 */
28#define OMAP_DMA_NO_DEVICE 0 128#define OMAP_DMA_NO_DEVICE 0
29#define OMAP_DMA_MCSI1_TX 1 129#define OMAP_DMA_MCSI1_TX 1
30#define OMAP_DMA_MCSI1_RX 2 130#define OMAP_DMA_MCSI1_RX 2
@@ -85,29 +185,72 @@
85#define OMAP_DMA_MMC2_RX 55 185#define OMAP_DMA_MMC2_RX 55
86#define OMAP_DMA_CRYPTO_DES_OUT 56 186#define OMAP_DMA_CRYPTO_DES_OUT 56
87 187
188/* DMA channels for 24xx */
189#define OMAP24XX_DMA_NO_DEVICE 0
190#define OMAP24XX_DMA_XTI_DMA 1 /* S_DMA_0 */
191#define OMAP24XX_DMA_EXT_NDMA_REQ0 2 /* S_DMA_1 */
192#define OMAP24XX_DMA_EXT_NDMA_REQ1 3 /* S_DMA_2 */
193#define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */
194#define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */
195#define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */
196#define OMAP24XX_DMA_VLYNQ_TX 7 /* S_DMA_6 */
197#define OMAP24XX_DMA_CWT 8 /* S_DMA_7 */
198#define OMAP24XX_DMA_AES_TX 9 /* S_DMA_8 */
199#define OMAP24XX_DMA_AES_RX 10 /* S_DMA_9 */
200#define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */
201#define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */
202#define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */
88 203
89#define OMAP_DMA_BASE (0xfffed800) 204#define OMAP24XX_DMA_EAC_AC_RD 17 /* S_DMA_16 */
90#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400) 205#define OMAP24XX_DMA_EAC_AC_WR 18 /* S_DMA_17 */
91#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404) 206#define OMAP24XX_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */
92#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408) 207#define OMAP24XX_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */
93#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442) 208#define OMAP24XX_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */
94#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444) 209#define OMAP24XX_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */
95#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446) 210#define OMAP24XX_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */
96#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448) 211#define OMAP24XX_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */
97#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a) 212#define OMAP24XX_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */
98#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c) 213#define OMAP24XX_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */
99#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e) 214#define OMAP24XX_DMA_I2C1_TX 27 /* S_DMA_26 */
100#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450) 215#define OMAP24XX_DMA_I2C1_RX 28 /* S_DMA_27 */
101#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452) 216#define OMAP24XX_DMA_I2C2_TX 29 /* S_DMA_28 */
102#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454) 217#define OMAP24XX_DMA_I2C2_RX 30 /* S_DMA_29 */
103#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456) 218#define OMAP24XX_DMA_MCBSP1_TX 31 /* SDMA_30 */
104#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458) 219#define OMAP24XX_DMA_MCBSP1_RX 32 /* SDMA_31 */
105#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a) 220#define OMAP24XX_DMA_MCBSP2_TX 33 /* SDMA_32 */
106#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460) 221#define OMAP24XX_DMA_MCBSP2_RX 34 /* SDMA_33 */
107#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480) 222#define OMAP24XX_DMA_SPI1_TX0 35 /* SDMA_34 */
108#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482) 223#define OMAP24XX_DMA_SPI1_RX0 36 /* SDMA_35 */
109#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0) 224#define OMAP24XX_DMA_SPI1_TX1 37 /* SDMA_36 */
225#define OMAP24XX_DMA_SPI1_RX1 38 /* SDMA_37 */
226#define OMAP24XX_DMA_SPI1_TX2 39 /* SDMA_38 */
227#define OMAP24XX_DMA_SPI1_RX2 40 /* SDMA_39 */
228#define OMAP24XX_DMA_SPI1_TX3 41 /* SDMA_40 */
229#define OMAP24XX_DMA_SPI1_RX3 42 /* SDMA_41 */
230#define OMAP24XX_DMA_SPI2_TX0 43 /* SDMA_42 */
231#define OMAP24XX_DMA_SPI2_RX0 44 /* SDMA_43 */
232#define OMAP24XX_DMA_SPI2_TX1 45 /* SDMA_44 */
233#define OMAP24XX_DMA_SPI2_RX1 46 /* SDMA_45 */
110 234
235#define OMAP24XX_DMA_UART1_TX 49 /* SDMA_48 */
236#define OMAP24XX_DMA_UART1_RX 50 /* SDMA_49 */
237#define OMAP24XX_DMA_UART2_TX 51 /* SDMA_50 */
238#define OMAP24XX_DMA_UART2_RX 52 /* SDMA_51 */
239#define OMAP24XX_DMA_UART3_TX 53 /* SDMA_52 */
240#define OMAP24XX_DMA_UART3_RX 54 /* SDMA_53 */
241#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* SDMA_54 */
242#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* SDMA_55 */
243#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* SDMA_56 */
244#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* SDMA_57 */
245#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* SDMA_58 */
246#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* SDMA_59 */
247#define OMAP24XX_DMA_MMC1_TX 61 /* SDMA_60 */
248#define OMAP24XX_DMA_MMC1_RX 62 /* SDMA_61 */
249#define OMAP24XX_DMA_MS 63 /* SDMA_62 */
250
251/*----------------------------------------------------------------------------*/
252
253/* Hardware registers for LCD DMA */
111#define OMAP1510_DMA_LCD_BASE (0xfffedb00) 254#define OMAP1510_DMA_LCD_BASE (0xfffedb00)
112#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00) 255#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00)
113#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02) 256#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02)
@@ -116,7 +259,7 @@
116#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08) 259#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08)
117 260
118#define OMAP1610_DMA_LCD_BASE (0xfffee300) 261#define OMAP1610_DMA_LCD_BASE (0xfffee300)
119#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0) 262#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0)
120#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2) 263#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2)
121#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4) 264#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4)
122#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8) 265#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8)
@@ -134,37 +277,18 @@
134#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea) 277#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea)
135#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4) 278#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4)
136 279
137 280#define OMAP_DMA_TOUT_IRQ (1 << 0) /* Only on omap1 */
138/* Every LCh has its own set of the registers below */
139#define OMAP_DMA_CSDP(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x00)
140#define OMAP_DMA_CCR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x02)
141#define OMAP_DMA_CICR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x04)
142#define OMAP_DMA_CSR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x06)
143#define OMAP_DMA_CSSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x08)
144#define OMAP_DMA_CSSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
145#define OMAP_DMA_CDSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
146#define OMAP_DMA_CDSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
147#define OMAP_DMA_CEN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x10)
148#define OMAP_DMA_CFN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x12)
149#define OMAP_DMA_CSFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x14)
150#define OMAP_DMA_CSEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x16)
151#define OMAP_DMA_CSAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x18)
152#define OMAP_DMA_CDAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
153#define OMAP_DMA_CDEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
154#define OMAP_DMA_CDFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
155#define OMAP_DMA_COLOR_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x20)
156#define OMAP_DMA_COLOR_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x22)
157#define OMAP_DMA_CCR2(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x24)
158#define OMAP_DMA_CLNK_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x28)
159#define OMAP_DMA_LCH_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
160
161#define OMAP_DMA_TOUT_IRQ (1 << 0)
162#define OMAP_DMA_DROP_IRQ (1 << 1) 281#define OMAP_DMA_DROP_IRQ (1 << 1)
163#define OMAP_DMA_HALF_IRQ (1 << 2) 282#define OMAP_DMA_HALF_IRQ (1 << 2)
164#define OMAP_DMA_FRAME_IRQ (1 << 3) 283#define OMAP_DMA_FRAME_IRQ (1 << 3)
165#define OMAP_DMA_LAST_IRQ (1 << 4) 284#define OMAP_DMA_LAST_IRQ (1 << 4)
166#define OMAP_DMA_BLOCK_IRQ (1 << 5) 285#define OMAP_DMA_BLOCK_IRQ (1 << 5)
167#define OMAP_DMA_SYNC_IRQ (1 << 6) 286#define OMAP1_DMA_SYNC_IRQ (1 << 6)
287#define OMAP2_DMA_PKT_IRQ (1 << 7)
288#define OMAP2_DMA_TRANS_ERR_IRQ (1 << 8)
289#define OMAP2_DMA_SECURE_ERR_IRQ (1 << 9)
290#define OMAP2_DMA_SUPERVISOR_ERR_IRQ (1 << 10)
291#define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11)
168 292
169#define OMAP_DMA_DATA_TYPE_S8 0x00 293#define OMAP_DMA_DATA_TYPE_S8 0x00
170#define OMAP_DMA_DATA_TYPE_S16 0x01 294#define OMAP_DMA_DATA_TYPE_S16 0x01
@@ -194,6 +318,7 @@ enum {
194 OMAP_LCD_DMA_B2_BOTTOM 318 OMAP_LCD_DMA_B2_BOTTOM
195}; 319};
196 320
321/* REVISIT: Check if BURST_4 is really 1 (or 2) */
197enum omap_dma_burst_mode { 322enum omap_dma_burst_mode {
198 OMAP_DMA_DATA_BURST_DIS = 0, 323 OMAP_DMA_DATA_BURST_DIS = 0,
199 OMAP_DMA_DATA_BURST_4, 324 OMAP_DMA_DATA_BURST_4,
@@ -206,6 +331,31 @@ enum omap_dma_color_mode {
206 OMAP_DMA_TRANSPARENT_COPY 331 OMAP_DMA_TRANSPARENT_COPY
207}; 332};
208 333
334struct omap_dma_channel_params {
335 int data_type; /* data type 8,16,32 */
336 int elem_count; /* number of elements in a frame */
337 int frame_count; /* number of frames in a element */
338
339 int src_port; /* Only on OMAP1 REVISIT: Is this needed? */
340 int src_amode; /* constant , post increment, indexed , double indexed */
341 int src_start; /* source address : physical */
342 int src_ei; /* source element index */
343 int src_fi; /* source frame index */
344
345 int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */
346 int dst_amode; /* constant , post increment, indexed , double indexed */
347 int dst_start; /* source address : physical */
348 int dst_ei; /* source element index */
349 int dst_fi; /* source frame index */
350
351 int trigger; /* trigger attached if the channel is synchronized */
352 int sync_mode; /* sycn on element, frame , block or packet */
353 int src_or_dst_synch; /* source synch(1) or destination synch(0) */
354
355 int ie; /* interrupt enabled */
356};
357
358
209extern void omap_set_dma_priority(int dst_port, int priority); 359extern void omap_set_dma_priority(int dst_port, int priority);
210extern int omap_request_dma(int dev_id, const char *dev_name, 360extern int omap_request_dma(int dev_id, const char *dev_name,
211 void (* callback)(int lch, u16 ch_status, void *data), 361 void (* callback)(int lch, u16 ch_status, void *data),
@@ -217,24 +367,30 @@ extern void omap_start_dma(int lch);
217extern void omap_stop_dma(int lch); 367extern void omap_stop_dma(int lch);
218extern void omap_set_dma_transfer_params(int lch, int data_type, 368extern void omap_set_dma_transfer_params(int lch, int data_type,
219 int elem_count, int frame_count, 369 int elem_count, int frame_count,
220 int sync_mode); 370 int sync_mode,
371 int dma_trigger, int src_or_dst_synch);
221extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, 372extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
222 u32 color); 373 u32 color);
223 374
224extern void omap_set_dma_src_params(int lch, int src_port, int src_amode, 375extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
225 unsigned long src_start); 376 unsigned long src_start,
377 int src_ei, int src_fi);
226extern void omap_set_dma_src_index(int lch, int eidx, int fidx); 378extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
227extern void omap_set_dma_src_data_pack(int lch, int enable); 379extern void omap_set_dma_src_data_pack(int lch, int enable);
228extern void omap_set_dma_src_burst_mode(int lch, 380extern void omap_set_dma_src_burst_mode(int lch,
229 enum omap_dma_burst_mode burst_mode); 381 enum omap_dma_burst_mode burst_mode);
230 382
231extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, 383extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
232 unsigned long dest_start); 384 unsigned long dest_start,
385 int dst_ei, int dst_fi);
233extern void omap_set_dma_dest_index(int lch, int eidx, int fidx); 386extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
234extern void omap_set_dma_dest_data_pack(int lch, int enable); 387extern void omap_set_dma_dest_data_pack(int lch, int enable);
235extern void omap_set_dma_dest_burst_mode(int lch, 388extern void omap_set_dma_dest_burst_mode(int lch,
236 enum omap_dma_burst_mode burst_mode); 389 enum omap_dma_burst_mode burst_mode);
237 390
391extern void omap_set_dma_params(int lch,
392 struct omap_dma_channel_params * params);
393
238extern void omap_dma_link_lch (int lch_head, int lch_queue); 394extern void omap_dma_link_lch (int lch_head, int lch_queue);
239extern void omap_dma_unlink_lch (int lch_head, int lch_queue); 395extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
240 396
@@ -244,9 +400,6 @@ extern int omap_get_dma_src_addr_counter(int lch);
244extern void omap_clear_dma(int lch); 400extern void omap_clear_dma(int lch);
245extern int omap_dma_running(void); 401extern int omap_dma_running(void);
246 402
247/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
248extern int omap_dma_in_1510_mode(void);
249
250/* LCD DMA functions */ 403/* LCD DMA functions */
251extern int omap_request_lcd_dma(void (* callback)(u16 status, void *data), 404extern int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
252 void *data); 405 void *data);
diff --git a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S
index 0d29b9c56a95..f8814a84910e 100644
--- a/include/asm-arm/arch-omap/entry-macro.S
+++ b/include/asm-arm/arch-omap/entry-macro.S
@@ -10,6 +10,20 @@
10 10
11#if defined(CONFIG_ARCH_OMAP1) 11#if defined(CONFIG_ARCH_OMAP1)
12 12
13#if defined(CONFIG_ARCH_OMAP730) && \
14 (defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
15#error "FIXME: OMAP730 doesn't support multiple-OMAP"
16#elif defined(CONFIG_ARCH_OMAP730)
17#define INT_IH2_IRQ INT_730_IH2_IRQ
18#elif defined(CONFIG_ARCH_OMAP15XX)
19#define INT_IH2_IRQ INT_1510_IH2_IRQ
20#elif defined(CONFIG_ARCH_OMAP16XX)
21#define INT_IH2_IRQ INT_1610_IH2_IRQ
22#else
23#warning "IH2 IRQ defaulted"
24#define INT_IH2_IRQ INT_1510_IH2_IRQ
25#endif
26
13 .macro disable_fiq 27 .macro disable_fiq
14 .endm 28 .endm
15 29
diff --git a/include/asm-arm/arch-omap/fpga.h b/include/asm-arm/arch-omap/fpga.h
index 676807dc50e1..6a883e0bdbb8 100644
--- a/include/asm-arm/arch-omap/fpga.h
+++ b/include/asm-arm/arch-omap/fpga.h
@@ -19,7 +19,7 @@
19#ifndef __ASM_ARCH_OMAP_FPGA_H 19#ifndef __ASM_ARCH_OMAP_FPGA_H
20#define __ASM_ARCH_OMAP_FPGA_H 20#define __ASM_ARCH_OMAP_FPGA_H
21 21
22#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP1510) 22#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
23extern void omap1510_fpga_init_irq(void); 23extern void omap1510_fpga_init_irq(void);
24#else 24#else
25#define omap1510_fpga_init_irq() (0) 25#define omap1510_fpga_init_irq() (0)
@@ -77,6 +77,8 @@ struct h2p2_dbg_fpga {
77#define H2P2_DBG_FPGA_LOAD_METER_SIZE 11 77#define H2P2_DBG_FPGA_LOAD_METER_SIZE 11
78#define H2P2_DBG_FPGA_LOAD_METER_MASK ((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1) 78#define H2P2_DBG_FPGA_LOAD_METER_MASK ((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1)
79 79
80#define H2P2_DBG_FPGA_P2_LED_TIMER (1 << 0)
81#define H2P2_DBG_FPGA_P2_LED_IDLE (1 << 1)
80 82
81/* 83/*
82 * --------------------------------------------------------------------------- 84 * ---------------------------------------------------------------------------
diff --git a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h
index 74cb2b93b700..1b3885741ac1 100644
--- a/include/asm-arm/arch-omap/gpio.h
+++ b/include/asm-arm/arch-omap/gpio.h
@@ -67,7 +67,7 @@
67 67
68#define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ? \ 68#define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ? \
69 IH_MPUIO_BASE + ((nr) & 0x0f) : \ 69 IH_MPUIO_BASE + ((nr) & 0x0f) : \
70 IH_GPIO_BASE + ((nr) & 0x3f)) 70 IH_GPIO_BASE + (nr))
71 71
72extern int omap_gpio_init(void); /* Call from board init only */ 72extern int omap_gpio_init(void); /* Call from board init only */
73extern int omap_request_gpio(int gpio); 73extern int omap_request_gpio(int gpio);
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 60201e1dd6ad..5406b875c422 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -267,8 +267,6 @@
267#define OMAP_LPG2_LCR (OMAP_LPG2_BASE + 0x00) 267#define OMAP_LPG2_LCR (OMAP_LPG2_BASE + 0x00)
268#define OMAP_LPG2_PMR (OMAP_LPG2_BASE + 0x04) 268#define OMAP_LPG2_PMR (OMAP_LPG2_BASE + 0x04)
269 269
270#ifndef __ASSEMBLER__
271
272/* 270/*
273 * --------------------------------------------------------------------------- 271 * ---------------------------------------------------------------------------
274 * Processor specific defines 272 * Processor specific defines
@@ -277,13 +275,11 @@
277 275
278#include "omap730.h" 276#include "omap730.h"
279#include "omap1510.h" 277#include "omap1510.h"
280
281#ifdef CONFIG_ARCH_OMAP24XX
282#include "omap24xx.h" 278#include "omap24xx.h"
283#endif
284
285#include "omap16xx.h" 279#include "omap16xx.h"
286 280
281#ifndef __ASSEMBLER__
282
287/* 283/*
288 * --------------------------------------------------------------------------- 284 * ---------------------------------------------------------------------------
289 * Board specific defines 285 * Board specific defines
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index 3d5bcd545082..f5bcc9a1aed6 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -52,23 +52,33 @@
52 * ---------------------------------------------------------------------------- 52 * ----------------------------------------------------------------------------
53 */ 53 */
54 54
55#define PCIO_BASE 0
56
55#if defined(CONFIG_ARCH_OMAP1) 57#if defined(CONFIG_ARCH_OMAP1)
58
56#define IO_PHYS 0xFFFB0000 59#define IO_PHYS 0xFFFB0000
57#define IO_OFFSET -0x01000000 /* Virtual IO = 0xfefb0000 */ 60#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
58#define IO_SIZE 0x40000 61#define IO_SIZE 0x40000
62#define IO_VIRT (IO_PHYS - IO_OFFSET)
63#define IO_ADDRESS(pa) ((pa) - IO_OFFSET)
64#define io_p2v(pa) ((pa) - IO_OFFSET)
65#define io_v2p(va) ((va) + IO_OFFSET)
59 66
60#elif defined(CONFIG_ARCH_OMAP2) 67#elif defined(CONFIG_ARCH_OMAP2)
61#define IO_PHYS 0x48000000 /* L4 peripherals; other stuff has to be mapped *
62 * manually. */
63#define IO_OFFSET 0x90000000 /* Virtual IO = 0xd8000000 */
64#define IO_SIZE 0x08000000
65#endif
66 68
67#define IO_VIRT (IO_PHYS + IO_OFFSET) 69/* We map both L3 and L4 on OMAP2 */
68#define IO_ADDRESS(x) ((x) + IO_OFFSET) 70#define L3_24XX_PHYS L3_24XX_BASE /* 0x68000000 */
69#define PCIO_BASE 0 71#define L3_24XX_VIRT 0xf8000000
70#define io_p2v(x) ((x) + IO_OFFSET) 72#define L3_24XX_SIZE SZ_1M /* 44kB of 128MB used, want 1MB sect */
71#define io_v2p(x) ((x) - IO_OFFSET) 73#define L4_24XX_PHYS L4_24XX_BASE /* 0x48000000 */
74#define L4_24XX_VIRT 0xd8000000
75#define L4_24XX_SIZE SZ_1M /* 1MB of 128MB used, want 1MB sect */
76#define IO_OFFSET 0x90000000
77#define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
78#define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
79#define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */
80
81#endif
72 82
73#ifndef __ASSEMBLER__ 83#ifndef __ASSEMBLER__
74 84
diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
index 74e108ccac16..9779686bdceb 100644
--- a/include/asm-arm/arch-omap/irqs.h
+++ b/include/asm-arm/arch-omap/irqs.h
@@ -22,8 +22,8 @@
22 * are different. 22 * are different.
23 */ 23 */
24 24
25#ifndef __ASM_ARCH_OMAP1510_IRQS_H 25#ifndef __ASM_ARCH_OMAP15XX_IRQS_H
26#define __ASM_ARCH_OMAP1510_IRQS_H 26#define __ASM_ARCH_OMAP15XX_IRQS_H
27 27
28/* 28/*
29 * IRQ numbers for interrupt handler 1 29 * IRQ numbers for interrupt handler 1
@@ -31,7 +31,6 @@
31 * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below 31 * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
32 * 32 *
33 */ 33 */
34#define INT_IH2_IRQ 0
35#define INT_CAMERA 1 34#define INT_CAMERA 1
36#define INT_FIQ 3 35#define INT_FIQ 3
37#define INT_RTDX 6 36#define INT_RTDX 6
@@ -60,6 +59,7 @@
60/* 59/*
61 * OMAP-1510 specific IRQ numbers for interrupt handler 1 60 * OMAP-1510 specific IRQ numbers for interrupt handler 1
62 */ 61 */
62#define INT_1510_IH2_IRQ 0
63#define INT_1510_RES2 2 63#define INT_1510_RES2 2
64#define INT_1510_SPI_TX 4 64#define INT_1510_SPI_TX 4
65#define INT_1510_SPI_RX 5 65#define INT_1510_SPI_RX 5
@@ -71,6 +71,7 @@
71/* 71/*
72 * OMAP-1610 specific IRQ numbers for interrupt handler 1 72 * OMAP-1610 specific IRQ numbers for interrupt handler 1
73 */ 73 */
74#define INT_1610_IH2_IRQ 0
74#define INT_1610_IH2_FIQ 2 75#define INT_1610_IH2_FIQ 2
75#define INT_1610_McBSP2_TX 4 76#define INT_1610_McBSP2_TX 4
76#define INT_1610_McBSP2_RX 5 77#define INT_1610_McBSP2_RX 5
@@ -231,6 +232,12 @@
231#define INT_730_DMA_CH15 (62 + IH2_BASE) 232#define INT_730_DMA_CH15 (62 + IH2_BASE)
232#define INT_730_NAND (63 + IH2_BASE) 233#define INT_730_NAND (63 + IH2_BASE)
233 234
235#define INT_24XX_SYS_NIRQ 7
236#define INT_24XX_SDMA_IRQ0 12
237#define INT_24XX_SDMA_IRQ1 13
238#define INT_24XX_SDMA_IRQ2 14
239#define INT_24XX_SDMA_IRQ3 15
240#define INT_24XX_DSS_IRQ 25
234#define INT_24XX_GPIO_BANK1 29 241#define INT_24XX_GPIO_BANK1 29
235#define INT_24XX_GPIO_BANK2 30 242#define INT_24XX_GPIO_BANK2 30
236#define INT_24XX_GPIO_BANK3 31 243#define INT_24XX_GPIO_BANK3 31
diff --git a/include/asm-arm/arch-omap/memory.h b/include/asm-arm/arch-omap/memory.h
index bf545b6e0a26..df50dd53e1dd 100644
--- a/include/asm-arm/arch-omap/memory.h
+++ b/include/asm-arm/arch-omap/memory.h
@@ -61,7 +61,7 @@
61 * Note that the is_lbus_device() test is not very efficient on 1510 61 * Note that the is_lbus_device() test is not very efficient on 1510
62 * because of the strncmp(). 62 * because of the strncmp().
63 */ 63 */
64#ifdef CONFIG_ARCH_OMAP1510 64#ifdef CONFIG_ARCH_OMAP15XX
65 65
66/* 66/*
67 * OMAP-1510 Local Bus address offset 67 * OMAP-1510 Local Bus address offset
@@ -84,7 +84,7 @@
84 virt_to_lbus(addr) : \ 84 virt_to_lbus(addr) : \
85 __virt_to_bus(addr);}) 85 __virt_to_bus(addr);})
86 86
87#endif /* CONFIG_ARCH_OMAP1510 */ 87#endif /* CONFIG_ARCH_OMAP15XX */
88 88
89#endif 89#endif
90 90
diff --git a/include/asm-arm/arch-omap/menelaus.h b/include/asm-arm/arch-omap/menelaus.h
new file mode 100644
index 000000000000..46be8b8d6346
--- /dev/null
+++ b/include/asm-arm/arch-omap/menelaus.h
@@ -0,0 +1,22 @@
1/*
2 * linux/include/asm-arm/arch-omap/menelaus.h
3 *
4 * Functions to access Menelaus power management chip
5 */
6
7#ifndef __ASM_ARCH_MENELAUS_H
8#define __ASM_ARCH_MENELAUS_H
9
10extern void menelaus_mmc_register(void (*callback)(u8 card_mask),
11 unsigned long data);
12extern void menelaus_mmc_remove(void);
13extern void menelaus_mmc_opendrain(int enable);
14
15#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
16#define omap_has_menelaus() 1
17#else
18#define omap_has_menelaus() 0
19#endif
20
21#endif
22
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index 1b1ad4105349..13415a9aab06 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -4,7 +4,7 @@
4 * Table of the Omap register configurations for the FUNC_MUX and 4 * Table of the Omap register configurations for the FUNC_MUX and
5 * PULL_DWN combinations. 5 * PULL_DWN combinations.
6 * 6 *
7 * Copyright (C) 2003 Nokia Corporation 7 * Copyright (C) 2003 - 2005 Nokia Corporation
8 * 8 *
9 * Written by Tony Lindgren <tony.lindgren@nokia.com> 9 * Written by Tony Lindgren <tony.lindgren@nokia.com>
10 * 10 *
@@ -58,6 +58,16 @@
58 .pu_pd_reg = PU_PD_SEL_##reg, \ 58 .pu_pd_reg = PU_PD_SEL_##reg, \
59 .pu_pd_val = status, 59 .pu_pd_val = status,
60 60
61#define MUX_REG_730(reg, mode_offset, mode) .mux_reg_name = "OMAP730_IO_CONF_"#reg, \
62 .mux_reg = OMAP730_IO_CONF_##reg, \
63 .mask_offset = mode_offset, \
64 .mask = mode,
65
66#define PULL_REG_730(reg, bit, status) .pull_name = "OMAP730_IO_CONF_"#reg, \
67 .pull_reg = OMAP730_IO_CONF_##reg, \
68 .pull_bit = bit, \
69 .pull_val = status,
70
61#else 71#else
62 72
63#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \ 73#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \
@@ -71,6 +81,15 @@
71#define PU_PD_REG(reg, status) .pu_pd_reg = PU_PD_SEL_##reg, \ 81#define PU_PD_REG(reg, status) .pu_pd_reg = PU_PD_SEL_##reg, \
72 .pu_pd_val = status, 82 .pu_pd_val = status,
73 83
84#define MUX_REG_730(reg, mode_offset, mode) \
85 .mux_reg = OMAP730_IO_CONF_##reg, \
86 .mask_offset = mode_offset, \
87 .mask = mode,
88
89#define PULL_REG_730(reg, bit, status) .pull_reg = OMAP730_IO_CONF_##reg, \
90 .pull_bit = bit, \
91 .pull_val = status,
92
74#endif /* CONFIG_OMAP_MUX_DEBUG */ 93#endif /* CONFIG_OMAP_MUX_DEBUG */
75 94
76#define MUX_CFG(desc, mux_reg, mode_offset, mode, \ 95#define MUX_CFG(desc, mux_reg, mode_offset, mode, \
@@ -84,13 +103,44 @@
84 PU_PD_REG(pu_pd_reg, pu_pd_status) \ 103 PU_PD_REG(pu_pd_reg, pu_pd_status) \
85}, 104},
86 105
106
107/*
108 * OMAP730 has a slightly different config for the pin mux.
109 * - config regs are the OMAP730_IO_CONF_x regs (see omap730.h) regs and
110 * not the FUNC_MUX_CTRL_x regs from hardware.h
111 * - for pull-up/down, only has one enable bit which is is in the same register
112 * as mux config
113 */
114#define MUX_CFG_730(desc, mux_reg, mode_offset, mode, \
115 pull_reg, pull_bit, pull_status, \
116 pu_pd_reg, pu_pd_status, debug_status)\
117{ \
118 .name = desc, \
119 .debug = debug_status, \
120 MUX_REG_730(mux_reg, mode_offset, mode) \
121 PULL_REG_730(mux_reg, pull_bit, pull_status) \
122 PU_PD_REG(pu_pd_reg, pu_pd_status) \
123},
124
125#define MUX_CFG_24XX(desc, reg_offset, mode, \
126 pull_en, pull_mode, dbg) \
127{ \
128 .name = desc, \
129 .debug = dbg, \
130 .mux_reg = reg_offset, \
131 .mask = mode, \
132 .pull_val = pull_en, \
133 .pu_pd_val = pull_mode, \
134},
135
136
87#define PULL_DISABLED 0 137#define PULL_DISABLED 0
88#define PULL_ENABLED 1 138#define PULL_ENABLED 1
89 139
90#define PULL_DOWN 0 140#define PULL_DOWN 0
91#define PULL_UP 1 141#define PULL_UP 1
92 142
93typedef struct { 143struct pin_config {
94 char *name; 144 char *name;
95 unsigned char busy; 145 unsigned char busy;
96 unsigned char debug; 146 unsigned char debug;
@@ -108,13 +158,23 @@ typedef struct {
108 const char *pu_pd_name; 158 const char *pu_pd_name;
109 const unsigned int pu_pd_reg; 159 const unsigned int pu_pd_reg;
110 const unsigned char pu_pd_val; 160 const unsigned char pu_pd_val;
111} reg_cfg_set; 161};
112 162
113/* 163enum omap730_index {
114 * Lookup table for FUNC_MUX and PULL_DWN register combinations for each 164 /* OMAP 730 keyboard */
115 * device. See also reg_cfg_table below for the register values. 165 E2_730_KBR0,
116 */ 166 J7_730_KBR1,
117typedef enum { 167 E1_730_KBR2,
168 F3_730_KBR3,
169 D2_730_KBR4,
170 C2_730_KBC0,
171 D3_730_KBC1,
172 E4_730_KBC2,
173 F4_730_KBC3,
174 E3_730_KBC4,
175};
176
177enum omap1xxx_index {
118 /* UART1 (BT_UART_GATING)*/ 178 /* UART1 (BT_UART_GATING)*/
119 UART1_TX = 0, 179 UART1_TX = 0,
120 UART1_RTS, 180 UART1_RTS,
@@ -331,245 +391,34 @@ typedef enum {
331 V10_1610_CF_IREQ, 391 V10_1610_CF_IREQ,
332 W10_1610_CF_RESET, 392 W10_1610_CF_RESET,
333 W11_1610_CF_CD1, 393 W11_1610_CF_CD1,
334} reg_cfg_t; 394};
335 395
336#if defined(__MUX_C__) && defined(CONFIG_OMAP_MUX) 396enum omap24xx_index {
397 /* 24xx I2C */
398 M19_24XX_I2C1_SCL,
399 L15_24XX_I2C1_SDA,
400 J15_24XX_I2C2_SCL,
401 H19_24XX_I2C2_SDA,
337 402
338/* 403 /* 24xx Menelaus interrupt */
339 * Table of various FUNC_MUX and PULL_DWN combinations for each device. 404 W19_24XX_SYS_NIRQ,
340 * See also reg_cfg_t above for the lookup table.
341 */
342static const reg_cfg_set __initdata_or_module
343reg_cfg_table[] = {
344/*
345 * description mux mode mux pull pull pull pu_pd pu dbg
346 * reg offset mode reg bit ena reg
347 */
348MUX_CFG("UART1_TX", 9, 21, 1, 2, 3, 0, NA, 0, 0)
349MUX_CFG("UART1_RTS", 9, 12, 1, 2, 0, 0, NA, 0, 0)
350
351/* UART2 (COM_UART_GATING), conflicts with USB2 */
352MUX_CFG("UART2_TX", C, 27, 1, 3, 3, 0, NA, 0, 0)
353MUX_CFG("UART2_RX", C, 18, 0, 3, 1, 1, NA, 0, 0)
354MUX_CFG("UART2_CTS", C, 21, 0, 3, 1, 1, NA, 0, 0)
355MUX_CFG("UART2_RTS", C, 24, 1, 3, 2, 0, NA, 0, 0)
356
357/* UART3 (GIGA_UART_GATING) */
358MUX_CFG("UART3_TX", 6, 0, 1, 0, 30, 0, NA, 0, 0)
359MUX_CFG("UART3_RX", 6, 3, 0, 0, 31, 1, NA, 0, 0)
360MUX_CFG("UART3_CTS", 5, 12, 2, 0, 24, 0, NA, 0, 0)
361MUX_CFG("UART3_RTS", 5, 15, 2, 0, 25, 0, NA, 0, 0)
362MUX_CFG("UART3_CLKREQ", 9, 27, 0, 2, 5, 0, NA, 0, 0)
363MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
364MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
365
366/* PWT & PWL, conflicts with UART3 */
367MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
368MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
369
370/* USB internal master generic */
371MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
372MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1)
373/* works around erratum: W4_USB_PUEN and W4_USB_PUDIS are switched! */
374MUX_CFG("W4_USB_PUEN", D, 3, 3, 3, 5, 1, NA, 0, 1)
375MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1)
376MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1)
377MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1)
378
379/* USB1 master */
380MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1)
381MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1)
382MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1)
383MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1)
384MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1)
385MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1)
386MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1)
387MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1)
388MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1)
389MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1)
390MUX_CFG("R13_1710_USB1_SEO", A, 12, 5, 2, 10, 0, NA, 0, 1)
391
392/* USB2 master */
393MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1)
394MUX_CFG("USB2_VP", B, 6, 1, 2, 18, 0, NA, 0, 1)
395MUX_CFG("USB2_TXEN", B, 9, 1, 2, 19, 0, NA, 0, 1)
396MUX_CFG("USB2_VM", C, 18, 1, 3, 0, 0, NA, 0, 1)
397MUX_CFG("USB2_RCV", C, 21, 1, 3, 1, 0, NA, 0, 1)
398MUX_CFG("USB2_SE0", C, 24, 2, 3, 2, 0, NA, 0, 1)
399MUX_CFG("USB2_TXD", C, 27, 2, 3, 3, 0, NA, 0, 1)
400
401/* OMAP-1510 GPIO */
402MUX_CFG("R18_1510_GPIO0", 7, 9, 0, 1, 11, 1, 0, 0, 1)
403MUX_CFG("R19_1510_GPIO1", 7, 6, 0, 1, 10, 1, 0, 0, 1)
404MUX_CFG("M14_1510_GPIO2", 7, 3, 0, 1, 9, 1, 0, 0, 1)
405
406/* OMAP1610 GPIO */
407MUX_CFG("P18_1610_GPIO3", 7, 0, 0, 1, 8, 0, NA, 0, 1)
408MUX_CFG("Y15_1610_GPIO17", A, 0, 7, 2, 6, 0, NA, 0, 1)
409
410/* OMAP-1710 GPIO */
411MUX_CFG("R18_1710_GPIO0", 7, 9, 0, 1, 11, 1, 1, 1, 1)
412MUX_CFG("V2_1710_GPIO10", F, 27, 1, 4, 3, 1, 4, 1, 1)
413MUX_CFG("N21_1710_GPIO14", 6, 9, 0, 1, 1, 1, 1, 1, 1)
414MUX_CFG("W15_1710_GPIO40", 9, 27, 7, 2, 5, 1, 2, 1, 1)
415
416/* MPUIO */
417MUX_CFG("MPUIO2", 7, 18, 0, 1, 14, 1, NA, 0, 1)
418MUX_CFG("N15_1610_MPUIO2", 7, 18, 0, 1, 14, 1, 1, 0, 1)
419MUX_CFG("MPUIO4", 7, 15, 0, 1, 13, 1, NA, 0, 1)
420MUX_CFG("MPUIO5", 7, 12, 0, 1, 12, 1, NA, 0, 1)
421
422MUX_CFG("T20_1610_MPUIO5", 7, 12, 0, 1, 12, 0, 3, 0, 1)
423MUX_CFG("W11_1610_MPUIO6", 10, 15, 2, 3, 8, 0, 3, 0, 1)
424MUX_CFG("V10_1610_MPUIO7", A, 24, 2, 2, 14, 0, 2, 0, 1)
425MUX_CFG("W11_1610_MPUIO9", 10, 15, 1, 3, 8, 0, 3, 0, 1)
426MUX_CFG("V10_1610_MPUIO10", A, 24, 1, 2, 14, 0, 2, 0, 1)
427MUX_CFG("W10_1610_MPUIO11", A, 18, 2, 2, 11, 0, 2, 0, 1)
428MUX_CFG("E20_1610_MPUIO13", 3, 21, 1, 0, 7, 0, 0, 0, 1)
429MUX_CFG("U20_1610_MPUIO14", 9, 6, 6, 0, 30, 0, 0, 0, 1)
430MUX_CFG("E19_1610_MPUIO15", 3, 18, 1, 0, 6, 0, 0, 0, 1)
431
432/* MCBSP2 */
433MUX_CFG("MCBSP2_CLKR", C, 6, 0, 2, 27, 1, NA, 0, 1)
434MUX_CFG("MCBSP2_CLKX", C, 9, 0, 2, 29, 1, NA, 0, 1)
435MUX_CFG("MCBSP2_DR", C, 0, 0, 2, 26, 1, NA, 0, 1)
436MUX_CFG("MCBSP2_DX", C, 15, 0, 2, 31, 1, NA, 0, 1)
437MUX_CFG("MCBSP2_FSR", C, 12, 0, 2, 30, 1, NA, 0, 1)
438MUX_CFG("MCBSP2_FSX", C, 3, 0, 2, 27, 1, NA, 0, 1)
439
440/* MCBSP3 NOTE: Mode must 1 for clock */
441MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
442
443/* Misc ballouts */
444MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
445MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
446
447/* OMAP-1610 MMC2 */
448MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
449MUX_CFG("V8_1610_MMC2_DAT1", B, 27, 6, 2, 25, 1, 2, 1, 1)
450MUX_CFG("W15_1610_MMC2_DAT2", 9, 12, 6, 2, 5, 1, 2, 1, 1)
451MUX_CFG("R10_1610_MMC2_DAT3", B, 18, 6, 2, 22, 1, 2, 1, 1)
452MUX_CFG("Y10_1610_MMC2_CLK", B, 3, 6, 2, 17, 0, 2, 0, 1)
453MUX_CFG("Y8_1610_MMC2_CMD", B, 24, 6, 2, 24, 1, 2, 1, 1)
454MUX_CFG("V9_1610_MMC2_CMDDIR", B, 12, 6, 2, 20, 0, 2, 1, 1)
455MUX_CFG("V5_1610_MMC2_DATDIR0", B, 15, 6, 2, 21, 0, 2, 1, 1)
456MUX_CFG("W19_1610_MMC2_DATDIR1", 8, 15, 6, 1, 23, 0, 1, 1, 1)
457MUX_CFG("R18_1610_MMC2_CLKIN", 7, 9, 6, 1, 11, 0, 1, 11, 1)
458
459/* OMAP-1610 External Trace Interface */
460MUX_CFG("M19_1610_ETM_PSTAT0", 5, 27, 1, 0, 29, 0, 0, 0, 1)
461MUX_CFG("L15_1610_ETM_PSTAT1", 5, 24, 1, 0, 28, 0, 0, 0, 1)
462MUX_CFG("L18_1610_ETM_PSTAT2", 5, 21, 1, 0, 27, 0, 0, 0, 1)
463MUX_CFG("L19_1610_ETM_D0", 5, 18, 1, 0, 26, 0, 0, 0, 1)
464MUX_CFG("J19_1610_ETM_D6", 5, 0, 1, 0, 20, 0, 0, 0, 1)
465MUX_CFG("J18_1610_ETM_D7", 5, 27, 1, 0, 19, 0, 0, 0, 1)
466
467/* OMAP16XX GPIO */
468MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1)
469MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1)
470MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1)
471MUX_CFG("N20_1610_GPIO11", 6, 18, 0, 1, 4, 0, 1, 1, 1)
472MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1)
473MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1)
474MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1)
475MUX_CFG("AA20_1610_GPIO_41", 9, 9, 7, 1, 31, 0, 1, 1, 1)
476MUX_CFG("W19_1610_GPIO48", 8, 15, 7, 1, 23, 1, 1, 0, 1)
477MUX_CFG("M7_1610_GPIO62", 10, 0, 0, 4, 24, 0, 4, 0, 1)
478MUX_CFG("V14_16XX_GPIO37", 9, 18, 7, 2, 2, 0, 2, 2, 0)
479MUX_CFG("R9_16XX_GPIO18", C, 18, 7, 3, 0, 0, 3, 0, 0)
480MUX_CFG("L14_16XX_GPIO49", 6, 3, 7, 0, 31, 0, 0, 31, 0)
481
482/* OMAP-1610 uWire */
483MUX_CFG("V19_1610_UWIRE_SCLK", 8, 6, 0, 1, 20, 0, 1, 1, 1)
484MUX_CFG("U18_1610_UWIRE_SDI", 8, 0, 0, 1, 18, 0, 1, 1, 1)
485MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1)
486MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
487MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
488MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
489
490/* OMAP-1610 Flash */
491MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
492MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
493
494/* First MMC interface, same on 1510, 1610 and 1710 */
495MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1)
496MUX_CFG("MMC_DAT1", A, 24, 0, 2, 14, 1, 2, 1, 1)
497MUX_CFG("MMC_DAT2", A, 18, 0, 2, 12, 1, 2, 1, 1)
498MUX_CFG("MMC_DAT0", B, 0, 0, 2, 16, 1, 2, 1, 1)
499MUX_CFG("MMC_CLK", A, 21, 0, NA, 0, 0, NA, 0, 1)
500MUX_CFG("MMC_DAT3", 10, 15, 0, 3, 8, 1, 3, 1, 1)
501MUX_CFG("M15_1710_MMC_CLKI", 6, 21, 2, 0, 0, 0, NA, 0, 1)
502MUX_CFG("P19_1710_MMC_CMDDIR", 6, 24, 6, 0, 0, 0, NA, 0, 1)
503MUX_CFG("P20_1710_MMC_DATDIR0", 6, 27, 5, 0, 0, 0, NA, 0, 1)
504
505/* OMAP-1610 USB0 alternate configuration */
506MUX_CFG("W9_USB0_TXEN", B, 9, 5, 2, 19, 0, 2, 0, 1)
507MUX_CFG("AA9_USB0_VP", B, 6, 5, 2, 18, 0, 2, 0, 1)
508MUX_CFG("Y5_USB0_RCV", C, 21, 5, 3, 1, 0, 1, 0, 1)
509MUX_CFG("R9_USB0_VM", C, 18, 5, 3, 0, 0, 3, 0, 1)
510MUX_CFG("V6_USB0_TXD", C, 27, 5, 3, 3, 0, 3, 0, 1)
511MUX_CFG("W5_USB0_SE0", C, 24, 5, 3, 2, 0, 3, 0, 1)
512MUX_CFG("V9_USB0_SPEED", B, 12, 5, 2, 20, 0, 2, 0, 1)
513MUX_CFG("Y10_USB0_SUSP", B, 3, 5, 2, 17, 0, 2, 0, 1)
514
515/* USB2 interface */
516MUX_CFG("W9_USB2_TXEN", B, 9, 1, NA, 0, 0, NA, 0, 1)
517MUX_CFG("AA9_USB2_VP", B, 6, 1, NA, 0, 0, NA, 0, 1)
518MUX_CFG("Y5_USB2_RCV", C, 21, 1, NA, 0, 0, NA, 0, 1)
519MUX_CFG("R9_USB2_VM", C, 18, 1, NA, 0, 0, NA, 0, 1)
520MUX_CFG("V6_USB2_TXD", C, 27, 2, NA, 0, 0, NA, 0, 1)
521MUX_CFG("W5_USB2_SE0", C, 24, 2, NA, 0, 0, NA, 0, 1)
522
523/* 16XX UART */
524MUX_CFG("R13_1610_UART1_TX", A, 12, 6, 2, 10, 0, 2, 10, 1)
525MUX_CFG("V14_16XX_UART1_RX", 9, 18, 0, 2, 2, 0, 2, 2, 1)
526MUX_CFG("R14_1610_UART1_CTS", 9, 15, 0, 2, 1, 0, 2, 1, 1)
527MUX_CFG("AA15_1610_UART1_RTS", 9, 12, 1, 2, 0, 0, 2, 0, 1)
528MUX_CFG("R9_16XX_UART2_RX", C, 18, 0, 3, 0, 0, 3, 0, 1)
529MUX_CFG("L14_16XX_UART3_RX", 6, 3, 0, 0, 31, 0, 0, 31, 1)
530
531/* I2C interface */
532MUX_CFG("I2C_SCL", 7, 24, 0, NA, 0, 0, NA, 0, 0)
533MUX_CFG("I2C_SDA", 7, 27, 0, NA, 0, 0, NA, 0, 0)
534
535/* Keypad */
536MUX_CFG("F18_1610_KBC0", 3, 15, 0, 0, 5, 1, 0, 0, 0)
537MUX_CFG("D20_1610_KBC1", 3, 12, 0, 0, 4, 1, 0, 0, 0)
538MUX_CFG("D19_1610_KBC2", 3, 9, 0, 0, 3, 1, 0, 0, 0)
539MUX_CFG("E18_1610_KBC3", 3, 6, 0, 0, 2, 1, 0, 0, 0)
540MUX_CFG("C21_1610_KBC4", 3, 3, 0, 0, 1, 1, 0, 0, 0)
541MUX_CFG("G18_1610_KBR0", 4, 0, 0, 0, 10, 1, 0, 1, 0)
542MUX_CFG("F19_1610_KBR1", 3, 27, 0, 0, 9, 1, 0, 1, 0)
543MUX_CFG("H14_1610_KBR2", 3, 24, 0, 0, 8, 1, 0, 1, 0)
544MUX_CFG("E20_1610_KBR3", 3, 21, 0, 0, 7, 1, 0, 1, 0)
545MUX_CFG("E19_1610_KBR4", 3, 18, 0, 0, 6, 1, 0, 1, 0)
546MUX_CFG("N19_1610_KBR5", 6, 12, 1, 1, 2, 1, 1, 1, 0)
547
548/* Power management */
549MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0)
550
551/* MCLK Settings */
552MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0)
553MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0)
554MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0)
555MUX_CFG("R10_1610_MCLK_OFF", B, 18, 6, 2, 22, 1, 2, 1, 1)
556
557/* CompactFlash controller, conflicts with MMC1 */
558MUX_CFG("P11_1610_CF_CD2", A, 27, 3, 2, 15, 1, 2, 1, 1)
559MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1)
560MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1)
561MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1)
562MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1)
563};
564 405
565#endif /* __MUX_C__ */ 406 /* 24xx GPIO */
407 Y20_24XX_GPIO60,
408 M15_24XX_GPIO92,
409};
566 410
567#ifdef CONFIG_OMAP_MUX 411#ifdef CONFIG_OMAP_MUX
568/* setup pin muxing in Linux */ 412/* setup pin muxing in Linux */
569extern int omap_cfg_reg(reg_cfg_t reg_cfg); 413extern int omap1_mux_init(void);
414extern int omap2_mux_init(void);
415extern int omap_mux_register(struct pin_config * pins, unsigned long size);
416extern int omap_cfg_reg(unsigned long reg_cfg);
570#else 417#else
571/* boot loader does it all (no warnings from CONFIG_OMAP_MUX_WARNINGS) */ 418/* boot loader does it all (no warnings from CONFIG_OMAP_MUX_WARNINGS) */
572static inline int omap_cfg_reg(reg_cfg_t reg_cfg) { return 0; } 419static inline int omap1_mux_init(void) { return 0; }
420static inline int omap2_mux_init(void) { return 0; }
421static inline int omap_cfg_reg(unsigned long reg_cfg) { return 0; }
573#endif 422#endif
574 423
575#endif 424#endif
diff --git a/include/asm-arm/arch-omap/omap1510.h b/include/asm-arm/arch-omap/omap1510.h
index f086a3933906..c575d354850f 100644
--- a/include/asm-arm/arch-omap/omap1510.h
+++ b/include/asm-arm/arch-omap/omap1510.h
@@ -25,8 +25,8 @@
25 * 675 Mass Ave, Cambridge, MA 02139, USA. 25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */ 26 */
27 27
28#ifndef __ASM_ARCH_OMAP1510_H 28#ifndef __ASM_ARCH_OMAP15XX_H
29#define __ASM_ARCH_OMAP1510_H 29#define __ASM_ARCH_OMAP15XX_H
30 30
31/* 31/*
32 * ---------------------------------------------------------------------------- 32 * ----------------------------------------------------------------------------
@@ -44,5 +44,5 @@
44#define OMAP1510_DSPREG_SIZE SZ_128K 44#define OMAP1510_DSPREG_SIZE SZ_128K
45#define OMAP1510_DSPREG_START 0xE1000000 45#define OMAP1510_DSPREG_START 0xE1000000
46 46
47#endif /* __ASM_ARCH_OMAP1510_H */ 47#endif /* __ASM_ARCH_OMAP15XX_H */
48 48
diff --git a/include/asm-arm/arch-omap/omap24xx.h b/include/asm-arm/arch-omap/omap24xx.h
index a9105466a417..6e59805fa654 100644
--- a/include/asm-arm/arch-omap/omap24xx.h
+++ b/include/asm-arm/arch-omap/omap24xx.h
@@ -1,15 +1,24 @@
1#ifndef __ASM_ARCH_OMAP24XX_H 1#ifndef __ASM_ARCH_OMAP24XX_H
2#define __ASM_ARCH_OMAP24XX_H 2#define __ASM_ARCH_OMAP24XX_H
3 3
4#define OMAP24XX_L4_IO_BASE 0x48000000 4/*
5 * Please place only base defines here and put the rest in device
6 * specific headers. Note also that some of these defines are needed
7 * for omap1 to compile without adding ifdefs.
8 */
9
10#define L4_24XX_BASE 0x48000000
11#define L3_24XX_BASE 0x68000000
5 12
6/* interrupt controller */ 13/* interrupt controller */
7#define OMAP24XX_IC_BASE (OMAP24XX_L4_IO_BASE + 0xfe000) 14#define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000)
8#define VA_IC_BASE IO_ADDRESS(OMAP24XX_IC_BASE) 15#define VA_IC_BASE IO_ADDRESS(OMAP24XX_IC_BASE)
9
10#define OMAP24XX_IVA_INTC_BASE 0x40000000 16#define OMAP24XX_IVA_INTC_BASE 0x40000000
11
12#define IRQ_SIR_IRQ 0x0040 17#define IRQ_SIR_IRQ 0x0040
13 18
19#define OMAP24XX_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
20#define OMAP24XX_PRCM_BASE (L4_24XX_BASE + 0x8000)
21#define OMAP24XX_SDRC_BASE (L3_24XX_BASE + 0x9000)
22
14#endif /* __ASM_ARCH_OMAP24XX_H */ 23#endif /* __ASM_ARCH_OMAP24XX_H */
15 24
diff --git a/include/asm-arm/arch-omap/omapfb.h b/include/asm-arm/arch-omap/omapfb.h
new file mode 100644
index 000000000000..4ba2622cc142
--- /dev/null
+++ b/include/asm-arm/arch-omap/omapfb.h
@@ -0,0 +1,281 @@
1/*
2 * File: include/asm-arm/arch-omap/omapfb.h
3 *
4 * Framebuffer driver for TI OMAP boards
5 *
6 * Copyright (C) 2004 Nokia Corporation
7 * Author: Imre Deak <imre.deak@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#ifndef __OMAPFB_H
25#define __OMAPFB_H
26
27/* IOCTL commands. */
28
29#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
30#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
31#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
32#define OMAP_IO(num) _IO('O', num)
33
34#define OMAPFB_MIRROR OMAP_IOW(31, int)
35#define OMAPFB_SYNC_GFX OMAP_IO(37)
36#define OMAPFB_VSYNC OMAP_IO(38)
37#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, enum omapfb_update_mode)
38#define OMAPFB_GET_CAPS OMAP_IOR(42, unsigned long)
39#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, enum omapfb_update_mode)
40#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
41#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
42#define OMAPFB_UPDATE_WINDOW OMAP_IOW(47, struct omapfb_update_window)
43#define OMAPFB_SETUP_PLANE OMAP_IOW(48, struct omapfb_setup_plane)
44#define OMAPFB_ENABLE_PLANE OMAP_IOW(49, struct omapfb_enable_plane)
45#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
46
47#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
48#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
49#define OMAPFB_CAPS_PANEL_MASK 0xff000000
50
51#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
52#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
53
54/* Values from DSP must map to lower 16-bits */
55#define OMAPFB_FORMAT_MASK 0x00ff
56#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
57
58enum omapfb_color_format {
59 OMAPFB_COLOR_RGB565 = 0,
60 OMAPFB_COLOR_YUV422,
61 OMAPFB_COLOR_YUV420,
62 OMAPFB_COLOR_CLUT_8BPP,
63 OMAPFB_COLOR_CLUT_4BPP,
64 OMAPFB_COLOR_CLUT_2BPP,
65 OMAPFB_COLOR_CLUT_1BPP,
66};
67
68struct omapfb_update_window {
69 u32 x, y;
70 u32 width, height;
71 u32 format;
72};
73
74enum omapfb_plane {
75 OMAPFB_PLANE_GFX = 0,
76 OMAPFB_PLANE_VID1,
77 OMAPFB_PLANE_VID2,
78};
79
80enum omapfb_channel_out {
81 OMAPFB_CHANNEL_OUT_LCD = 0,
82 OMAPFB_CHANNEL_OUT_DIGIT,
83};
84
85struct omapfb_setup_plane {
86 u8 plane;
87 u8 channel_out;
88 u32 offset;
89 u32 pos_x, pos_y;
90 u32 width, height;
91 u32 color_mode;
92};
93
94struct omapfb_enable_plane {
95 u8 plane;
96 u8 enable;
97};
98
99enum omapfb_color_key_type {
100 OMAPFB_COLOR_KEY_DISABLED = 0,
101 OMAPFB_COLOR_KEY_GFX_DST,
102 OMAPFB_COLOR_KEY_VID_SRC,
103};
104
105struct omapfb_color_key {
106 u8 channel_out;
107 u32 background;
108 u32 trans_key;
109 u8 key_type;
110};
111
112enum omapfb_update_mode {
113 OMAPFB_UPDATE_DISABLED = 0,
114 OMAPFB_AUTO_UPDATE,
115 OMAPFB_MANUAL_UPDATE
116};
117
118#ifdef __KERNEL__
119
120#include <linux/completion.h>
121#include <linux/interrupt.h>
122#include <linux/fb.h>
123
124#define OMAP_LCDC_INV_VSYNC 0x0001
125#define OMAP_LCDC_INV_HSYNC 0x0002
126#define OMAP_LCDC_INV_PIX_CLOCK 0x0004
127#define OMAP_LCDC_INV_OUTPUT_EN 0x0008
128#define OMAP_LCDC_HSVS_RISING_EDGE 0x0010
129#define OMAP_LCDC_HSVS_OPPOSITE 0x0020
130
131#define OMAP_LCDC_SIGNAL_MASK 0x003f
132
133#define OMAP_LCDC_PANEL_TFT 0x0100
134
135#ifdef CONFIG_ARCH_OMAP1
136#define OMAPFB_PLANE_NUM 1
137#else
138#define OMAPFB_PLANE_NUM 3
139#endif
140
141struct omapfb_device;
142
143struct lcd_panel {
144 const char *name;
145 int config; /* TFT/STN, signal inversion */
146 int bpp; /* Pixel format in fb mem */
147 int data_lines; /* Lines on LCD HW interface */
148
149 int x_res, y_res;
150 int pixel_clock; /* In kHz */
151 int hsw; /* Horizontal synchronization
152 pulse width */
153 int hfp; /* Horizontal front porch */
154 int hbp; /* Horizontal back porch */
155 int vsw; /* Vertical synchronization
156 pulse width */
157 int vfp; /* Vertical front porch */
158 int vbp; /* Vertical back porch */
159 int acb; /* ac-bias pin frequency */
160 int pcd; /* pixel clock divider.
161 Obsolete use pixel_clock instead */
162
163 int (*init) (struct omapfb_device *fbdev);
164 void (*cleanup) (void);
165 int (*enable) (void);
166 void (*disable) (void);
167 unsigned long (*get_caps) (void);
168 int (*set_bklight_level)(unsigned int level);
169 unsigned int (*get_bklight_level)(void);
170 unsigned int (*get_bklight_max) (void);
171 int (*run_test) (int test_num);
172};
173
174struct omapfb_device;
175
176struct extif_timings {
177 int cs_on_time;
178 int cs_off_time;
179 int we_on_time;
180 int we_off_time;
181 int re_on_time;
182 int re_off_time;
183 int we_cycle_time;
184 int re_cycle_time;
185 int cs_pulse_width;
186 int access_time;
187};
188
189struct lcd_ctrl_extif {
190 int (*init) (void);
191 void (*cleanup) (void);
192 void (*set_timings) (const struct extif_timings *timings);
193 void (*write_command) (u32 cmd);
194 u32 (*read_data) (void);
195 void (*write_data) (u32 data);
196 void (*transfer_area) (int width, int height,
197 void (callback)(void * data), void *data);
198};
199
200struct lcd_ctrl {
201 const char *name;
202 void *data;
203
204 int (*init) (struct omapfb_device *fbdev,
205 int ext_mode, int req_vram_size);
206 void (*cleanup) (void);
207 void (*get_vram_layout)(unsigned long *size,
208 void **virt_base,
209 dma_addr_t *phys_base);
210 unsigned long (*get_caps) (void);
211 int (*set_update_mode)(enum omapfb_update_mode mode);
212 enum omapfb_update_mode (*get_update_mode)(void);
213 int (*setup_plane) (int plane, int channel_out,
214 unsigned long offset,
215 int screen_width,
216 int pos_x, int pos_y, int width,
217 int height, int color_mode);
218 int (*enable_plane) (int plane, int enable);
219 int (*update_window) (struct omapfb_update_window *win,
220 void (*callback)(void *),
221 void *callback_data);
222 void (*sync) (void);
223 void (*suspend) (void);
224 void (*resume) (void);
225 int (*run_test) (int test_num);
226 int (*setcolreg) (u_int regno, u16 red, u16 green,
227 u16 blue, u16 transp,
228 int update_hw_mem);
229 int (*set_color_key) (struct omapfb_color_key *ck);
230
231};
232
233enum omapfb_state {
234 OMAPFB_DISABLED = 0,
235 OMAPFB_SUSPENDED= 99,
236 OMAPFB_ACTIVE = 100
237};
238
239struct omapfb_device {
240 int state;
241 int ext_lcdc; /* Using external
242 LCD controller */
243 struct semaphore rqueue_sema;
244
245 void *vram_virt_base;
246 dma_addr_t vram_phys_base;
247 unsigned long vram_size;
248
249 int color_mode;
250 int palette_size;
251 int mirror;
252 u32 pseudo_palette[17];
253
254 struct lcd_panel *panel; /* LCD panel */
255 struct lcd_ctrl *ctrl; /* LCD controller */
256 struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */
257 struct lcd_ctrl_extif *ext_if; /* LCD ctrl external
258 interface */
259 struct fb_info *fb_info;
260
261 struct device *dev;
262};
263
264extern struct lcd_panel h3_panel;
265extern struct lcd_panel h2_panel;
266extern struct lcd_panel p2_panel;
267extern struct lcd_panel osk_panel;
268extern struct lcd_panel innovator1610_panel;
269extern struct lcd_panel innovator1510_panel;
270
271#ifdef CONFIG_ARCH_OMAP1
272extern struct lcd_ctrl omap1_lcd_ctrl;
273#else
274extern struct lcd_ctrl omap2_disp_ctrl;
275#endif
276
277extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
278
279#endif /* __KERNEL__ */
280
281#endif /* __OMAPFB_H */
diff --git a/include/asm-arm/arch-omap/pm.h b/include/asm-arm/arch-omap/pm.h
index fbd742d0c499..7c790425e363 100644
--- a/include/asm-arm/arch-omap/pm.h
+++ b/include/asm-arm/arch-omap/pm.h
@@ -98,7 +98,14 @@
98#define OMAP1610_IDLECT3 0xfffece24 98#define OMAP1610_IDLECT3 0xfffece24
99#define OMAP1610_IDLE_LOOP_REQUEST 0x0400 99#define OMAP1610_IDLE_LOOP_REQUEST 0x0400
100 100
101#if !defined(CONFIG_ARCH_OMAP1510) && \ 101#define OMAP730_IDLECT1_SLEEP_VAL 0x16c7
102#define OMAP730_IDLECT2_SLEEP_VAL 0x09c7
103#define OMAP730_IDLECT3_VAL 0x3f
104#define OMAP730_IDLECT3 0xfffece24
105#define OMAP730_IDLE_LOOP_REQUEST 0x0C00
106
107#if !defined(CONFIG_ARCH_OMAP730) && \
108 !defined(CONFIG_ARCH_OMAP15XX) && \
102 !defined(CONFIG_ARCH_OMAP16XX) && \ 109 !defined(CONFIG_ARCH_OMAP16XX) && \
103 !defined(CONFIG_ARCH_OMAP24XX) 110 !defined(CONFIG_ARCH_OMAP24XX)
104#error "Power management for this processor not implemented yet" 111#error "Power management for this processor not implemented yet"
@@ -107,8 +114,10 @@
107#ifndef __ASSEMBLER__ 114#ifndef __ASSEMBLER__
108extern void omap_pm_idle(void); 115extern void omap_pm_idle(void);
109extern void omap_pm_suspend(void); 116extern void omap_pm_suspend(void);
117extern void omap730_cpu_suspend(unsigned short, unsigned short);
110extern void omap1510_cpu_suspend(unsigned short, unsigned short); 118extern void omap1510_cpu_suspend(unsigned short, unsigned short);
111extern void omap1610_cpu_suspend(unsigned short, unsigned short); 119extern void omap1610_cpu_suspend(unsigned short, unsigned short);
120extern void omap730_idle_loop_suspend(void);
112extern void omap1510_idle_loop_suspend(void); 121extern void omap1510_idle_loop_suspend(void);
113extern void omap1610_idle_loop_suspend(void); 122extern void omap1610_idle_loop_suspend(void);
114 123
@@ -118,6 +127,8 @@ extern void omap_serial_wake_trigger(int enable);
118#define omap_serial_wake_trigger(x) {} 127#define omap_serial_wake_trigger(x) {}
119#endif /* CONFIG_OMAP_SERIAL_WAKE */ 128#endif /* CONFIG_OMAP_SERIAL_WAKE */
120 129
130extern unsigned int omap730_cpu_suspend_sz;
131extern unsigned int omap730_idle_loop_suspend_sz;
121extern unsigned int omap1510_cpu_suspend_sz; 132extern unsigned int omap1510_cpu_suspend_sz;
122extern unsigned int omap1510_idle_loop_suspend_sz; 133extern unsigned int omap1510_idle_loop_suspend_sz;
123extern unsigned int omap1610_cpu_suspend_sz; 134extern unsigned int omap1610_cpu_suspend_sz;
@@ -131,6 +142,10 @@ extern unsigned int omap1610_idle_loop_suspend_sz;
131#define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x)) 142#define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x))
132#define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] 143#define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]
133 144
145#define MPUI730_SAVE(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x] = omap_readl(x)
146#define MPUI730_RESTORE(x) omap_writel((mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]), (x))
147#define MPUI730_SHOW(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]
148
134#define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x) 149#define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x)
135#define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x)) 150#define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x))
136#define MPUI1510_SHOW(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] 151#define MPUI1510_SHOW(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]
@@ -188,13 +203,34 @@ enum mpui1510_save_state {
188 MPUI1510_SLEEP_SAVE_EMIFS_CONFIG, 203 MPUI1510_SLEEP_SAVE_EMIFS_CONFIG,
189 MPUI1510_SLEEP_SAVE_OMAP_IH1_MIR, 204 MPUI1510_SLEEP_SAVE_OMAP_IH1_MIR,
190 MPUI1510_SLEEP_SAVE_OMAP_IH2_MIR, 205 MPUI1510_SLEEP_SAVE_OMAP_IH2_MIR,
191#if defined(CONFIG_ARCH_OMAP1510) 206#if defined(CONFIG_ARCH_OMAP15XX)
192 MPUI1510_SLEEP_SAVE_SIZE 207 MPUI1510_SLEEP_SAVE_SIZE
193#else 208#else
194 MPUI1510_SLEEP_SAVE_SIZE = 0 209 MPUI1510_SLEEP_SAVE_SIZE = 0
195#endif 210#endif
196}; 211};
197 212
213enum mpui730_save_state {
214 MPUI730_SLEEP_SAVE_START = 0,
215 /*
216 * MPUI registers 32 bits
217 */
218 MPUI730_SLEEP_SAVE_MPUI_CTRL,
219 MPUI730_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
220 MPUI730_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
221 MPUI730_SLEEP_SAVE_MPUI_DSP_STATUS,
222 MPUI730_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
223 MPUI730_SLEEP_SAVE_EMIFS_CONFIG,
224 MPUI730_SLEEP_SAVE_OMAP_IH1_MIR,
225 MPUI730_SLEEP_SAVE_OMAP_IH2_0_MIR,
226 MPUI730_SLEEP_SAVE_OMAP_IH2_1_MIR,
227#if defined(CONFIG_ARCH_OMAP730)
228 MPUI730_SLEEP_SAVE_SIZE
229#else
230 MPUI730_SLEEP_SAVE_SIZE = 0
231#endif
232};
233
198enum mpui1610_save_state { 234enum mpui1610_save_state {
199 MPUI1610_SLEEP_SAVE_START = 0, 235 MPUI1610_SLEEP_SAVE_START = 0,
200 /* 236 /*
diff --git a/include/asm-arm/arch-omap/prcm.h b/include/asm-arm/arch-omap/prcm.h
new file mode 100644
index 000000000000..7b48a5cbb15f
--- /dev/null
+++ b/include/asm-arm/arch-omap/prcm.h
@@ -0,0 +1,429 @@
1/*
2 * prcm.h - Access definations for use in OMAP24XX clock and power management
3 *
4 * Copyright (C) 2005 Texas Instruments, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
22#define __ASM_ARM_ARCH_DPM_PRCM_H
23
24/* SET_PERFORMANCE_LEVEL PARAMETERS */
25#define PRCM_HALF_SPEED 1
26#define PRCM_FULL_SPEED 2
27
28#ifndef __ASSEMBLER__
29
30#define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset))
31
32#define PRCM_REVISION PRCM_REG32(0x000)
33#define PRCM_SYSCONFIG PRCM_REG32(0x010)
34#define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018)
35#define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C)
36#define PRCM_VOLTCTRL PRCM_REG32(0x050)
37#define PRCM_VOLTST PRCM_REG32(0x054)
38#define PRCM_CLKSRC_CTRL PRCM_REG32(0x060)
39#define PRCM_CLKOUT_CTRL PRCM_REG32(0x070)
40#define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078)
41#define PRCM_CLKCFG_CTRL PRCM_REG32(0x080)
42#define PRCM_CLKCFG_STATUS PRCM_REG32(0x084)
43#define PRCM_VOLTSETUP PRCM_REG32(0x090)
44#define PRCM_CLKSSETUP PRCM_REG32(0x094)
45#define PRCM_POLCTRL PRCM_REG32(0x098)
46
47/* GENERAL PURPOSE */
48#define GENERAL_PURPOSE1 PRCM_REG32(0x0B0)
49#define GENERAL_PURPOSE2 PRCM_REG32(0x0B4)
50#define GENERAL_PURPOSE3 PRCM_REG32(0x0B8)
51#define GENERAL_PURPOSE4 PRCM_REG32(0x0BC)
52#define GENERAL_PURPOSE5 PRCM_REG32(0x0C0)
53#define GENERAL_PURPOSE6 PRCM_REG32(0x0C4)
54#define GENERAL_PURPOSE7 PRCM_REG32(0x0C8)
55#define GENERAL_PURPOSE8 PRCM_REG32(0x0CC)
56#define GENERAL_PURPOSE9 PRCM_REG32(0x0D0)
57#define GENERAL_PURPOSE10 PRCM_REG32(0x0D4)
58#define GENERAL_PURPOSE11 PRCM_REG32(0x0D8)
59#define GENERAL_PURPOSE12 PRCM_REG32(0x0DC)
60#define GENERAL_PURPOSE13 PRCM_REG32(0x0E0)
61#define GENERAL_PURPOSE14 PRCM_REG32(0x0E4)
62#define GENERAL_PURPOSE15 PRCM_REG32(0x0E8)
63#define GENERAL_PURPOSE16 PRCM_REG32(0x0EC)
64#define GENERAL_PURPOSE17 PRCM_REG32(0x0F0)
65#define GENERAL_PURPOSE18 PRCM_REG32(0x0F4)
66#define GENERAL_PURPOSE19 PRCM_REG32(0x0F8)
67#define GENERAL_PURPOSE20 PRCM_REG32(0x0FC)
68
69/* MPU */
70#define CM_CLKSEL_MPU PRCM_REG32(0x140)
71#define CM_CLKSTCTRL_MPU PRCM_REG32(0x148)
72#define RM_RSTST_MPU PRCM_REG32(0x158)
73#define PM_WKDEP_MPU PRCM_REG32(0x1C8)
74#define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4)
75#define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8)
76#define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC)
77#define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0)
78#define PM_PWSTST_MPU PRCM_REG32(0x1E4)
79
80/* CORE */
81#define CM_FCLKEN1_CORE PRCM_REG32(0x200)
82#define CM_FCLKEN2_CORE PRCM_REG32(0x204)
83#define CM_FCLKEN3_CORE PRCM_REG32(0x208)
84#define CM_ICLKEN1_CORE PRCM_REG32(0x210)
85#define CM_ICLKEN2_CORE PRCM_REG32(0x214)
86#define CM_ICLKEN3_CORE PRCM_REG32(0x218)
87#define CM_ICLKEN4_CORE PRCM_REG32(0x21C)
88#define CM_IDLEST1_CORE PRCM_REG32(0x220)
89#define CM_IDLEST2_CORE PRCM_REG32(0x224)
90#define CM_IDLEST3_CORE PRCM_REG32(0x228)
91#define CM_IDLEST4_CORE PRCM_REG32(0x22C)
92#define CM_AUTOIDLE1_CORE PRCM_REG32(0x230)
93#define CM_AUTOIDLE2_CORE PRCM_REG32(0x234)
94#define CM_AUTOIDLE3_CORE PRCM_REG32(0x238)
95#define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C)
96#define CM_CLKSEL1_CORE PRCM_REG32(0x240)
97#define CM_CLKSEL2_CORE PRCM_REG32(0x244)
98#define CM_CLKSTCTRL_CORE PRCM_REG32(0x248)
99#define PM_WKEN1_CORE PRCM_REG32(0x2A0)
100#define PM_WKEN2_CORE PRCM_REG32(0x2A4)
101#define PM_WKST1_CORE PRCM_REG32(0x2B0)
102#define PM_WKST2_CORE PRCM_REG32(0x2B4)
103#define PM_WKDEP_CORE PRCM_REG32(0x2C8)
104#define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0)
105#define PM_PWSTST_CORE PRCM_REG32(0x2E4)
106
107/* GFX */
108#define CM_FCLKEN_GFX PRCM_REG32(0x300)
109#define CM_ICLKEN_GFX PRCM_REG32(0x310)
110#define CM_IDLEST_GFX PRCM_REG32(0x320)
111#define CM_CLKSEL_GFX PRCM_REG32(0x340)
112#define CM_CLKSTCTRL_GFX PRCM_REG32(0x348)
113#define RM_RSTCTRL_GFX PRCM_REG32(0x350)
114#define RM_RSTST_GFX PRCM_REG32(0x358)
115#define PM_WKDEP_GFX PRCM_REG32(0x3C8)
116#define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0)
117#define PM_PWSTST_GFX PRCM_REG32(0x3E4)
118
119/* WAKE-UP */
120#define CM_FCLKEN_WKUP PRCM_REG32(0x400)
121#define CM_ICLKEN_WKUP PRCM_REG32(0x410)
122#define CM_IDLEST_WKUP PRCM_REG32(0x420)
123#define CM_AUTOIDLE_WKUP PRCM_REG32(0x430)
124#define CM_CLKSEL_WKUP PRCM_REG32(0x440)
125#define RM_RSTCTRL_WKUP PRCM_REG32(0x450)
126#define RM_RSTTIME_WKUP PRCM_REG32(0x454)
127#define RM_RSTST_WKUP PRCM_REG32(0x458)
128#define PM_WKEN_WKUP PRCM_REG32(0x4A0)
129#define PM_WKST_WKUP PRCM_REG32(0x4B0)
130
131/* CLOCKS */
132#define CM_CLKEN_PLL PRCM_REG32(0x500)
133#define CM_IDLEST_CKGEN PRCM_REG32(0x520)
134#define CM_AUTOIDLE_PLL PRCM_REG32(0x530)
135#define CM_CLKSEL1_PLL PRCM_REG32(0x540)
136#define CM_CLKSEL2_PLL PRCM_REG32(0x544)
137
138/* DSP */
139#define CM_FCLKEN_DSP PRCM_REG32(0x800)
140#define CM_ICLKEN_DSP PRCM_REG32(0x810)
141#define CM_IDLEST_DSP PRCM_REG32(0x820)
142#define CM_AUTOIDLE_DSP PRCM_REG32(0x830)
143#define CM_CLKSEL_DSP PRCM_REG32(0x840)
144#define CM_CLKSTCTRL_DSP PRCM_REG32(0x848)
145#define RM_RSTCTRL_DSP PRCM_REG32(0x850)
146#define RM_RSTST_DSP PRCM_REG32(0x858)
147#define PM_WKEN_DSP PRCM_REG32(0x8A0)
148#define PM_WKDEP_DSP PRCM_REG32(0x8C8)
149#define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0)
150#define PM_PWSTST_DSP PRCM_REG32(0x8E4)
151#define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0)
152#define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4)
153
154/* IVA */
155#define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8)
156#define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC)
157
158/* Modem on 2430 */
159#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
160#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
161#define CM_IDLEST_MDM PRCM_REG32(0xC20)
162#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
163
164/* FIXME: Move to header for 2430 */
165#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
166#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
167
168#define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000)
169#define GPMC_BASE (OMAP24XX_GPMC_BASE)
170#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
171
172#define GPT1_BASE (OMAP24XX_GPT1)
173#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
174
175/* Misc sysconfig */
176#define DISPC_SYSCONFIG DISP_REG32(0x410)
177#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
178#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
179#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
180
181//#define DSP_MMU_SYSCONFIG 0x5A000010
182#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
183//#define IVA_MMU_SYSCONFIG 0x5D000010
184//#define DSP_DMA_SYSCONFIG 0x00FCC02C
185#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
186#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
187#define GPMC_SYSCONFIG GPMC_REG32(0x010)
188#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
189#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
190#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
191#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
192//#define IVA_SYSCONFIG 0x5C060010
193#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
194#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
195#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
196//#define VLYNQ_SYSCONFIG 0x67FFFE10
197
198/* rkw - good cannidates for PM_ to start what nm was trying */
199#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
200#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
201#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
202#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
203#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
204#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
205#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
206#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
207#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
208#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
209#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
210
211#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
212#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
213#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
214#define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10)
215#define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10)
216#define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10)
217#define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10)
218#define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10)
219#define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10)
220#define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10)
221#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
222#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
223
224#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
225
226#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
227#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
228#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
229#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
230
231/* GP TIMER 1 */
232#define GPTIMER1_TISTAT GPT1_REG32(0x014)
233#define GPTIMER1_TISR GPT1_REG32(0x018)
234#define GPTIMER1_TIER GPT1_REG32(0x01C)
235#define GPTIMER1_TWER GPT1_REG32(0x020)
236#define GPTIMER1_TCLR GPT1_REG32(0x024)
237#define GPTIMER1_TCRR GPT1_REG32(0x028)
238#define GPTIMER1_TLDR GPT1_REG32(0x02C)
239#define GPTIMER1_TTGR GPT1_REG32(0x030)
240#define GPTIMER1_TWPS GPT1_REG32(0x034)
241#define GPTIMER1_TMAR GPT1_REG32(0x038)
242#define GPTIMER1_TCAR1 GPT1_REG32(0x03C)
243#define GPTIMER1_TSICR GPT1_REG32(0x040)
244#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
245
246/* rkw -- base fix up please... */
247#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
248
249/* SDRC */
250#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
251#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
252#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
253#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
254#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
255#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
256
257/* GPIO 1 */
258#define GPIO1_BASE GPIOX_BASE(1)
259#define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset))
260#define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C)
261#define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018)
262#define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C)
263#define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028)
264#define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020)
265#define GPIO1_RISINGDETECT GPIO1_REG32(0x048)
266#define GPIO1_DATAIN GPIO1_REG32(0x038)
267#define GPIO1_OE GPIO1_REG32(0x034)
268#define GPIO1_DATAOUT GPIO1_REG32(0x03C)
269
270/* GPIO2 */
271#define GPIO2_BASE GPIOX_BASE(2)
272#define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset))
273#define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C)
274#define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018)
275#define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C)
276#define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028)
277#define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020)
278#define GPIO2_RISINGDETECT GPIO2_REG32(0x048)
279#define GPIO2_DATAIN GPIO2_REG32(0x038)
280#define GPIO2_OE GPIO2_REG32(0x034)
281#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
282
283/* GPIO 3 */
284#define GPIO3_BASE GPIOX_BASE(3)
285#define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset))
286#define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C)
287#define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018)
288#define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C)
289#define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028)
290#define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020)
291#define GPIO3_RISINGDETECT GPIO3_REG32(0x048)
292#define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C)
293#define GPIO3_DATAIN GPIO3_REG32(0x038)
294#define GPIO3_OE GPIO3_REG32(0x034)
295#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
296#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
297#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
298
299/* GPIO 4 */
300#define GPIO4_BASE GPIOX_BASE(4)
301#define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset))
302#define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C)
303#define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018)
304#define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C)
305#define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028)
306#define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020)
307#define GPIO4_RISINGDETECT GPIO4_REG32(0x048)
308#define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C)
309#define GPIO4_DATAIN GPIO4_REG32(0x038)
310#define GPIO4_OE GPIO4_REG32(0x034)
311#define GPIO4_DATAOUT GPIO4_REG32(0x03C)
312#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
313#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
314
315
316/* IO CONFIG */
317#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
318#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
319
320#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
321#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
322#define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8)
323#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
324#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
325#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
326#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
327#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
328#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
329
330/* CONTROL */
331#define CONTROL_DEVCONF CONTROL_REG32(0x274)
332
333/* INTERRUPT CONTROLLER */
334#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
335#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
336
337#define INTC1_U_BASE INTC_REG32(0x000)
338#define INTC_MIR0 INTC_REG32(0x084)
339#define INTC_MIR_SET0 INTC_REG32(0x08C)
340#define INTC_MIR_CLEAR0 INTC_REG32(0x088)
341#define INTC_ISR_CLEAR0 INTC_REG32(0x094)
342#define INTC_MIR1 INTC_REG32(0x0A4)
343#define INTC_MIR_SET1 INTC_REG32(0x0AC)
344#define INTC_MIR_CLEAR1 INTC_REG32(0x0A8)
345#define INTC_ISR_CLEAR1 INTC_REG32(0x0B4)
346#define INTC_MIR2 INTC_REG32(0x0C4)
347#define INTC_MIR_SET2 INTC_REG32(0x0CC)
348#define INTC_MIR_CLEAR2 INTC_REG32(0x0C8)
349#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
350#define INTC_SIR_IRQ INTC_REG32(0x040)
351#define INTC_CONTROL INTC_REG32(0x048)
352#define INTC_ILR11 INTC_REG32(0x12C)
353#define INTC_ILR32 INTC_REG32(0x180)
354#define INTC_ILR37 INTC_REG32(0x194)
355#define INTC_SYSCONFIG INTC_REG32(0x010)
356
357/* RAM FIREWALL */
358#define RAMFW_BASE (0x68005000)
359#define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset))
360
361#define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048)
362#define RAMFW_READPERM0 RAMFW_REG32(0x050)
363#define RAMFW_WRITEPERM0 RAMFW_REG32(0x058)
364
365/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
366//#define DEBUG_BOARD_LED_REGISTER 0x04000014
367
368/* GPMC CS0 */
369#define GPMC_CONFIG1_0 GPMC_REG32(0x060)
370#define GPMC_CONFIG2_0 GPMC_REG32(0x064)
371#define GPMC_CONFIG3_0 GPMC_REG32(0x068)
372#define GPMC_CONFIG4_0 GPMC_REG32(0x06C)
373#define GPMC_CONFIG5_0 GPMC_REG32(0x070)
374#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
375#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
376
377/* GPMC CS1 */
378#define GPMC_CONFIG1_1 GPMC_REG32(0x090)
379#define GPMC_CONFIG2_1 GPMC_REG32(0x094)
380#define GPMC_CONFIG3_1 GPMC_REG32(0x098)
381#define GPMC_CONFIG4_1 GPMC_REG32(0x09C)
382#define GPMC_CONFIG5_1 GPMC_REG32(0x0a0)
383#define GPMC_CONFIG6_1 GPMC_REG32(0x0a4)
384#define GPMC_CONFIG7_1 GPMC_REG32(0x0a8)
385
386/* DSS */
387#define DSS_CONTROL DISP_REG32(0x040)
388#define DISPC_CONTROL DISP_REG32(0x440)
389#define DISPC_SYSSTATUS DISP_REG32(0x414)
390#define DISPC_IRQSTATUS DISP_REG32(0x418)
391#define DISPC_IRQENABLE DISP_REG32(0x41C)
392#define DISPC_CONFIG DISP_REG32(0x444)
393#define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C)
394#define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450)
395#define DISPC_TRANS_COLOR0 DISP_REG32(0x454)
396#define DISPC_TRANS_COLOR1 DISP_REG32(0x458)
397#define DISPC_LINE_NUMBER DISP_REG32(0x460)
398#define DISPC_TIMING_H DISP_REG32(0x464)
399#define DISPC_TIMING_V DISP_REG32(0x468)
400#define DISPC_POL_FREQ DISP_REG32(0x46C)
401#define DISPC_DIVISOR DISP_REG32(0x470)
402#define DISPC_SIZE_DIG DISP_REG32(0x478)
403#define DISPC_SIZE_LCD DISP_REG32(0x47C)
404#define DISPC_GFX_BA0 DISP_REG32(0x480)
405#define DISPC_GFX_BA1 DISP_REG32(0x484)
406#define DISPC_GFX_POSITION DISP_REG32(0x488)
407#define DISPC_GFX_SIZE DISP_REG32(0x48C)
408#define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0)
409#define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4)
410#define DISPC_GFX_ROW_INC DISP_REG32(0x4AC)
411#define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0)
412#define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4)
413#define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8)
414#define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4)
415#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
416#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
417
418/* Wake up define for board */
419#define GPIO97 (1 << 1)
420#define GPIO88 (1 << 24)
421
422#endif /* __ASSEMBLER__ */
423
424#endif
425
426
427
428
429
diff --git a/include/asm-arm/arch-omap/sram.h b/include/asm-arm/arch-omap/sram.h
new file mode 100644
index 000000000000..e72ccbf0fe06
--- /dev/null
+++ b/include/asm-arm/arch-omap/sram.h
@@ -0,0 +1,38 @@
1/*
2 * linux/include/asm-arm/arch-omap/sram.h
3 *
4 * Interface for functions that need to be run in internal SRAM
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ARCH_ARM_OMAP_SRAM_H
12#define __ARCH_ARM_OMAP_SRAM_H
13
14extern void * omap_sram_push(void * start, unsigned long size);
15extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
16
17extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
18 u32 base_cs, u32 force_unlock);
19extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
20 u32 mem_type);
21extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
22
23
24/* Do not use these */
25extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
26extern unsigned long sram_reprogram_clock_sz;
27
28extern void sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
29 u32 base_cs, u32 force_unlock);
30extern unsigned long sram_ddr_init_sz;
31
32extern u32 sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
33extern unsigned long sram_set_prcm_sz;
34
35extern void sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type);
36extern unsigned long sram_reprogram_sdrc_sz;
37
38#endif
diff --git a/include/asm-arm/arch-omap/system.h b/include/asm-arm/arch-omap/system.h
index ff37bc27e603..b43cdd2a3874 100644
--- a/include/asm-arm/arch-omap/system.h
+++ b/include/asm-arm/arch-omap/system.h
@@ -6,18 +6,21 @@
6#define __ASM_ARCH_SYSTEM_H 6#define __ASM_ARCH_SYSTEM_H
7#include <linux/config.h> 7#include <linux/config.h>
8#include <asm/mach-types.h> 8#include <asm/mach-types.h>
9#include <asm/hardware/clock.h>
9#include <asm/arch/hardware.h> 10#include <asm/arch/hardware.h>
10#include <asm/mach-types.h> 11#include <asm/arch/prcm.h>
12
13#ifndef CONFIG_MACH_VOICEBLUE
14#define voiceblue_reset() do {} while (0)
15#endif
11 16
12static inline void arch_idle(void) 17static inline void arch_idle(void)
13{ 18{
14 cpu_do_idle(); 19 cpu_do_idle();
15} 20}
16 21
17static inline void arch_reset(char mode) 22static inline void omap1_arch_reset(char mode)
18{ 23{
19
20#ifdef CONFIG_ARCH_OMAP16XX
21 /* 24 /*
22 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 25 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
23 * "Global Software Reset Affects Traffic Controller Frequency". 26 * "Global Software Reset Affects Traffic Controller Frequency".
@@ -27,13 +30,31 @@ static inline void arch_reset(char mode)
27 DPLL_CTL); 30 DPLL_CTL);
28 omap_writew(0x8, ARM_RSTCT1); 31 omap_writew(0x8, ARM_RSTCT1);
29 } 32 }
30#endif 33
31#ifdef CONFIG_MACH_VOICEBLUE
32 if (machine_is_voiceblue()) 34 if (machine_is_voiceblue())
33 voiceblue_reset(); 35 voiceblue_reset();
34 else 36 else
35#endif
36 omap_writew(1, ARM_RSTCT1); 37 omap_writew(1, ARM_RSTCT1);
37} 38}
38 39
40static inline void omap2_arch_reset(char mode)
41{
42 u32 rate;
43 struct clk *vclk, *sclk;
44
45 vclk = clk_get(NULL, "virt_prcm_set");
46 sclk = clk_get(NULL, "sys_ck");
47 rate = clk_get_rate(sclk);
48 clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */
49 RM_RSTCTRL_WKUP |= 2;
50}
51
52static inline void arch_reset(char mode)
53{
54 if (!cpu_is_omap24xx())
55 omap1_arch_reset(mode);
56 else
57 omap2_arch_reset(mode);
58}
59
39#endif 60#endif
diff --git a/include/asm-arm/arch-omap/timex.h b/include/asm-arm/arch-omap/timex.h
index b61ddb491e83..21f2e367185a 100644
--- a/include/asm-arm/arch-omap/timex.h
+++ b/include/asm-arm/arch-omap/timex.h
@@ -28,6 +28,14 @@
28#if !defined(__ASM_ARCH_OMAP_TIMEX_H) 28#if !defined(__ASM_ARCH_OMAP_TIMEX_H)
29#define __ASM_ARCH_OMAP_TIMEX_H 29#define __ASM_ARCH_OMAP_TIMEX_H
30 30
31/*
32 * OMAP 32KHz timer updates time one jiffie at a time from a secondary timer,
33 * and that's why the CLOCK_TICK_RATE is not 32768.
34 */
35#ifdef CONFIG_OMAP_32K_TIMER
36#define CLOCK_TICK_RATE (CONFIG_OMAP_32K_TIMER_HZ)
37#else
31#define CLOCK_TICK_RATE (HZ * 100000UL) 38#define CLOCK_TICK_RATE (HZ * 100000UL)
39#endif
32 40
33#endif /* __ASM_ARCH_OMAP_TIMEX_H */ 41#endif /* __ASM_ARCH_OMAP_TIMEX_H */
diff --git a/include/asm-arm/arch-omap/uncompress.h b/include/asm-arm/arch-omap/uncompress.h
index 3545c86859cc..c718264affbd 100644
--- a/include/asm-arm/arch-omap/uncompress.h
+++ b/include/asm-arm/arch-omap/uncompress.h
@@ -36,10 +36,14 @@ putstr(const char *s)
36 volatile u8 * uart = 0; 36 volatile u8 * uart = 0;
37 int shift = 2; 37 int shift = 2;
38 38
39#ifdef CONFIG_MACH_OMAP_PALMTE
40 return;
41#endif
42
39#ifdef CONFIG_ARCH_OMAP 43#ifdef CONFIG_ARCH_OMAP
40#ifdef CONFIG_OMAP_LL_DEBUG_UART3 44#ifdef CONFIG_OMAP_LL_DEBUG_UART3
41 uart = (volatile u8 *)(OMAP_UART3_BASE); 45 uart = (volatile u8 *)(OMAP_UART3_BASE);
42#elif CONFIG_OMAP_LL_DEBUG_UART2 46#elif defined(CONFIG_OMAP_LL_DEBUG_UART2)
43 uart = (volatile u8 *)(OMAP_UART2_BASE); 47 uart = (volatile u8 *)(OMAP_UART2_BASE);
44#else 48#else
45 uart = (volatile u8 *)(OMAP_UART1_BASE); 49 uart = (volatile u8 *)(OMAP_UART1_BASE);
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h
index 311f2bb5386a..0b43495d24b4 100644
--- a/include/asm-arm/arch-pxa/sharpsl.h
+++ b/include/asm-arm/arch-pxa/sharpsl.h
@@ -21,12 +21,18 @@ struct corgits_machinfo {
21 void (*wait_hsync)(void); 21 void (*wait_hsync)(void);
22}; 22};
23 23
24
24/* 25/*
25 * SharpSL Backlight 26 * SharpSL Backlight
26 */ 27 */
27
28struct corgibl_machinfo { 28struct corgibl_machinfo {
29 int max_intensity; 29 int max_intensity;
30 void (*set_bl_intensity)(int intensity); 30 void (*set_bl_intensity)(int intensity);
31}; 31};
32extern void corgibl_limit_intensity(int limit);
33
32 34
35/*
36 * SharpSL Battery/PM Driver
37 */
38extern void sharpsl_battery_kick(void);
diff --git a/include/asm-arm/arch-pxa/ssp.h b/include/asm-arm/arch-pxa/ssp.h
index 6ec67b018c09..949878c0d908 100644
--- a/include/asm-arm/arch-pxa/ssp.h
+++ b/include/asm-arm/arch-pxa/ssp.h
@@ -18,6 +18,11 @@
18#ifndef SSP_H 18#ifndef SSP_H
19#define SSP_H 19#define SSP_H
20 20
21/*
22 * SSP initialisation flags
23 */
24#define SSP_NO_IRQ 0x1 /* don't register an irq handler in SSP driver */
25
21struct ssp_state { 26struct ssp_state {
22 u32 cr0; 27 u32 cr0;
23 u32 cr1; 28 u32 cr1;
@@ -31,6 +36,7 @@ struct ssp_dev {
31 u32 flags; 36 u32 flags;
32 u32 psp_flags; 37 u32 psp_flags;
33 u32 speed; 38 u32 speed;
39 int irq;
34}; 40};
35 41
36int ssp_write_word(struct ssp_dev *dev, u32 data); 42int ssp_write_word(struct ssp_dev *dev, u32 data);
@@ -40,7 +46,7 @@ void ssp_enable(struct ssp_dev *dev);
40void ssp_disable(struct ssp_dev *dev); 46void ssp_disable(struct ssp_dev *dev);
41void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp); 47void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
42void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp); 48void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
43int ssp_init(struct ssp_dev *dev, u32 port); 49int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
44int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed); 50int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
45void ssp_exit(struct ssp_dev *dev); 51void ssp_exit(struct ssp_dev *dev);
46 52
diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
index 4df469bf42e2..6288fad0dc41 100644
--- a/include/asm-arm/arch-realview/entry-macro.S
+++ b/include/asm-arm/arch-realview/entry-macro.S
@@ -61,3 +61,14 @@
61 strcc \irqstat, [\base, #GIC_CPU_EOI] 61 strcc \irqstat, [\base, #GIC_CPU_EOI]
62 cmpcs \irqnr, \irqnr 62 cmpcs \irqnr, \irqnr
63 .endm 63 .endm
64
65 /* As above, this assumes that irqstat and base are preserved.. */
66
67 .macro test_for_ltirq, irqnr, irqstat, base, tmp
68 bic \irqnr, \irqstat, #0x1c00
69 mov \tmp, #0
70 cmp \irqnr, #29
71 moveq \tmp, #1
72 streq \irqstat, [\base, #GIC_CPU_EOI]
73 cmp \tmp, #0
74 .endm
diff --git a/include/asm-arm/arch-realview/irqs.h b/include/asm-arm/arch-realview/irqs.h
index ff376494e5b1..c16223c9588d 100644
--- a/include/asm-arm/arch-realview/irqs.h
+++ b/include/asm-arm/arch-realview/irqs.h
@@ -21,6 +21,9 @@
21 21
22#include <asm/arch/platform.h> 22#include <asm/arch/platform.h>
23 23
24#define IRQ_LOCALTIMER 29
25#define IRQ_LOCALWDOG 30
26
24/* 27/*
25 * IRQ interrupts definitions are the same the INT definitions 28 * IRQ interrupts definitions are the same the INT definitions
26 * held within platform.h 29 * held within platform.h
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
index aef9b36b3c37..18d7c18b738c 100644
--- a/include/asm-arm/arch-realview/platform.h
+++ b/include/asm-arm/arch-realview/platform.h
@@ -209,6 +209,8 @@
209#else 209#else
210#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */ 210#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */
211#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */ 211#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
212#define REALVIEW_TWD_BASE 0x10100700
213#define REALVIEW_TWD_SIZE 0x00000100
212#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */ 214#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
213#endif 215#endif
214#define REALVIEW_SMC_BASE 0x10080000 /* SMC */ 216#define REALVIEW_SMC_BASE 0x10080000 /* SMC */
@@ -305,9 +307,6 @@
305#define INT_TSPENINT 30 /* Touchscreen pen */ 307#define INT_TSPENINT 30 /* Touchscreen pen */
306#define INT_TSKPADINT 31 /* Touchscreen keypad */ 308#define INT_TSKPADINT 31 /* Touchscreen keypad */
307#else 309#else
308#define INT_LOCALTIMER 29
309#define INT_LOCALWDOG 30
310
311#define INT_AACI 0 310#define INT_AACI 0
312#define INT_TIMERINT0_1 1 311#define INT_TIMERINT0_1 1
313#define INT_TIMERINT2_3 2 312#define INT_TIMERINT2_3 2
diff --git a/include/asm-arm/assembler.h b/include/asm-arm/assembler.h
index 69a28f96bee2..f31ac92b6c7f 100644
--- a/include/asm-arm/assembler.h
+++ b/include/asm-arm/assembler.h
@@ -83,10 +83,13 @@
83 * Save the current IRQ state and disable IRQs. Note that this macro 83 * Save the current IRQ state and disable IRQs. Note that this macro
84 * assumes FIQs are enabled, and that the processor is in SVC mode. 84 * assumes FIQs are enabled, and that the processor is in SVC mode.
85 */ 85 */
86 .macro save_and_disable_irqs, oldcpsr, temp 86 .macro save_and_disable_irqs, oldcpsr
87 mrs \oldcpsr, cpsr 87 mrs \oldcpsr, cpsr
88 mov \temp, #PSR_I_BIT | MODE_SVC 88#if __LINUX_ARM_ARCH__ >= 6
89 msr cpsr_c, \temp 89 cpsid i
90#else
91 msr cpsr_c, #PSR_I_BIT | MODE_SVC
92#endif
90 .endm 93 .endm
91 94
92/* 95/*
diff --git a/include/asm-arm/mach/flash.h b/include/asm-arm/mach/flash.h
index cd57436d9874..05b029ef6371 100644
--- a/include/asm-arm/mach/flash.h
+++ b/include/asm-arm/mach/flash.h
@@ -11,6 +11,7 @@
11#define ASMARM_MACH_FLASH_H 11#define ASMARM_MACH_FLASH_H
12 12
13struct mtd_partition; 13struct mtd_partition;
14struct mtd_info;
14 15
15/* 16/*
16 * map_name: the map probe function name 17 * map_name: the map probe function name
@@ -19,6 +20,7 @@ struct mtd_partition;
19 * init: method called at driver/device initialisation 20 * init: method called at driver/device initialisation
20 * exit: method called at driver/device removal 21 * exit: method called at driver/device removal
21 * set_vpp: method called to enable or disable VPP 22 * set_vpp: method called to enable or disable VPP
23 * mmcontrol: method called to enable or disable Sync. Burst Read in OneNAND
22 * parts: optional array of mtd_partitions for static partitioning 24 * parts: optional array of mtd_partitions for static partitioning
23 * nr_parts: number of mtd_partitions for static partitoning 25 * nr_parts: number of mtd_partitions for static partitoning
24 */ 26 */
@@ -29,6 +31,7 @@ struct flash_platform_data {
29 int (*init)(void); 31 int (*init)(void);
30 void (*exit)(void); 32 void (*exit)(void);
31 void (*set_vpp)(int on); 33 void (*set_vpp)(int on);
34 void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
32 struct mtd_partition *parts; 35 struct mtd_partition *parts;
33 unsigned int nr_parts; 36 unsigned int nr_parts;
34}; 37};
diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h
index 79dfab87135d..454440193eac 100644
--- a/include/asm-i386/ide.h
+++ b/include/asm-i386/ide.h
@@ -41,6 +41,12 @@ static __inline__ int ide_default_irq(unsigned long base)
41 41
42static __inline__ unsigned long ide_default_io_base(int index) 42static __inline__ unsigned long ide_default_io_base(int index)
43{ 43{
44 /*
45 * If PCI is present then it is not safe to poke around
46 * the other legacy IDE ports. Only 0x1f0 and 0x170 are
47 * defined compatibility mode ports for PCI. A user can
48 * override this using ide= but we must default safe.
49 */
44 if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) { 50 if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) {
45 switch(index) { 51 switch(index) {
46 case 2: return 0x1e8; 52 case 2: return 0x1e8;
diff --git a/include/asm-i386/msi.h b/include/asm-i386/msi.h
index b85393094c83..f041d4495faf 100644
--- a/include/asm-i386/msi.h
+++ b/include/asm-i386/msi.h
@@ -10,13 +10,6 @@
10#include <mach_apic.h> 10#include <mach_apic.h>
11 11
12#define LAST_DEVICE_VECTOR 232 12#define LAST_DEVICE_VECTOR 232
13#define MSI_DEST_MODE MSI_LOGICAL_MODE 13#define MSI_TARGET_CPU_SHIFT 12
14#define MSI_TARGET_CPU_SHIFT 12
15
16#ifdef CONFIG_SMP
17#define MSI_TARGET_CPU logical_smp_processor_id()
18#else
19#define MSI_TARGET_CPU cpu_to_logical_apicid(first_cpu(cpu_online_map))
20#endif
21 14
22#endif /* ASM_MSI_H */ 15#endif /* ASM_MSI_H */
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index 13250199976d..61d3ab9db70c 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -45,6 +45,8 @@ extern void unlock_ipi_call_lock(void);
45#define MAX_APICID 256 45#define MAX_APICID 256
46extern u8 x86_cpu_to_apicid[]; 46extern u8 x86_cpu_to_apicid[];
47 47
48#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
49
48#ifdef CONFIG_HOTPLUG_CPU 50#ifdef CONFIG_HOTPLUG_CPU
49extern void cpu_exit_clear(void); 51extern void cpu_exit_clear(void);
50extern void cpu_uninit(void); 52extern void cpu_uninit(void);
@@ -92,6 +94,10 @@ extern int __cpu_disable(void);
92extern void __cpu_die(unsigned int cpu); 94extern void __cpu_die(unsigned int cpu);
93#endif /* !__ASSEMBLY__ */ 95#endif /* !__ASSEMBLY__ */
94 96
97#else /* CONFIG_SMP */
98
99#define cpu_physical_id(cpu) boot_cpu_physical_apicid
100
95#define NO_PROC_ID 0xFF /* No processor magic marker */ 101#define NO_PROC_ID 0xFF /* No processor magic marker */
96 102
97#endif 103#endif
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
index 4d376e1663f7..8b01a083dde6 100644
--- a/include/asm-ia64/kdebug.h
+++ b/include/asm-ia64/kdebug.h
@@ -22,6 +22,9 @@
22 * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy 22 * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
23 * <anil.s.keshavamurthy@intel.com> adopted from 23 * <anil.s.keshavamurthy@intel.com> adopted from
24 * include/asm-x86_64/kdebug.h 24 * include/asm-x86_64/kdebug.h
25 *
26 * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more
27 * events.
25 */ 28 */
26#include <linux/notifier.h> 29#include <linux/notifier.h>
27 30
@@ -35,13 +38,36 @@ struct die_args {
35 int signr; 38 int signr;
36}; 39};
37 40
38int register_die_notifier(struct notifier_block *nb); 41extern int register_die_notifier(struct notifier_block *);
42extern int unregister_die_notifier(struct notifier_block *);
39extern struct notifier_block *ia64die_chain; 43extern struct notifier_block *ia64die_chain;
40 44
41enum die_val { 45enum die_val {
42 DIE_BREAK = 1, 46 DIE_BREAK = 1,
43 DIE_SS, 47 DIE_FAULT,
48 DIE_OOPS,
44 DIE_PAGE_FAULT, 49 DIE_PAGE_FAULT,
50 DIE_MACHINE_HALT,
51 DIE_MACHINE_RESTART,
52 DIE_MCA_MONARCH_ENTER,
53 DIE_MCA_MONARCH_PROCESS,
54 DIE_MCA_MONARCH_LEAVE,
55 DIE_MCA_SLAVE_ENTER,
56 DIE_MCA_SLAVE_PROCESS,
57 DIE_MCA_SLAVE_LEAVE,
58 DIE_MCA_RENDZVOUS_ENTER,
59 DIE_MCA_RENDZVOUS_PROCESS,
60 DIE_MCA_RENDZVOUS_LEAVE,
61 DIE_INIT_MONARCH_ENTER,
62 DIE_INIT_MONARCH_PROCESS,
63 DIE_INIT_MONARCH_LEAVE,
64 DIE_INIT_SLAVE_ENTER,
65 DIE_INIT_SLAVE_PROCESS,
66 DIE_INIT_SLAVE_LEAVE,
67 DIE_KDEBUG_ENTER,
68 DIE_KDEBUG_LEAVE,
69 DIE_KDUMP_ENTER,
70 DIE_KDUMP_LEAVE,
45}; 71};
46 72
47static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs, 73static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
index 8d6e72f7b08e..b5c65081a3aa 100644
--- a/include/asm-ia64/mmu_context.h
+++ b/include/asm-ia64/mmu_context.h
@@ -7,12 +7,13 @@
7 */ 7 */
8 8
9/* 9/*
10 * Routines to manage the allocation of task context numbers. Task context numbers are 10 * Routines to manage the allocation of task context numbers. Task context
11 * used to reduce or eliminate the need to perform TLB flushes due to context switches. 11 * numbers are used to reduce or eliminate the need to perform TLB flushes
12 * Context numbers are implemented using ia-64 region ids. Since the IA-64 TLB does not 12 * due to context switches. Context numbers are implemented using ia-64
13 * consider the region number when performing a TLB lookup, we need to assign a unique 13 * region ids. Since the IA-64 TLB does not consider the region number when
14 * region id to each region in a process. We use the least significant three bits in a 14 * performing a TLB lookup, we need to assign a unique region id to each
15 * region id for this purpose. 15 * region in a process. We use the least significant three bits in aregion
16 * id for this purpose.
16 */ 17 */
17 18
18#define IA64_REGION_ID_KERNEL 0 /* the kernel's region id (tlb.c depends on this being 0) */ 19#define IA64_REGION_ID_KERNEL 0 /* the kernel's region id (tlb.c depends on this being 0) */
@@ -32,13 +33,17 @@
32struct ia64_ctx { 33struct ia64_ctx {
33 spinlock_t lock; 34 spinlock_t lock;
34 unsigned int next; /* next context number to use */ 35 unsigned int next; /* next context number to use */
35 unsigned int limit; /* next >= limit => must call wrap_mmu_context() */ 36 unsigned int limit; /* available free range */
36 unsigned int max_ctx; /* max. context value supported by all CPUs */ 37 unsigned int max_ctx; /* max. context value supported by all CPUs */
38 /* call wrap_mmu_context when next >= max */
39 unsigned long *bitmap; /* bitmap size is max_ctx+1 */
40 unsigned long *flushmap;/* pending rid to be flushed */
37}; 41};
38 42
39extern struct ia64_ctx ia64_ctx; 43extern struct ia64_ctx ia64_ctx;
40DECLARE_PER_CPU(u8, ia64_need_tlb_flush); 44DECLARE_PER_CPU(u8, ia64_need_tlb_flush);
41 45
46extern void mmu_context_init (void);
42extern void wrap_mmu_context (struct mm_struct *mm); 47extern void wrap_mmu_context (struct mm_struct *mm);
43 48
44static inline void 49static inline void
@@ -47,10 +52,10 @@ enter_lazy_tlb (struct mm_struct *mm, struct task_struct *tsk)
47} 52}
48 53
49/* 54/*
50 * When the context counter wraps around all TLBs need to be flushed because an old 55 * When the context counter wraps around all TLBs need to be flushed because
51 * context number might have been reused. This is signalled by the ia64_need_tlb_flush 56 * an old context number might have been reused. This is signalled by the
52 * per-CPU variable, which is checked in the routine below. Called by activate_mm(). 57 * ia64_need_tlb_flush per-CPU variable, which is checked in the routine
53 * <efocht@ess.nec.de> 58 * below. Called by activate_mm(). <efocht@ess.nec.de>
54 */ 59 */
55static inline void 60static inline void
56delayed_tlb_flush (void) 61delayed_tlb_flush (void)
@@ -60,11 +65,9 @@ delayed_tlb_flush (void)
60 65
61 if (unlikely(__ia64_per_cpu_var(ia64_need_tlb_flush))) { 66 if (unlikely(__ia64_per_cpu_var(ia64_need_tlb_flush))) {
62 spin_lock_irqsave(&ia64_ctx.lock, flags); 67 spin_lock_irqsave(&ia64_ctx.lock, flags);
63 { 68 if (__ia64_per_cpu_var(ia64_need_tlb_flush)) {
64 if (__ia64_per_cpu_var(ia64_need_tlb_flush)) { 69 local_flush_tlb_all();
65 local_flush_tlb_all(); 70 __ia64_per_cpu_var(ia64_need_tlb_flush) = 0;
66 __ia64_per_cpu_var(ia64_need_tlb_flush) = 0;
67 }
68 } 71 }
69 spin_unlock_irqrestore(&ia64_ctx.lock, flags); 72 spin_unlock_irqrestore(&ia64_ctx.lock, flags);
70 } 73 }
@@ -76,20 +79,27 @@ get_mmu_context (struct mm_struct *mm)
76 unsigned long flags; 79 unsigned long flags;
77 nv_mm_context_t context = mm->context; 80 nv_mm_context_t context = mm->context;
78 81
79 if (unlikely(!context)) { 82 if (likely(context))
80 spin_lock_irqsave(&ia64_ctx.lock, flags); 83 goto out;
81 { 84
82 /* re-check, now that we've got the lock: */ 85 spin_lock_irqsave(&ia64_ctx.lock, flags);
83 context = mm->context; 86 /* re-check, now that we've got the lock: */
84 if (context == 0) { 87 context = mm->context;
85 cpus_clear(mm->cpu_vm_mask); 88 if (context == 0) {
86 if (ia64_ctx.next >= ia64_ctx.limit) 89 cpus_clear(mm->cpu_vm_mask);
87 wrap_mmu_context(mm); 90 if (ia64_ctx.next >= ia64_ctx.limit) {
88 mm->context = context = ia64_ctx.next++; 91 ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
89 } 92 ia64_ctx.max_ctx, ia64_ctx.next);
93 ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
94 ia64_ctx.max_ctx, ia64_ctx.next);
95 if (ia64_ctx.next >= ia64_ctx.max_ctx)
96 wrap_mmu_context(mm);
90 } 97 }
91 spin_unlock_irqrestore(&ia64_ctx.lock, flags); 98 mm->context = context = ia64_ctx.next++;
99 __set_bit(context, ia64_ctx.bitmap);
92 } 100 }
101 spin_unlock_irqrestore(&ia64_ctx.lock, flags);
102out:
93 /* 103 /*
94 * Ensure we're not starting to use "context" before any old 104 * Ensure we're not starting to use "context" before any old
95 * uses of it are gone from our TLB. 105 * uses of it are gone from our TLB.
@@ -100,8 +110,8 @@ get_mmu_context (struct mm_struct *mm)
100} 110}
101 111
102/* 112/*
103 * Initialize context number to some sane value. MM is guaranteed to be a brand-new 113 * Initialize context number to some sane value. MM is guaranteed to be a
104 * address-space, so no TLB flushing is needed, ever. 114 * brand-new address-space, so no TLB flushing is needed, ever.
105 */ 115 */
106static inline int 116static inline int
107init_new_context (struct task_struct *p, struct mm_struct *mm) 117init_new_context (struct task_struct *p, struct mm_struct *mm)
@@ -162,7 +172,10 @@ activate_context (struct mm_struct *mm)
162 if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) 172 if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
163 cpu_set(smp_processor_id(), mm->cpu_vm_mask); 173 cpu_set(smp_processor_id(), mm->cpu_vm_mask);
164 reload_context(context); 174 reload_context(context);
165 /* in the unlikely event of a TLB-flush by another thread, redo the load: */ 175 /*
176 * in the unlikely event of a TLB-flush by another thread,
177 * redo the load.
178 */
166 } while (unlikely(context != mm->context)); 179 } while (unlikely(context != mm->context));
167} 180}
168 181
@@ -175,8 +188,8 @@ static inline void
175activate_mm (struct mm_struct *prev, struct mm_struct *next) 188activate_mm (struct mm_struct *prev, struct mm_struct *next)
176{ 189{
177 /* 190 /*
178 * We may get interrupts here, but that's OK because interrupt handlers cannot 191 * We may get interrupts here, but that's OK because interrupt
179 * touch user-space. 192 * handlers cannot touch user-space.
180 */ 193 */
181 ia64_set_kr(IA64_KR_PT_BASE, __pa(next->pgd)); 194 ia64_set_kr(IA64_KR_PT_BASE, __pa(next->pgd));
182 activate_context(next); 195 activate_context(next);
diff --git a/include/asm-ia64/msi.h b/include/asm-ia64/msi.h
index 60f2137f9278..97890f7762b3 100644
--- a/include/asm-ia64/msi.h
+++ b/include/asm-ia64/msi.h
@@ -12,9 +12,6 @@
12static inline void set_intr_gate (int nr, void *func) {} 12static inline void set_intr_gate (int nr, void *func) {}
13#define IO_APIC_VECTOR(irq) (irq) 13#define IO_APIC_VECTOR(irq) (irq)
14#define ack_APIC_irq ia64_eoi 14#define ack_APIC_irq ia64_eoi
15#define cpu_mask_to_apicid(mask) cpu_physical_id(first_cpu(mask))
16#define MSI_DEST_MODE MSI_PHYSICAL_MODE
17#define MSI_TARGET_CPU ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
18#define MSI_TARGET_CPU_SHIFT 4 15#define MSI_TARGET_CPU_SHIFT 4
19 16
20#endif /* ASM_MSI_H */ 17#endif /* ASM_MSI_H */
diff --git a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h
index b65c62702724..a35b323bae4c 100644
--- a/include/asm-ia64/tlbflush.h
+++ b/include/asm-ia64/tlbflush.h
@@ -51,6 +51,7 @@ flush_tlb_mm (struct mm_struct *mm)
51 if (!mm) 51 if (!mm)
52 return; 52 return;
53 53
54 set_bit(mm->context, ia64_ctx.flushmap);
54 mm->context = 0; 55 mm->context = 0;
55 56
56 if (atomic_read(&mm->mm_users) == 0) 57 if (atomic_read(&mm->mm_users) == 0)
diff --git a/include/asm-ppc64/abs_addr.h b/include/asm-powerpc/abs_addr.h
index dc3fc3fefef2..18415108fc56 100644
--- a/include/asm-ppc64/abs_addr.h
+++ b/include/asm-powerpc/abs_addr.h
@@ -1,5 +1,5 @@
1#ifndef _ABS_ADDR_H 1#ifndef _ASM_POWERPC_ABS_ADDR_H
2#define _ABS_ADDR_H 2#define _ASM_POWERPC_ABS_ADDR_H
3 3
4#include <linux/config.h> 4#include <linux/config.h>
5 5
@@ -70,4 +70,4 @@ static inline unsigned long phys_to_abs(unsigned long pa)
70#define iseries_hv_addr(virtaddr) \ 70#define iseries_hv_addr(virtaddr) \
71 (0x8000000000000000 | virt_to_abs(virtaddr)) 71 (0x8000000000000000 | virt_to_abs(virtaddr))
72 72
73#endif /* _ABS_ADDR_H */ 73#endif /* _ASM_POWERPC_ABS_ADDR_H */
diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h
new file mode 100644
index 000000000000..8b133efc9f79
--- /dev/null
+++ b/include/asm-powerpc/asm-compat.h
@@ -0,0 +1,55 @@
1#ifndef _ASM_POWERPC_ASM_COMPAT_H
2#define _ASM_POWERPC_ASM_COMPAT_H
3
4#include <linux/config.h>
5#include <asm/types.h>
6
7#ifdef __ASSEMBLY__
8# define stringify_in_c(...) __VA_ARGS__
9# define ASM_CONST(x) x
10#else
11/* This version of stringify will deal with commas... */
12# define __stringify_in_c(...) #__VA_ARGS__
13# define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " "
14# define __ASM_CONST(x) x##UL
15# define ASM_CONST(x) __ASM_CONST(x)
16#endif
17
18#ifdef __powerpc64__
19
20/* operations for longs and pointers */
21#define PPC_LL stringify_in_c(ld)
22#define PPC_STL stringify_in_c(std)
23#define PPC_LCMPI stringify_in_c(cmpdi)
24#define PPC_LONG stringify_in_c(.llong)
25#define PPC_TLNEI stringify_in_c(tdnei)
26#define PPC_LLARX stringify_in_c(ldarx)
27#define PPC_STLCX stringify_in_c(stdcx.)
28#define PPC_CNTLZL stringify_in_c(cntlzd)
29
30#else /* 32-bit */
31
32/* operations for longs and pointers */
33#define PPC_LL stringify_in_c(lwz)
34#define PPC_STL stringify_in_c(stw)
35#define PPC_LCMPI stringify_in_c(cmpwi)
36#define PPC_LONG stringify_in_c(.long)
37#define PPC_TLNEI stringify_in_c(twnei)
38#define PPC_LLARX stringify_in_c(lwarx)
39#define PPC_STLCX stringify_in_c(stwcx.)
40#define PPC_CNTLZL stringify_in_c(cntlzw)
41
42#endif
43
44#ifdef CONFIG_IBM405_ERR77
45/* Erratum #77 on the 405 means we need a sync or dcbt before every
46 * stwcx. The old ATOMIC_SYNC_FIX covered some but not all of this.
47 */
48#define PPC405_ERR77(ra,rb) stringify_in_c(dcbt ra, rb;)
49#define PPC405_ERR77_SYNC stringify_in_c(sync;)
50#else
51#define PPC405_ERR77(ra,rb)
52#define PPC405_ERR77_SYNC
53#endif
54
55#endif /* _ASM_POWERPC_ASM_COMPAT_H */
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index ed4b345ed75d..9c0b372a46e1 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -9,21 +9,13 @@ typedef struct { volatile int counter; } atomic_t;
9 9
10#ifdef __KERNEL__ 10#ifdef __KERNEL__
11#include <asm/synch.h> 11#include <asm/synch.h>
12#include <asm/asm-compat.h>
12 13
13#define ATOMIC_INIT(i) { (i) } 14#define ATOMIC_INIT(i) { (i) }
14 15
15#define atomic_read(v) ((v)->counter) 16#define atomic_read(v) ((v)->counter)
16#define atomic_set(v,i) (((v)->counter) = (i)) 17#define atomic_set(v,i) (((v)->counter) = (i))
17 18
18/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx.
19 * The old ATOMIC_SYNC_FIX covered some but not all of this.
20 */
21#ifdef CONFIG_IBM405_ERR77
22#define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";"
23#else
24#define PPC405_ERR77(ra,rb)
25#endif
26
27static __inline__ void atomic_add(int a, atomic_t *v) 19static __inline__ void atomic_add(int a, atomic_t *v)
28{ 20{
29 int t; 21 int t;
@@ -205,5 +197,183 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
205#define smp_mb__before_atomic_inc() smp_mb() 197#define smp_mb__before_atomic_inc() smp_mb()
206#define smp_mb__after_atomic_inc() smp_mb() 198#define smp_mb__after_atomic_inc() smp_mb()
207 199
200#ifdef __powerpc64__
201
202typedef struct { volatile long counter; } atomic64_t;
203
204#define ATOMIC64_INIT(i) { (i) }
205
206#define atomic64_read(v) ((v)->counter)
207#define atomic64_set(v,i) (((v)->counter) = (i))
208
209static __inline__ void atomic64_add(long a, atomic64_t *v)
210{
211 long t;
212
213 __asm__ __volatile__(
214"1: ldarx %0,0,%3 # atomic64_add\n\
215 add %0,%2,%0\n\
216 stdcx. %0,0,%3 \n\
217 bne- 1b"
218 : "=&r" (t), "=m" (v->counter)
219 : "r" (a), "r" (&v->counter), "m" (v->counter)
220 : "cc");
221}
222
223static __inline__ long atomic64_add_return(long a, atomic64_t *v)
224{
225 long t;
226
227 __asm__ __volatile__(
228 EIEIO_ON_SMP
229"1: ldarx %0,0,%2 # atomic64_add_return\n\
230 add %0,%1,%0\n\
231 stdcx. %0,0,%2 \n\
232 bne- 1b"
233 ISYNC_ON_SMP
234 : "=&r" (t)
235 : "r" (a), "r" (&v->counter)
236 : "cc", "memory");
237
238 return t;
239}
240
241#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
242
243static __inline__ void atomic64_sub(long a, atomic64_t *v)
244{
245 long t;
246
247 __asm__ __volatile__(
248"1: ldarx %0,0,%3 # atomic64_sub\n\
249 subf %0,%2,%0\n\
250 stdcx. %0,0,%3 \n\
251 bne- 1b"
252 : "=&r" (t), "=m" (v->counter)
253 : "r" (a), "r" (&v->counter), "m" (v->counter)
254 : "cc");
255}
256
257static __inline__ long atomic64_sub_return(long a, atomic64_t *v)
258{
259 long t;
260
261 __asm__ __volatile__(
262 EIEIO_ON_SMP
263"1: ldarx %0,0,%2 # atomic64_sub_return\n\
264 subf %0,%1,%0\n\
265 stdcx. %0,0,%2 \n\
266 bne- 1b"
267 ISYNC_ON_SMP
268 : "=&r" (t)
269 : "r" (a), "r" (&v->counter)
270 : "cc", "memory");
271
272 return t;
273}
274
275static __inline__ void atomic64_inc(atomic64_t *v)
276{
277 long t;
278
279 __asm__ __volatile__(
280"1: ldarx %0,0,%2 # atomic64_inc\n\
281 addic %0,%0,1\n\
282 stdcx. %0,0,%2 \n\
283 bne- 1b"
284 : "=&r" (t), "=m" (v->counter)
285 : "r" (&v->counter), "m" (v->counter)
286 : "cc");
287}
288
289static __inline__ long atomic64_inc_return(atomic64_t *v)
290{
291 long t;
292
293 __asm__ __volatile__(
294 EIEIO_ON_SMP
295"1: ldarx %0,0,%1 # atomic64_inc_return\n\
296 addic %0,%0,1\n\
297 stdcx. %0,0,%1 \n\
298 bne- 1b"
299 ISYNC_ON_SMP
300 : "=&r" (t)
301 : "r" (&v->counter)
302 : "cc", "memory");
303
304 return t;
305}
306
307/*
308 * atomic64_inc_and_test - increment and test
309 * @v: pointer of type atomic64_t
310 *
311 * Atomically increments @v by 1
312 * and returns true if the result is zero, or false for all
313 * other cases.
314 */
315#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
316
317static __inline__ void atomic64_dec(atomic64_t *v)
318{
319 long t;
320
321 __asm__ __volatile__(
322"1: ldarx %0,0,%2 # atomic64_dec\n\
323 addic %0,%0,-1\n\
324 stdcx. %0,0,%2\n\
325 bne- 1b"
326 : "=&r" (t), "=m" (v->counter)
327 : "r" (&v->counter), "m" (v->counter)
328 : "cc");
329}
330
331static __inline__ long atomic64_dec_return(atomic64_t *v)
332{
333 long t;
334
335 __asm__ __volatile__(
336 EIEIO_ON_SMP
337"1: ldarx %0,0,%1 # atomic64_dec_return\n\
338 addic %0,%0,-1\n\
339 stdcx. %0,0,%1\n\
340 bne- 1b"
341 ISYNC_ON_SMP
342 : "=&r" (t)
343 : "r" (&v->counter)
344 : "cc", "memory");
345
346 return t;
347}
348
349#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
350#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
351
352/*
353 * Atomically test *v and decrement if it is greater than 0.
354 * The function returns the old value of *v minus 1.
355 */
356static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
357{
358 long t;
359
360 __asm__ __volatile__(
361 EIEIO_ON_SMP
362"1: ldarx %0,0,%1 # atomic64_dec_if_positive\n\
363 addic. %0,%0,-1\n\
364 blt- 2f\n\
365 stdcx. %0,0,%1\n\
366 bne- 1b"
367 ISYNC_ON_SMP
368 "\n\
3692:" : "=&r" (t)
370 : "r" (&v->counter)
371 : "cc", "memory");
372
373 return t;
374}
375
376#endif /* __powerpc64__ */
377
208#endif /* __KERNEL__ */ 378#endif /* __KERNEL__ */
209#endif /* _ASM_POWERPC_ATOMIC_H_ */ 379#endif /* _ASM_POWERPC_ATOMIC_H_ */
diff --git a/include/asm-powerpc/auxvec.h b/include/asm-powerpc/auxvec.h
index 79d8c4732309..19a099b62cd6 100644
--- a/include/asm-powerpc/auxvec.h
+++ b/include/asm-powerpc/auxvec.h
@@ -14,8 +14,6 @@
14/* The vDSO location. We have to use the same value as x86 for glibc's 14/* The vDSO location. We have to use the same value as x86 for glibc's
15 * sake :-) 15 * sake :-)
16 */ 16 */
17#ifdef __powerpc64__
18#define AT_SYSINFO_EHDR 33 17#define AT_SYSINFO_EHDR 33
19#endif
20 18
21#endif 19#endif
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index dc25c53704d5..5727229b0444 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -40,6 +40,7 @@
40 40
41#include <linux/compiler.h> 41#include <linux/compiler.h>
42#include <asm/atomic.h> 42#include <asm/atomic.h>
43#include <asm/asm-compat.h>
43#include <asm/synch.h> 44#include <asm/synch.h>
44 45
45/* 46/*
@@ -52,16 +53,6 @@
52#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) 53#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
53#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) 54#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
54 55
55#ifdef CONFIG_PPC64
56#define LARXL "ldarx"
57#define STCXL "stdcx."
58#define CNTLZL "cntlzd"
59#else
60#define LARXL "lwarx"
61#define STCXL "stwcx."
62#define CNTLZL "cntlzw"
63#endif
64
65static __inline__ void set_bit(int nr, volatile unsigned long *addr) 56static __inline__ void set_bit(int nr, volatile unsigned long *addr)
66{ 57{
67 unsigned long old; 58 unsigned long old;
@@ -69,10 +60,10 @@ static __inline__ void set_bit(int nr, volatile unsigned long *addr)
69 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); 60 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
70 61
71 __asm__ __volatile__( 62 __asm__ __volatile__(
72"1:" LARXL " %0,0,%3 # set_bit\n" 63"1:" PPC_LLARX "%0,0,%3 # set_bit\n"
73 "or %0,%0,%2\n" 64 "or %0,%0,%2\n"
74 PPC405_ERR77(0,%3) 65 PPC405_ERR77(0,%3)
75 STCXL " %0,0,%3\n" 66 PPC_STLCX "%0,0,%3\n"
76 "bne- 1b" 67 "bne- 1b"
77 : "=&r"(old), "=m"(*p) 68 : "=&r"(old), "=m"(*p)
78 : "r"(mask), "r"(p), "m"(*p) 69 : "r"(mask), "r"(p), "m"(*p)
@@ -86,10 +77,10 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
86 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); 77 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
87 78
88 __asm__ __volatile__( 79 __asm__ __volatile__(
89"1:" LARXL " %0,0,%3 # set_bit\n" 80"1:" PPC_LLARX "%0,0,%3 # clear_bit\n"
90 "andc %0,%0,%2\n" 81 "andc %0,%0,%2\n"
91 PPC405_ERR77(0,%3) 82 PPC405_ERR77(0,%3)
92 STCXL " %0,0,%3\n" 83 PPC_STLCX "%0,0,%3\n"
93 "bne- 1b" 84 "bne- 1b"
94 : "=&r"(old), "=m"(*p) 85 : "=&r"(old), "=m"(*p)
95 : "r"(mask), "r"(p), "m"(*p) 86 : "r"(mask), "r"(p), "m"(*p)
@@ -103,10 +94,10 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr)
103 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); 94 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
104 95
105 __asm__ __volatile__( 96 __asm__ __volatile__(
106"1:" LARXL " %0,0,%3 # set_bit\n" 97"1:" PPC_LLARX "%0,0,%3 # change_bit\n"
107 "xor %0,%0,%2\n" 98 "xor %0,%0,%2\n"
108 PPC405_ERR77(0,%3) 99 PPC405_ERR77(0,%3)
109 STCXL " %0,0,%3\n" 100 PPC_STLCX "%0,0,%3\n"
110 "bne- 1b" 101 "bne- 1b"
111 : "=&r"(old), "=m"(*p) 102 : "=&r"(old), "=m"(*p)
112 : "r"(mask), "r"(p), "m"(*p) 103 : "r"(mask), "r"(p), "m"(*p)
@@ -122,10 +113,10 @@ static __inline__ int test_and_set_bit(unsigned long nr,
122 113
123 __asm__ __volatile__( 114 __asm__ __volatile__(
124 EIEIO_ON_SMP 115 EIEIO_ON_SMP
125"1:" LARXL " %0,0,%3 # test_and_set_bit\n" 116"1:" PPC_LLARX "%0,0,%3 # test_and_set_bit\n"
126 "or %1,%0,%2 \n" 117 "or %1,%0,%2 \n"
127 PPC405_ERR77(0,%3) 118 PPC405_ERR77(0,%3)
128 STCXL " %1,0,%3 \n" 119 PPC_STLCX "%1,0,%3 \n"
129 "bne- 1b" 120 "bne- 1b"
130 ISYNC_ON_SMP 121 ISYNC_ON_SMP
131 : "=&r" (old), "=&r" (t) 122 : "=&r" (old), "=&r" (t)
@@ -144,10 +135,10 @@ static __inline__ int test_and_clear_bit(unsigned long nr,
144 135
145 __asm__ __volatile__( 136 __asm__ __volatile__(
146 EIEIO_ON_SMP 137 EIEIO_ON_SMP
147"1:" LARXL " %0,0,%3 # test_and_clear_bit\n" 138"1:" PPC_LLARX "%0,0,%3 # test_and_clear_bit\n"
148 "andc %1,%0,%2 \n" 139 "andc %1,%0,%2 \n"
149 PPC405_ERR77(0,%3) 140 PPC405_ERR77(0,%3)
150 STCXL " %1,0,%3 \n" 141 PPC_STLCX "%1,0,%3 \n"
151 "bne- 1b" 142 "bne- 1b"
152 ISYNC_ON_SMP 143 ISYNC_ON_SMP
153 : "=&r" (old), "=&r" (t) 144 : "=&r" (old), "=&r" (t)
@@ -166,10 +157,10 @@ static __inline__ int test_and_change_bit(unsigned long nr,
166 157
167 __asm__ __volatile__( 158 __asm__ __volatile__(
168 EIEIO_ON_SMP 159 EIEIO_ON_SMP
169"1:" LARXL " %0,0,%3 # test_and_change_bit\n" 160"1:" PPC_LLARX "%0,0,%3 # test_and_change_bit\n"
170 "xor %1,%0,%2 \n" 161 "xor %1,%0,%2 \n"
171 PPC405_ERR77(0,%3) 162 PPC405_ERR77(0,%3)
172 STCXL " %1,0,%3 \n" 163 PPC_STLCX "%1,0,%3 \n"
173 "bne- 1b" 164 "bne- 1b"
174 ISYNC_ON_SMP 165 ISYNC_ON_SMP
175 : "=&r" (old), "=&r" (t) 166 : "=&r" (old), "=&r" (t)
@@ -184,9 +175,9 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
184 unsigned long old; 175 unsigned long old;
185 176
186 __asm__ __volatile__( 177 __asm__ __volatile__(
187"1:" LARXL " %0,0,%3 # set_bit\n" 178"1:" PPC_LLARX "%0,0,%3 # set_bits\n"
188 "or %0,%0,%2\n" 179 "or %0,%0,%2\n"
189 STCXL " %0,0,%3\n" 180 PPC_STLCX "%0,0,%3\n"
190 "bne- 1b" 181 "bne- 1b"
191 : "=&r" (old), "=m" (*addr) 182 : "=&r" (old), "=m" (*addr)
192 : "r" (mask), "r" (addr), "m" (*addr) 183 : "r" (mask), "r" (addr), "m" (*addr)
@@ -268,7 +259,7 @@ static __inline__ int __ilog2(unsigned long x)
268{ 259{
269 int lz; 260 int lz;
270 261
271 asm (CNTLZL " %0,%1" : "=r" (lz) : "r" (x)); 262 asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
272 return BITS_PER_LONG - 1 - lz; 263 return BITS_PER_LONG - 1 - lz;
273} 264}
274 265
diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h
index d625ee55f957..b001ecb3cd99 100644
--- a/include/asm-powerpc/bug.h
+++ b/include/asm-powerpc/bug.h
@@ -1,6 +1,7 @@
1#ifndef _ASM_POWERPC_BUG_H 1#ifndef _ASM_POWERPC_BUG_H
2#define _ASM_POWERPC_BUG_H 2#define _ASM_POWERPC_BUG_H
3 3
4#include <asm/asm-compat.h>
4/* 5/*
5 * Define an illegal instr to trap on the bug. 6 * Define an illegal instr to trap on the bug.
6 * We don't use 0 because that marks the end of a function 7 * We don't use 0 because that marks the end of a function
@@ -11,14 +12,6 @@
11 12
12#ifndef __ASSEMBLY__ 13#ifndef __ASSEMBLY__
13 14
14#ifdef __powerpc64__
15#define BUG_TABLE_ENTRY ".llong"
16#define BUG_TRAP_OP "tdnei"
17#else
18#define BUG_TABLE_ENTRY ".long"
19#define BUG_TRAP_OP "twnei"
20#endif /* __powerpc64__ */
21
22struct bug_entry { 15struct bug_entry {
23 unsigned long bug_addr; 16 unsigned long bug_addr;
24 long line; 17 long line;
@@ -40,16 +33,16 @@ struct bug_entry *find_bug(unsigned long bugaddr);
40 __asm__ __volatile__( \ 33 __asm__ __volatile__( \
41 "1: twi 31,0,0\n" \ 34 "1: twi 31,0,0\n" \
42 ".section __bug_table,\"a\"\n" \ 35 ".section __bug_table,\"a\"\n" \
43 "\t"BUG_TABLE_ENTRY" 1b,%0,%1,%2\n" \ 36 "\t"PPC_LONG" 1b,%0,%1,%2\n" \
44 ".previous" \ 37 ".previous" \
45 : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ 38 : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
46} while (0) 39} while (0)
47 40
48#define BUG_ON(x) do { \ 41#define BUG_ON(x) do { \
49 __asm__ __volatile__( \ 42 __asm__ __volatile__( \
50 "1: "BUG_TRAP_OP" %0,0\n" \ 43 "1: "PPC_TLNEI" %0,0\n" \
51 ".section __bug_table,\"a\"\n" \ 44 ".section __bug_table,\"a\"\n" \
52 "\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \ 45 "\t"PPC_LONG" 1b,%1,%2,%3\n" \
53 ".previous" \ 46 ".previous" \
54 : : "r" ((long)(x)), "i" (__LINE__), \ 47 : : "r" ((long)(x)), "i" (__LINE__), \
55 "i" (__FILE__), "i" (__FUNCTION__)); \ 48 "i" (__FILE__), "i" (__FUNCTION__)); \
@@ -57,9 +50,9 @@ struct bug_entry *find_bug(unsigned long bugaddr);
57 50
58#define WARN_ON(x) do { \ 51#define WARN_ON(x) do { \
59 __asm__ __volatile__( \ 52 __asm__ __volatile__( \
60 "1: "BUG_TRAP_OP" %0,0\n" \ 53 "1: "PPC_TLNEI" %0,0\n" \
61 ".section __bug_table,\"a\"\n" \ 54 ".section __bug_table,\"a\"\n" \
62 "\t"BUG_TABLE_ENTRY" 1b,%1,%2,%3\n" \ 55 "\t"PPC_LONG" 1b,%1,%2,%3\n" \
63 ".previous" \ 56 ".previous" \
64 : : "r" ((long)(x)), \ 57 : : "r" ((long)(x)), \
65 "i" (__LINE__ + BUG_WARNING_TRAP), \ 58 "i" (__LINE__ + BUG_WARNING_TRAP), \
diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h
new file mode 100644
index 000000000000..26ce502e76e8
--- /dev/null
+++ b/include/asm-powerpc/cache.h
@@ -0,0 +1,40 @@
1#ifndef _ASM_POWERPC_CACHE_H
2#define _ASM_POWERPC_CACHE_H
3
4#ifdef __KERNEL__
5
6#include <linux/config.h>
7
8/* bytes per L1 cache line */
9#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
10#define L1_CACHE_SHIFT 4
11#define MAX_COPY_PREFETCH 1
12#elif defined(CONFIG_PPC32)
13#define L1_CACHE_SHIFT 5
14#define MAX_COPY_PREFETCH 4
15#else /* CONFIG_PPC64 */
16#define L1_CACHE_SHIFT 7
17#endif
18
19#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
20
21#define SMP_CACHE_BYTES L1_CACHE_BYTES
22#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
23
24#if defined(__powerpc64__) && !defined(__ASSEMBLY__)
25struct ppc64_caches {
26 u32 dsize; /* L1 d-cache size */
27 u32 dline_size; /* L1 d-cache line size */
28 u32 log_dline_size;
29 u32 dlines_per_page;
30 u32 isize; /* L1 i-cache size */
31 u32 iline_size; /* L1 i-cache line size */
32 u32 log_iline_size;
33 u32 ilines_per_page;
34};
35
36extern struct ppc64_caches ppc64_caches;
37#endif /* __powerpc64__ && ! __ASSEMBLY__ */
38
39#endif /* __KERNEL__ */
40#endif /* _ASM_POWERPC_CACHE_H */
diff --git a/include/asm-ppc64/cacheflush.h b/include/asm-powerpc/cacheflush.h
index ffbc08be8e52..8a740c88d93d 100644
--- a/include/asm-ppc64/cacheflush.h
+++ b/include/asm-powerpc/cacheflush.h
@@ -1,13 +1,20 @@
1#ifndef _PPC64_CACHEFLUSH_H 1/*
2#define _PPC64_CACHEFLUSH_H 2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version
5 * 2 of the License, or (at your option) any later version.
6 */
7#ifndef _ASM_POWERPC_CACHEFLUSH_H
8#define _ASM_POWERPC_CACHEFLUSH_H
9
10#ifdef __KERNEL__
3 11
4#include <linux/mm.h> 12#include <linux/mm.h>
5#include <asm/cputable.h> 13#include <asm/cputable.h>
6 14
7/* 15/*
8 * No cache flushing is required when address mappings are 16 * No cache flushing is required when address mappings are changed,
9 * changed, because the caches on PowerPCs are physically 17 * because the caches on PowerPCs are physically addressed.
10 * addressed.
11 */ 18 */
12#define flush_cache_all() do { } while (0) 19#define flush_cache_all() do { } while (0)
13#define flush_cache_mm(mm) do { } while (0) 20#define flush_cache_mm(mm) do { } while (0)
@@ -22,27 +29,40 @@ extern void flush_dcache_page(struct page *page);
22#define flush_dcache_mmap_unlock(mapping) do { } while (0) 29#define flush_dcache_mmap_unlock(mapping) do { } while (0)
23 30
24extern void __flush_icache_range(unsigned long, unsigned long); 31extern void __flush_icache_range(unsigned long, unsigned long);
32static inline void flush_icache_range(unsigned long start, unsigned long stop)
33{
34 if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
35 __flush_icache_range(start, stop);
36}
37
25extern void flush_icache_user_range(struct vm_area_struct *vma, 38extern void flush_icache_user_range(struct vm_area_struct *vma,
26 struct page *page, unsigned long addr, 39 struct page *page, unsigned long addr,
27 int len); 40 int len);
41extern void __flush_dcache_icache(void *page_va);
42extern void flush_dcache_icache_page(struct page *page);
43#if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE)
44extern void __flush_dcache_icache_phys(unsigned long physaddr);
45#endif /* CONFIG_PPC32 && !CONFIG_BOOKE */
28 46
29extern void flush_dcache_range(unsigned long start, unsigned long stop); 47extern void flush_dcache_range(unsigned long start, unsigned long stop);
30extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); 48#ifdef CONFIG_PPC32
49extern void clean_dcache_range(unsigned long start, unsigned long stop);
50extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
51#endif /* CONFIG_PPC32 */
52#ifdef CONFIG_PPC64
31extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); 53extern void flush_inval_dcache_range(unsigned long start, unsigned long stop);
54extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
55#endif
32 56
33#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ 57#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
34do { memcpy(dst, src, len); \ 58 do { \
35 flush_icache_user_range(vma, page, vaddr, len); \ 59 memcpy(dst, src, len); \
36} while (0) 60 flush_icache_user_range(vma, page, vaddr, len); \
61 } while (0)
37#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ 62#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
38 memcpy(dst, src, len) 63 memcpy(dst, src, len)
39 64
40extern void __flush_dcache_icache(void *page_va);
41 65
42static inline void flush_icache_range(unsigned long start, unsigned long stop) 66#endif /* __KERNEL__ */
43{
44 if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
45 __flush_icache_range(start, stop);
46}
47 67
48#endif /* _PPC64_CACHEFLUSH_H */ 68#endif /* _ASM_POWERPC_CACHEFLUSH_H */
diff --git a/include/asm-ppc64/compat.h b/include/asm-powerpc/compat.h
index 6ec62cd2d1d1..4db4360c4d4a 100644
--- a/include/asm-ppc64/compat.h
+++ b/include/asm-powerpc/compat.h
@@ -1,5 +1,5 @@
1#ifndef _ASM_PPC64_COMPAT_H 1#ifndef _ASM_POWERPC_COMPAT_H
2#define _ASM_PPC64_COMPAT_H 2#define _ASM_POWERPC_COMPAT_H
3/* 3/*
4 * Architecture specific compatibility types 4 * Architecture specific compatibility types
5 */ 5 */
@@ -49,7 +49,7 @@ struct compat_stat {
49 compat_dev_t st_dev; 49 compat_dev_t st_dev;
50 compat_ino_t st_ino; 50 compat_ino_t st_ino;
51 compat_mode_t st_mode; 51 compat_mode_t st_mode;
52 compat_nlink_t st_nlink; 52 compat_nlink_t st_nlink;
53 __compat_uid32_t st_uid; 53 __compat_uid32_t st_uid;
54 __compat_gid32_t st_gid; 54 __compat_gid32_t st_gid;
55 compat_dev_t st_rdev; 55 compat_dev_t st_rdev;
@@ -202,4 +202,4 @@ struct compat_shmid64_ds {
202 compat_ulong_t __unused6; 202 compat_ulong_t __unused6;
203}; 203};
204 204
205#endif /* _ASM_PPC64_COMPAT_H */ 205#endif /* _ASM_POWERPC_COMPAT_H */
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 79a0556a0ab8..04e2726002cf 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -2,7 +2,7 @@
2#define __ASM_POWERPC_CPUTABLE_H 2#define __ASM_POWERPC_CPUTABLE_H
3 3
4#include <linux/config.h> 4#include <linux/config.h>
5#include <asm/ppc_asm.h> /* for ASM_CONST */ 5#include <asm/asm-compat.h>
6 6
7#define PPC_FEATURE_32 0x80000000 7#define PPC_FEATURE_32 0x80000000
8#define PPC_FEATURE_64 0x40000000 8#define PPC_FEATURE_64 0x40000000
@@ -16,6 +16,10 @@
16#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 16#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
17#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 17#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
18#define PPC_FEATURE_NO_TB 0x00100000 18#define PPC_FEATURE_NO_TB 0x00100000
19#define PPC_FEATURE_POWER4 0x00080000
20#define PPC_FEATURE_POWER5 0x00040000
21#define PPC_FEATURE_POWER5_PLUS 0x00020000
22#define PPC_FEATURE_CELL 0x00010000
19 23
20#ifdef __KERNEL__ 24#ifdef __KERNEL__
21#ifndef __ASSEMBLY__ 25#ifndef __ASSEMBLY__
diff --git a/include/asm-powerpc/current.h b/include/asm-powerpc/current.h
new file mode 100644
index 000000000000..82cd4a9ca99a
--- /dev/null
+++ b/include/asm-powerpc/current.h
@@ -0,0 +1,27 @@
1#ifndef _ASM_POWERPC_CURRENT_H
2#define _ASM_POWERPC_CURRENT_H
3
4/*
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11struct task_struct;
12
13#ifdef __powerpc64__
14#include <asm/paca.h>
15
16#define current (get_paca()->__current)
17
18#else
19
20/*
21 * We keep `current' in r2 for speed.
22 */
23register struct task_struct *current asm ("r2");
24
25#endif
26
27#endif /* _ASM_POWERPC_CURRENT_H */
diff --git a/include/asm-powerpc/eeh_event.h b/include/asm-powerpc/eeh_event.h
new file mode 100644
index 000000000000..d168a30b3866
--- /dev/null
+++ b/include/asm-powerpc/eeh_event.h
@@ -0,0 +1,52 @@
1/*
2 * eeh_event.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
19 */
20
21#ifndef ASM_PPC64_EEH_EVENT_H
22#define ASM_PPC64_EEH_EVENT_H
23
24/** EEH event -- structure holding pci controller data that describes
25 * a change in the isolation status of a PCI slot. A pointer
26 * to this struct is passed as the data pointer in a notify callback.
27 */
28struct eeh_event {
29 struct list_head list;
30 struct device_node *dn; /* struct device node */
31 struct pci_dev *dev; /* affected device */
32 int state;
33 int time_unavail; /* milliseconds until device might be available */
34};
35
36/**
37 * eeh_send_failure_event - generate a PCI error event
38 * @dev pci device
39 *
40 * This routine builds a PCI error event which will be delivered
41 * to all listeners on the peh_notifier_chain.
42 *
43 * This routine can be called within an interrupt context;
44 * the actual event will be delivered in a normal context
45 * (from a workqueue).
46 */
47int eeh_send_failure_event (struct device_node *dn,
48 struct pci_dev *dev,
49 int reset_state,
50 int time_unavail);
51
52#endif /* ASM_PPC64_EEH_EVENT_H */
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index feac3458d71f..3dcd65edf978 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -269,14 +269,12 @@ extern int dcache_bsize;
269extern int icache_bsize; 269extern int icache_bsize;
270extern int ucache_bsize; 270extern int ucache_bsize;
271 271
272#ifdef __powerpc64__ 272/* vDSO has arch_setup_additional_pages */
273#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
273struct linux_binprm; 274struct linux_binprm;
274#define ARCH_HAS_SETUP_ADDITIONAL_PAGES /* vDSO has arch_setup_additional_pages */ 275extern int arch_setup_additional_pages(struct linux_binprm *bprm,
275extern int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack); 276 int executable_stack);
276#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b); 277#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b);
277#else
278#define VDSO_AUX_ENT(a,b)
279#endif /* __powerpc64__ */
280 278
281/* 279/*
282 * The requirements here are: 280 * The requirements here are:
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index 806c142ae9ea..12fabbcb04f0 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -43,6 +43,7 @@
43#define FW_FEATURE_ISERIES (1UL<<21) 43#define FW_FEATURE_ISERIES (1UL<<21)
44 44
45enum { 45enum {
46#ifdef CONFIG_PPC64
46 FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE | 47 FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE |
47 FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY | 48 FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY |
48 FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM | 49 FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM |
@@ -70,6 +71,11 @@ enum {
70 FW_FEATURE_ISERIES_ALWAYS & 71 FW_FEATURE_ISERIES_ALWAYS &
71#endif 72#endif
72 FW_FEATURE_POSSIBLE, 73 FW_FEATURE_POSSIBLE,
74
75#else /* CONFIG_PPC64 */
76 FW_FEATURE_POSSIBLE = 0,
77 FW_FEATURE_ALWAYS = 0,
78#endif
73}; 79};
74 80
75/* This is used to identify firmware features which are available 81/* This is used to identify firmware features which are available
diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h
index 37c94e52ab6d..f0319d50b129 100644
--- a/include/asm-powerpc/futex.h
+++ b/include/asm-powerpc/futex.h
@@ -7,13 +7,14 @@
7#include <asm/errno.h> 7#include <asm/errno.h>
8#include <asm/synch.h> 8#include <asm/synch.h>
9#include <asm/uaccess.h> 9#include <asm/uaccess.h>
10#include <asm/ppc_asm.h> 10#include <asm/asm-compat.h>
11 11
12#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ 12#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
13 __asm__ __volatile ( \ 13 __asm__ __volatile ( \
14 SYNC_ON_SMP \ 14 SYNC_ON_SMP \
15"1: lwarx %0,0,%2\n" \ 15"1: lwarx %0,0,%2\n" \
16 insn \ 16 insn \
17 PPC405_ERR77(0, %2) \
17"2: stwcx. %1,0,%2\n" \ 18"2: stwcx. %1,0,%2\n" \
18 "bne- 1b\n" \ 19 "bne- 1b\n" \
19 "li %1,0\n" \ 20 "li %1,0\n" \
@@ -23,7 +24,7 @@
23 ".previous\n" \ 24 ".previous\n" \
24 ".section __ex_table,\"a\"\n" \ 25 ".section __ex_table,\"a\"\n" \
25 ".align 3\n" \ 26 ".align 3\n" \
26 DATAL " 1b,4b,2b,4b\n" \ 27 PPC_LONG "1b,4b,2b,4b\n" \
27 ".previous" \ 28 ".previous" \
28 : "=&r" (oldval), "=&r" (ret) \ 29 : "=&r" (oldval), "=&r" (ret) \
29 : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \ 30 : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
diff --git a/include/asm-ppc64/hvcall.h b/include/asm-powerpc/hvcall.h
index ab7c3cf24888..d36da61dbc53 100644
--- a/include/asm-ppc64/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -1,5 +1,5 @@
1#ifndef _PPC64_HVCALL_H 1#ifndef _ASM_POWERPC_HVCALL_H
2#define _PPC64_HVCALL_H 2#define _ASM_POWERPC_HVCALL_H
3 3
4#define HVSC .long 0x44000022 4#define HVSC .long 0x44000022
5 5
@@ -138,7 +138,7 @@ long plpar_hcall(unsigned long opcode,
138 */ 138 */
139long plpar_hcall_norets(unsigned long opcode, ...); 139long plpar_hcall_norets(unsigned long opcode, ...);
140 140
141/* 141/*
142 * Special hcall interface for ibmveth support. 142 * Special hcall interface for ibmveth support.
143 * Takes 8 input parms. Returns a rc and stores the 143 * Takes 8 input parms. Returns a rc and stores the
144 * R4 return value in *out1. 144 * R4 return value in *out1.
@@ -153,11 +153,11 @@ long plpar_hcall_8arg_2ret(unsigned long opcode,
153 unsigned long arg7, 153 unsigned long arg7,
154 unsigned long arg8, 154 unsigned long arg8,
155 unsigned long *out1); 155 unsigned long *out1);
156 156
157/* plpar_hcall_4out() 157/* plpar_hcall_4out()
158 * 158 *
159 * same as plpar_hcall except with 4 output arguments. 159 * same as plpar_hcall except with 4 output arguments.
160 * 160 *
161 */ 161 */
162long plpar_hcall_4out(unsigned long opcode, 162long plpar_hcall_4out(unsigned long opcode,
163 unsigned long arg1, 163 unsigned long arg1,
@@ -170,4 +170,4 @@ long plpar_hcall_4out(unsigned long opcode,
170 unsigned long *out4); 170 unsigned long *out4);
171 171
172#endif /* __ASSEMBLY__ */ 172#endif /* __ASSEMBLY__ */
173#endif /* _PPC64_HVCALL_H */ 173#endif /* _ASM_POWERPC_HVCALL_H */
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
index c37b31b96337..26b89d859c56 100644
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -12,7 +12,6 @@
12#include <asm/processor.h> 12#include <asm/processor.h>
13 13
14extern void timer_interrupt(struct pt_regs *); 14extern void timer_interrupt(struct pt_regs *);
15extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
16 15
17#ifdef CONFIG_PPC_ISERIES 16#ifdef CONFIG_PPC_ISERIES
18 17
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index b3935ea28fff..8eb7e857ec4c 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -389,6 +389,7 @@ extern u64 ppc64_interrupt_controller;
389#define SIU_INT_TIMER4 ((uint)0x0f + CPM_IRQ_OFFSET) 389#define SIU_INT_TIMER4 ((uint)0x0f + CPM_IRQ_OFFSET)
390#define SIU_INT_TMCNT ((uint)0x10 + CPM_IRQ_OFFSET) 390#define SIU_INT_TMCNT ((uint)0x10 + CPM_IRQ_OFFSET)
391#define SIU_INT_PIT ((uint)0x11 + CPM_IRQ_OFFSET) 391#define SIU_INT_PIT ((uint)0x11 + CPM_IRQ_OFFSET)
392#define SIU_INT_PCI ((uint)0x12 + CPM_IRQ_OFFSET)
392#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET) 393#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET)
393#define SIU_INT_IRQ2 ((uint)0x14 + CPM_IRQ_OFFSET) 394#define SIU_INT_IRQ2 ((uint)0x14 + CPM_IRQ_OFFSET)
394#define SIU_INT_IRQ3 ((uint)0x15 + CPM_IRQ_OFFSET) 395#define SIU_INT_IRQ3 ((uint)0x15 + CPM_IRQ_OFFSET)
@@ -429,7 +430,6 @@ extern u64 ppc64_interrupt_controller;
429#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 430#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
430/* pedantic: these are long because they are used with set_bit --RR */ 431/* pedantic: these are long because they are used with set_bit --RR */
431extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; 432extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
432extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
433extern atomic_t ppc_n_lost_interrupts; 433extern atomic_t ppc_n_lost_interrupts;
434 434
435#define virt_irq_create_mapping(x) (x) 435#define virt_irq_create_mapping(x) (x)
@@ -488,8 +488,8 @@ extern struct thread_info *softirq_ctx[NR_CPUS];
488 488
489extern void irq_ctx_init(void); 489extern void irq_ctx_init(void);
490extern void call_do_softirq(struct thread_info *tp); 490extern void call_do_softirq(struct thread_info *tp);
491extern int call_handle_IRQ_event(int irq, struct pt_regs *regs, 491extern int call___do_IRQ(int irq, struct pt_regs *regs,
492 struct irqaction *action, struct thread_info *tp); 492 struct thread_info *tp);
493 493
494#define __ARCH_HAS_DO_SOFTIRQ 494#define __ARCH_HAS_DO_SOFTIRQ
495 495
diff --git a/include/asm-ppc64/lppaca.h b/include/asm-powerpc/lppaca.h
index 9e2a6c0649a0..c1bedab1515b 100644
--- a/include/asm-ppc64/lppaca.h
+++ b/include/asm-powerpc/lppaca.h
@@ -16,8 +16,8 @@
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19#ifndef _ASM_LPPACA_H 19#ifndef _ASM_POWERPC_LPPACA_H
20#define _ASM_LPPACA_H 20#define _ASM_POWERPC_LPPACA_H
21 21
22//============================================================================= 22//=============================================================================
23// 23//
@@ -28,8 +28,7 @@
28//---------------------------------------------------------------------------- 28//----------------------------------------------------------------------------
29#include <asm/types.h> 29#include <asm/types.h>
30 30
31struct lppaca 31struct lppaca {
32{
33//============================================================================= 32//=============================================================================
34// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data 33// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
35// NOTE: The xDynXyz fields are fields that will be dynamically changed by 34// NOTE: The xDynXyz fields are fields that will be dynamically changed by
@@ -129,4 +128,4 @@ struct lppaca
129 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF 128 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF
130}; 129};
131 130
132#endif /* _ASM_LPPACA_H */ 131#endif /* _ASM_POWERPC_LPPACA_H */
diff --git a/include/asm-ppc64/paca.h b/include/asm-powerpc/paca.h
index bccacd6aa93a..92c765c35bd0 100644
--- a/include/asm-ppc64/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -1,11 +1,8 @@
1#ifndef _PPC64_PACA_H
2#define _PPC64_PACA_H
3
4/* 1/*
5 * include/asm-ppc64/paca.h 2 * include/asm-powerpc/paca.h
6 * 3 *
7 * This control block defines the PACA which defines the processor 4 * This control block defines the PACA which defines the processor
8 * specific data for each logical processor on the system. 5 * specific data for each logical processor on the system.
9 * There are some pointers defined that are utilized by PLIC. 6 * There are some pointers defined that are utilized by PLIC.
10 * 7 *
11 * C 2001 PPC 64 Team, IBM Corp 8 * C 2001 PPC 64 Team, IBM Corp
@@ -14,7 +11,9 @@
14 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 12 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version. 13 * 2 of the License, or (at your option) any later version.
17 */ 14 */
15#ifndef _ASM_POWERPC_PACA_H
16#define _ASM_POWERPC_PACA_H
18 17
19#include <linux/config.h> 18#include <linux/config.h>
20#include <asm/types.h> 19#include <asm/types.h>
@@ -118,4 +117,4 @@ struct paca_struct {
118 117
119extern struct paca_struct paca[]; 118extern struct paca_struct paca[];
120 119
121#endif /* _PPC64_PACA_H */ 120#endif /* _ASM_POWERPC_PACA_H */
diff --git a/include/asm-powerpc/pmc.h b/include/asm-powerpc/pmc.h
index 2f3c3fc2b796..5f41f3a2b293 100644
--- a/include/asm-powerpc/pmc.h
+++ b/include/asm-powerpc/pmc.h
@@ -22,6 +22,7 @@
22#include <asm/ptrace.h> 22#include <asm/ptrace.h>
23 23
24typedef void (*perf_irq_t)(struct pt_regs *); 24typedef void (*perf_irq_t)(struct pt_regs *);
25extern perf_irq_t perf_irq;
25 26
26int reserve_pmc_hardware(perf_irq_t new_perf_irq); 27int reserve_pmc_hardware(perf_irq_t new_perf_irq);
27void release_pmc_hardware(void); 28void release_pmc_hardware(void);
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index 13aacff755f3..9896fade98a7 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -26,6 +26,10 @@ extern unsigned long find_and_init_phbs(void);
26 26
27extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */ 27extern struct pci_dev *ppc64_isabridge_dev; /* may be NULL if no ISA bus */
28 28
29/** Bus Unit ID macros; get low and hi 32-bits of the 64-bit BUID */
30#define BUID_HI(buid) ((buid) >> 32)
31#define BUID_LO(buid) ((buid) & 0xffffffff)
32
29/* PCI device_node operations */ 33/* PCI device_node operations */
30struct device_node; 34struct device_node;
31typedef void *(*traverse_func)(struct device_node *me, void *data); 35typedef void *(*traverse_func)(struct device_node *me, void *data);
@@ -36,10 +40,6 @@ void pci_devs_phb_init(void);
36void pci_devs_phb_init_dynamic(struct pci_controller *phb); 40void pci_devs_phb_init_dynamic(struct pci_controller *phb);
37void __devinit scan_phb(struct pci_controller *hose); 41void __devinit scan_phb(struct pci_controller *hose);
38 42
39/* PCI address cache management routines */
40void pci_addr_cache_insert_device(struct pci_dev *dev);
41void pci_addr_cache_remove_device(struct pci_dev *dev);
42
43/* From rtas_pci.h */ 43/* From rtas_pci.h */
44void init_pci_config_tokens (void); 44void init_pci_config_tokens (void);
45unsigned long get_phb_buid (struct device_node *); 45unsigned long get_phb_buid (struct device_node *);
@@ -52,4 +52,48 @@ extern unsigned long pci_probe_only;
52extern unsigned long pci_assign_all_buses; 52extern unsigned long pci_assign_all_buses;
53extern int pci_read_irq_line(struct pci_dev *pci_dev); 53extern int pci_read_irq_line(struct pci_dev *pci_dev);
54 54
55/* ---- EEH internal-use-only related routines ---- */
56#ifdef CONFIG_EEH
57/**
58 * rtas_set_slot_reset -- unfreeze a frozen slot
59 *
60 * Clear the EEH-frozen condition on a slot. This routine
61 * does this by asserting the PCI #RST line for 1/8th of
62 * a second; this routine will sleep while the adapter is
63 * being reset.
64 */
65void rtas_set_slot_reset (struct pci_dn *);
66
67/**
68 * eeh_restore_bars - Restore device configuration info.
69 *
70 * A reset of a PCI device will clear out its config space.
71 * This routines will restore the config space for this
72 * device, and is children, to values previously obtained
73 * from the firmware.
74 */
75void eeh_restore_bars(struct pci_dn *);
76
77/**
78 * rtas_configure_bridge -- firmware initialization of pci bridge
79 *
80 * Ask the firmware to configure all PCI bridges devices
81 * located behind the indicated node. Required after a
82 * pci device reset. Does essentially the same hing as
83 * eeh_restore_bars, but for brdges, and lets firmware
84 * do the work.
85 */
86void rtas_configure_bridge(struct pci_dn *);
87
88int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
89
90/**
91 * mark and clear slots: find "partition endpoint" PE and set or
92 * clear the flags for each subnode of the PE.
93 */
94void eeh_mark_slot (struct device_node *dn, int mode_flag);
95void eeh_clear_slot (struct device_node *dn, int mode_flag);
96
97#endif
98
55#endif /* _ASM_POWERPC_PPC_PCI_H */ 99#endif /* _ASM_POWERPC_PPC_PCI_H */
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
index c534ca41224b..c27baa0563fe 100644
--- a/include/asm-powerpc/ppc_asm.h
+++ b/include/asm-powerpc/ppc_asm.h
@@ -6,8 +6,13 @@
6 6
7#include <linux/stringify.h> 7#include <linux/stringify.h>
8#include <linux/config.h> 8#include <linux/config.h>
9#include <asm/asm-compat.h>
9 10
10#ifdef __ASSEMBLY__ 11#ifndef __ASSEMBLY__
12#error __FILE__ should only be used in assembler files
13#else
14
15#define SZL (BITS_PER_LONG/8)
11 16
12/* 17/*
13 * Macros for storing registers into and loading registers from 18 * Macros for storing registers into and loading registers from
@@ -184,12 +189,6 @@ n:
184 oris reg,reg,(label)@h; \ 189 oris reg,reg,(label)@h; \
185 ori reg,reg,(label)@l; 190 ori reg,reg,(label)@l;
186 191
187/* operations for longs and pointers */
188#define LDL ld
189#define STL std
190#define CMPI cmpdi
191#define SZL 8
192
193/* offsets for stack frame layout */ 192/* offsets for stack frame layout */
194#define LRSAVE 16 193#define LRSAVE 16
195 194
@@ -203,12 +202,6 @@ n:
203 202
204#define OFF(name) name@l 203#define OFF(name) name@l
205 204
206/* operations for longs and pointers */
207#define LDL lwz
208#define STL stw
209#define CMPI cmpwi
210#define SZL 4
211
212/* offsets for stack frame layout */ 205/* offsets for stack frame layout */
213#define LRSAVE 4 206#define LRSAVE 4
214 207
@@ -266,15 +259,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
266#endif 259#endif
267 260
268 261
269#ifdef CONFIG_IBM405_ERR77
270#define PPC405_ERR77(ra,rb) dcbt ra, rb;
271#define PPC405_ERR77_SYNC sync;
272#else
273#define PPC405_ERR77(ra,rb)
274#define PPC405_ERR77_SYNC
275#endif
276
277
278#ifdef CONFIG_IBM440EP_ERR42 262#ifdef CONFIG_IBM440EP_ERR42
279#define PPC440EP_ERR42 isync 263#define PPC440EP_ERR42 isync
280#else 264#else
@@ -502,17 +486,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
502#define N_SLINE 68 486#define N_SLINE 68
503#define N_SO 100 487#define N_SO 100
504 488
505#define ASM_CONST(x) x
506#else
507 #define __ASM_CONST(x) x##UL
508 #define ASM_CONST(x) __ASM_CONST(x)
509
510#ifdef CONFIG_PPC64
511#define DATAL ".llong"
512#else
513#define DATAL ".long"
514#endif
515
516#endif /* __ASSEMBLY__ */ 489#endif /* __ASSEMBLY__ */
517 490
518#endif /* _ASM_POWERPC_PPC_ASM_H */ 491#endif /* _ASM_POWERPC_PPC_ASM_H */
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index 1dc4bf7b52b3..d12382d292d4 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -17,65 +17,71 @@
17#include <linux/compiler.h> 17#include <linux/compiler.h>
18#include <asm/ptrace.h> 18#include <asm/ptrace.h>
19#include <asm/types.h> 19#include <asm/types.h>
20#ifdef CONFIG_PPC64
21#include <asm/systemcfg.h>
22#endif
23 20
24#ifdef CONFIG_PPC32 21/* We do _not_ want to define new machine types at all, those must die
25/* 32-bit platform types */ 22 * in favor of using the device-tree
26/* We only need to define a new _MACH_xxx for machines which are part of 23 * -- BenH.
27 * a configuration which supports more than one type of different machine.
28 * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac.
29 * -- Tom
30 */ 24 */
31#define _MACH_prep 0x00000001
32#define _MACH_Pmac 0x00000002 /* pmac or pmac clone (non-chrp) */
33#define _MACH_chrp 0x00000004 /* chrp machine */
34 25
35/* see residual.h for these */ 26/* Platforms codes (to be obsoleted) */
27#define PLATFORM_PSERIES 0x0100
28#define PLATFORM_PSERIES_LPAR 0x0101
29#define PLATFORM_ISERIES_LPAR 0x0201
30#define PLATFORM_LPAR 0x0001
31#define PLATFORM_POWERMAC 0x0400
32#define PLATFORM_MAPLE 0x0500
33#define PLATFORM_PREP 0x0600
34#define PLATFORM_CHRP 0x0700
35#define PLATFORM_CELL 0x1000
36
37/* Compat platform codes for 32 bits */
38#define _MACH_prep PLATFORM_PREP
39#define _MACH_Pmac PLATFORM_POWERMAC
40#define _MACH_chrp PLATFORM_CHRP
41
42/* PREP sub-platform types see residual.h for these */
36#define _PREP_Motorola 0x01 /* motorola prep */ 43#define _PREP_Motorola 0x01 /* motorola prep */
37#define _PREP_Firm 0x02 /* firmworks prep */ 44#define _PREP_Firm 0x02 /* firmworks prep */
38#define _PREP_IBM 0x00 /* ibm prep */ 45#define _PREP_IBM 0x00 /* ibm prep */
39#define _PREP_Bull 0x03 /* bull prep */ 46#define _PREP_Bull 0x03 /* bull prep */
40 47
41/* these are arbitrary */ 48/* CHRP sub-platform types. These are arbitrary */
42#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ 49#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */
43#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ 50#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
44#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ 51#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */
45 52
46#ifdef CONFIG_PPC_MULTIPLATFORM 53#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \
54 _machine == PLATFORM_PSERIES_LPAR)
55#define platform_is_lpar() (!!(_machine & PLATFORM_LPAR))
56
57#if defined(CONFIG_PPC_MULTIPLATFORM)
47extern int _machine; 58extern int _machine;
48 59
60#ifdef CONFIG_PPC32
61
49/* what kind of prep workstation we are */ 62/* what kind of prep workstation we are */
50extern int _prep_type; 63extern int _prep_type;
51extern int _chrp_type; 64extern int _chrp_type;
52 65
53/* 66/*
54 * This is used to identify the board type from a given PReP board 67 * This is used to identify the board type from a given PReP board
55 * vendor. Board revision is also made available. 68 * vendor. Board revision is also made available. This will be moved
69 * elsewhere soon
56 */ 70 */
57extern unsigned char ucSystemType; 71extern unsigned char ucSystemType;
58extern unsigned char ucBoardRev; 72extern unsigned char ucBoardRev;
59extern unsigned char ucBoardRevMaj, ucBoardRevMin; 73extern unsigned char ucBoardRevMaj, ucBoardRevMin;
74
75#endif /* CONFIG_PPC32 */
76
77#elif defined(CONFIG_PPC_ISERIES)
78/*
79 * iSeries is soon to become MULTIPLATFORM hopefully ...
80 */
81#define _machine PLATFORM_ISERIES_LPAR
60#else 82#else
61#define _machine 0 83#define _machine 0
62#endif /* CONFIG_PPC_MULTIPLATFORM */ 84#endif /* CONFIG_PPC_MULTIPLATFORM */
63#endif /* CONFIG_PPC32 */
64
65#ifdef CONFIG_PPC64
66/* Platforms supported by PPC64 */
67#define PLATFORM_PSERIES 0x0100
68#define PLATFORM_PSERIES_LPAR 0x0101
69#define PLATFORM_ISERIES_LPAR 0x0201
70#define PLATFORM_LPAR 0x0001
71#define PLATFORM_POWERMAC 0x0400
72#define PLATFORM_MAPLE 0x0500
73#define PLATFORM_CELL 0x1000
74
75/* Compatibility with drivers coming from PPC32 world */
76#define _machine (systemcfg->platform)
77#define _MACH_Pmac PLATFORM_POWERMAC
78#endif
79 85
80/* 86/*
81 * Default implementation of macro that returns current 87 * Default implementation of macro that returns current
@@ -171,8 +177,8 @@ struct thread_struct {
171#ifdef CONFIG_PPC64 177#ifdef CONFIG_PPC64
172 unsigned long start_tb; /* Start purr when proc switched in */ 178 unsigned long start_tb; /* Start purr when proc switched in */
173 unsigned long accum_tb; /* Total accumilated purr for process */ 179 unsigned long accum_tb; /* Total accumilated purr for process */
174 unsigned long vdso_base; /* base of the vDSO library */
175#endif 180#endif
181 unsigned long vdso_base; /* base of the vDSO library */
176 unsigned long dabr; /* Data address breakpoint register */ 182 unsigned long dabr; /* Data address breakpoint register */
177#ifdef CONFIG_ALTIVEC 183#ifdef CONFIG_ALTIVEC
178 /* Complete AltiVec register set */ 184 /* Complete AltiVec register set */
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 489cf4c99c21..eb392d038ed7 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -16,7 +16,11 @@
16/* Pickup Book E specific registers. */ 16/* Pickup Book E specific registers. */
17#if defined(CONFIG_BOOKE) || defined(CONFIG_40x) 17#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
18#include <asm/reg_booke.h> 18#include <asm/reg_booke.h>
19#endif 19#endif /* CONFIG_BOOKE || CONFIG_40x */
20
21#ifdef CONFIG_8xx
22#include <asm/reg_8xx.h>
23#endif /* CONFIG_8xx */
20 24
21#define MSR_SF_LG 63 /* Enable 64 bit mode */ 25#define MSR_SF_LG 63 /* Enable 64 bit mode */
22#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ 26#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
@@ -359,6 +363,7 @@
359#define SPRN_RPA 0x3D6 /* Required Physical Address Register */ 363#define SPRN_RPA 0x3D6 /* Required Physical Address Register */
360#define SPRN_SDA 0x3BF /* Sampled Data Address Register */ 364#define SPRN_SDA 0x3BF /* Sampled Data Address Register */
361#define SPRN_SDR1 0x019 /* MMU Hash Base Register */ 365#define SPRN_SDR1 0x019 /* MMU Hash Base Register */
366#define SPRN_ASR 0x118 /* Address Space Register */
362#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ 367#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */
363#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ 368#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */
364#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ 369#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */
diff --git a/include/asm-ppc/cache.h b/include/asm-powerpc/reg_8xx.h
index 7a157d0f4b5f..e8ea346b21d3 100644
--- a/include/asm-ppc/cache.h
+++ b/include/asm-powerpc/reg_8xx.h
@@ -1,49 +1,9 @@
1/* 1/*
2 * include/asm-ppc/cache.h 2 * Contains register definitions common to PowerPC 8xx CPUs. Notice
3 */ 3 */
4#ifdef __KERNEL__ 4#ifndef _ASM_POWERPC_REG_8xx_H
5#ifndef __ARCH_PPC_CACHE_H 5#define _ASM_POWERPC_REG_8xx_H
6#define __ARCH_PPC_CACHE_H
7 6
8#include <linux/config.h>
9
10/* bytes per L1 cache line */
11#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
12#define L1_CACHE_SHIFT 4
13#define MAX_COPY_PREFETCH 1
14#elif defined(CONFIG_PPC64BRIDGE)
15#define L1_CACHE_SHIFT 7
16#define MAX_COPY_PREFETCH 1
17#else
18#define L1_CACHE_SHIFT 5
19#define MAX_COPY_PREFETCH 4
20#endif
21
22#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
23
24#define SMP_CACHE_BYTES L1_CACHE_BYTES
25#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
26
27#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
28#define L1_CACHE_PAGES 8
29
30#ifndef __ASSEMBLY__
31extern void clean_dcache_range(unsigned long start, unsigned long stop);
32extern void flush_dcache_range(unsigned long start, unsigned long stop);
33extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
34extern void flush_dcache_all(void);
35#endif /* __ASSEMBLY__ */
36
37/* prep registers for L2 */
38#define CACHECRBA 0x80000823 /* Cache configuration register address */
39#define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */
40#define L2CACHE_512KB 0x00 /* 512KB */
41#define L2CACHE_256KB 0x01 /* 256KB */
42#define L2CACHE_1MB 0x02 /* 1MB */
43#define L2CACHE_NONE 0x03 /* NONE */
44#define L2CACHE_PARITY 0x08 /* Mask for L2 Cache Parity Protected bit */
45
46#ifdef CONFIG_8xx
47/* Cache control on the MPC8xx is provided through some additional 7/* Cache control on the MPC8xx is provided through some additional
48 * special purpose registers. 8 * special purpose registers.
49 */ 9 */
@@ -78,7 +38,5 @@ extern void flush_dcache_all(void);
78 38
79#define DC_DFWT 0x40000000 /* Data cache is forced write through */ 39#define DC_DFWT 0x40000000 /* Data cache is forced write through */
80#define DC_LES 0x20000000 /* Caches are little endian mode */ 40#define DC_LES 0x20000000 /* Caches are little endian mode */
81#endif /* CONFIG_8xx */
82 41
83#endif 42#endif /* _ASM_POWERPC_REG_8xx_H */
84#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/signal.h b/include/asm-powerpc/signal.h
index caf6ede3710f..694c8d2dab87 100644
--- a/include/asm-ppc/signal.h
+++ b/include/asm-powerpc/signal.h
@@ -1,18 +1,11 @@
1#ifndef _ASMPPC_SIGNAL_H 1#ifndef _ASM_POWERPC_SIGNAL_H
2#define _ASMPPC_SIGNAL_H 2#define _ASM_POWERPC_SIGNAL_H
3 3
4#ifdef __KERNEL__
5#include <linux/types.h> 4#include <linux/types.h>
6#endif /* __KERNEL__ */ 5#include <linux/config.h>
7
8/* Avoid too many header ordering problems. */
9struct siginfo;
10
11/* Most things should be clean enough to redefine this at will, if care
12 is taken to make libc match. */
13 6
14#define _NSIG 64 7#define _NSIG 64
15#define _NSIG_BPW 32 8#define _NSIG_BPW BITS_PER_LONG
16#define _NSIG_WORDS (_NSIG / _NSIG_BPW) 9#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
17 10
18typedef unsigned long old_sigset_t; /* at least 32 bits */ 11typedef unsigned long old_sigset_t; /* at least 32 bits */
@@ -77,19 +70,19 @@ typedef struct {
77 * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single 70 * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
78 * Unix names RESETHAND and NODEFER respectively. 71 * Unix names RESETHAND and NODEFER respectively.
79 */ 72 */
80#define SA_NOCLDSTOP 0x00000001 73#define SA_NOCLDSTOP 0x00000001U
81#define SA_NOCLDWAIT 0x00000002 74#define SA_NOCLDWAIT 0x00000002U
82#define SA_SIGINFO 0x00000004 75#define SA_SIGINFO 0x00000004U
83#define SA_ONSTACK 0x08000000 76#define SA_ONSTACK 0x08000000U
84#define SA_RESTART 0x10000000 77#define SA_RESTART 0x10000000U
85#define SA_NODEFER 0x40000000 78#define SA_NODEFER 0x40000000U
86#define SA_RESETHAND 0x80000000 79#define SA_RESETHAND 0x80000000U
87 80
88#define SA_NOMASK SA_NODEFER 81#define SA_NOMASK SA_NODEFER
89#define SA_ONESHOT SA_RESETHAND 82#define SA_ONESHOT SA_RESETHAND
90#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ 83#define SA_INTERRUPT 0x20000000u /* dummy -- ignored */
91 84
92#define SA_RESTORER 0x04000000 85#define SA_RESTORER 0x04000000U
93 86
94/* 87/*
95 * sigaltstack controls 88 * sigaltstack controls
@@ -127,10 +120,13 @@ typedef struct sigaltstack {
127} stack_t; 120} stack_t;
128 121
129#ifdef __KERNEL__ 122#ifdef __KERNEL__
130#include <asm/sigcontext.h> 123struct pt_regs;
124extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
125extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
131#define ptrace_signal_deliver(regs, cookie) do { } while (0) 126#define ptrace_signal_deliver(regs, cookie) do { } while (0)
132#endif /* __KERNEL__ */ 127#endif /* __KERNEL__ */
133 128
129#ifndef __powerpc64__
134/* 130/*
135 * These are parameters to dbg_sigreturn syscall. They enable or 131 * These are parameters to dbg_sigreturn syscall. They enable or
136 * disable certain debugging things that can be done from signal 132 * disable certain debugging things that can be done from signal
@@ -149,5 +145,6 @@ struct sig_dbg_op {
149 145
150/* Enable or disable branch tracing. The value sets the state. */ 146/* Enable or disable branch tracing. The value sets the state. */
151#define SIG_DBG_BRANCH_TRACING 2 147#define SIG_DBG_BRANCH_TRACING 2
148#endif /* ! __powerpc64__ */
152 149
153#endif 150#endif /* _ASM_POWERPC_SIGNAL_H */
diff --git a/include/asm-powerpc/sparsemem.h b/include/asm-powerpc/sparsemem.h
index 1c95ab99deb3..ba1b34fdb967 100644
--- a/include/asm-powerpc/sparsemem.h
+++ b/include/asm-powerpc/sparsemem.h
@@ -8,8 +8,12 @@
8 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space 8 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
9 */ 9 */
10#define SECTION_SIZE_BITS 24 10#define SECTION_SIZE_BITS 24
11#define MAX_PHYSADDR_BITS 38 11#define MAX_PHYSADDR_BITS 44
12#define MAX_PHYSMEM_BITS 36 12#define MAX_PHYSMEM_BITS 44
13
14#ifdef CONFIG_MEMORY_HOTPLUG
15extern void create_section_mapping(unsigned long start, unsigned long end);
16#endif /* CONFIG_MEMORY_HOTPLUG */
13 17
14#endif /* CONFIG_SPARSEMEM */ 18#endif /* CONFIG_SPARSEMEM */
15 19
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 3536a5cd7a2d..5341b75c75cb 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -8,7 +8,6 @@
8#include <linux/kernel.h> 8#include <linux/kernel.h>
9 9
10#include <asm/hw_irq.h> 10#include <asm/hw_irq.h>
11#include <asm/ppc_asm.h>
12#include <asm/atomic.h> 11#include <asm/atomic.h>
13 12
14/* 13/*
@@ -180,6 +179,7 @@ extern struct task_struct *_switch(struct thread_struct *prev,
180extern unsigned int rtas_data; 179extern unsigned int rtas_data;
181extern int mem_init_done; /* set on boot once kmalloc can be called */ 180extern int mem_init_done; /* set on boot once kmalloc can be called */
182extern unsigned long memory_limit; 181extern unsigned long memory_limit;
182extern unsigned long klimit;
183 183
184extern int powersave_nap; /* set if nap mode can be used in idle loop */ 184extern int powersave_nap; /* set if nap mode can be used in idle loop */
185 185
diff --git a/include/asm-ppc64/tce.h b/include/asm-powerpc/tce.h
index d40b6b42ab35..d099d5200f9b 100644
--- a/include/asm-ppc64/tce.h
+++ b/include/asm-powerpc/tce.h
@@ -18,8 +18,8 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21#ifndef _ASM_TCE_H 21#ifndef _ASM_POWERPC_TCE_H
22#define _ASM_TCE_H 22#define _ASM_POWERPC_TCE_H
23 23
24/* 24/*
25 * Tces come in two formats, one for the virtual bus and a different 25 * Tces come in two formats, one for the virtual bus and a different
@@ -61,4 +61,4 @@ union tce_entry {
61}; 61};
62 62
63 63
64#endif 64#endif /* _ASM_POWERPC_TCE_H */
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 2512e3836bf4..015d28746e1b 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -9,15 +9,7 @@
9 9
10static inline int cpu_to_node(int cpu) 10static inline int cpu_to_node(int cpu)
11{ 11{
12 int node; 12 return numa_cpu_lookup_table[cpu];
13
14 node = numa_cpu_lookup_table[cpu];
15
16#ifdef DEBUG_NUMA
17 BUG_ON(node == -1);
18#endif
19
20 return node;
21} 13}
22 14
23#define parent_node(node) (node) 15#define parent_node(node) (node)
@@ -37,8 +29,6 @@ static inline int node_to_first_cpu(int node)
37#define pcibus_to_node(node) (-1) 29#define pcibus_to_node(node) (-1)
38#define pcibus_to_cpumask(bus) (cpu_online_map) 30#define pcibus_to_cpumask(bus) (cpu_online_map)
39 31
40#define nr_cpus_node(node) (nr_cpus_in_node[node])
41
42/* sched_domains SD_NODE_INIT for PPC64 machines */ 32/* sched_domains SD_NODE_INIT for PPC64 machines */
43#define SD_NODE_INIT (struct sched_domain) { \ 33#define SD_NODE_INIT (struct sched_domain) { \
44 .span = CPU_MASK_NONE, \ 34 .span = CPU_MASK_NONE, \
diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h
index 33af730f0d19..3872e924cdd6 100644
--- a/include/asm-powerpc/uaccess.h
+++ b/include/asm-powerpc/uaccess.h
@@ -120,14 +120,6 @@ struct exception_table_entry {
120 120
121extern long __put_user_bad(void); 121extern long __put_user_bad(void);
122 122
123#ifdef __powerpc64__
124#define __EX_TABLE_ALIGN "3"
125#define __EX_TABLE_TYPE "llong"
126#else
127#define __EX_TABLE_ALIGN "2"
128#define __EX_TABLE_TYPE "long"
129#endif
130
131/* 123/*
132 * We don't tell gcc that we are accessing memory, but this is OK 124 * We don't tell gcc that we are accessing memory, but this is OK
133 * because we do not write to any memory gcc knows about, so there 125 * because we do not write to any memory gcc knows about, so there
@@ -142,11 +134,12 @@ extern long __put_user_bad(void);
142 " b 2b\n" \ 134 " b 2b\n" \
143 ".previous\n" \ 135 ".previous\n" \
144 ".section __ex_table,\"a\"\n" \ 136 ".section __ex_table,\"a\"\n" \
145 " .align " __EX_TABLE_ALIGN "\n" \ 137 " .balign %5\n" \
146 " ."__EX_TABLE_TYPE" 1b,3b\n" \ 138 PPC_LONG "1b,3b\n" \
147 ".previous" \ 139 ".previous" \
148 : "=r" (err) \ 140 : "=r" (err) \
149 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) 141 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
142 "i"(sizeof(unsigned long)))
150 143
151#ifdef __powerpc64__ 144#ifdef __powerpc64__
152#define __put_user_asm2(x, ptr, retval) \ 145#define __put_user_asm2(x, ptr, retval) \
@@ -162,12 +155,13 @@ extern long __put_user_bad(void);
162 " b 3b\n" \ 155 " b 3b\n" \
163 ".previous\n" \ 156 ".previous\n" \
164 ".section __ex_table,\"a\"\n" \ 157 ".section __ex_table,\"a\"\n" \
165 " .align " __EX_TABLE_ALIGN "\n" \ 158 " .balign %5\n" \
166 " ." __EX_TABLE_TYPE " 1b,4b\n" \ 159 PPC_LONG "1b,4b\n" \
167 " ." __EX_TABLE_TYPE " 2b,4b\n" \ 160 PPC_LONG "2b,4b\n" \
168 ".previous" \ 161 ".previous" \
169 : "=r" (err) \ 162 : "=r" (err) \
170 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) 163 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
164 "i"(sizeof(unsigned long)))
171#endif /* __powerpc64__ */ 165#endif /* __powerpc64__ */
172 166
173#define __put_user_size(x, ptr, size, retval) \ 167#define __put_user_size(x, ptr, size, retval) \
@@ -213,11 +207,12 @@ extern long __get_user_bad(void);
213 " b 2b\n" \ 207 " b 2b\n" \
214 ".previous\n" \ 208 ".previous\n" \
215 ".section __ex_table,\"a\"\n" \ 209 ".section __ex_table,\"a\"\n" \
216 " .align "__EX_TABLE_ALIGN "\n" \ 210 " .balign %5\n" \
217 " ." __EX_TABLE_TYPE " 1b,3b\n" \ 211 PPC_LONG "1b,3b\n" \
218 ".previous" \ 212 ".previous" \
219 : "=r" (err), "=r" (x) \ 213 : "=r" (err), "=r" (x) \
220 : "b" (addr), "i" (-EFAULT), "0" (err)) 214 : "b" (addr), "i" (-EFAULT), "0" (err), \
215 "i"(sizeof(unsigned long)))
221 216
222#ifdef __powerpc64__ 217#ifdef __powerpc64__
223#define __get_user_asm2(x, addr, err) \ 218#define __get_user_asm2(x, addr, err) \
@@ -235,12 +230,13 @@ extern long __get_user_bad(void);
235 " b 3b\n" \ 230 " b 3b\n" \
236 ".previous\n" \ 231 ".previous\n" \
237 ".section __ex_table,\"a\"\n" \ 232 ".section __ex_table,\"a\"\n" \
238 " .align " __EX_TABLE_ALIGN "\n" \ 233 " .balign %5\n" \
239 " ." __EX_TABLE_TYPE " 1b,4b\n" \ 234 PPC_LONG "1b,4b\n" \
240 " ." __EX_TABLE_TYPE " 2b,4b\n" \ 235 PPC_LONG "2b,4b\n" \
241 ".previous" \ 236 ".previous" \
242 : "=r" (err), "=&r" (x) \ 237 : "=r" (err), "=&r" (x) \
243 : "b" (addr), "i" (-EFAULT), "0" (err)) 238 : "b" (addr), "i" (-EFAULT), "0" (err), \
239 "i"(sizeof(unsigned long)))
244#endif /* __powerpc64__ */ 240#endif /* __powerpc64__ */
245 241
246#define __get_user_size(x, ptr, size, retval) \ 242#define __get_user_size(x, ptr, size, retval) \
diff --git a/include/asm-ppc64/udbg.h b/include/asm-powerpc/udbg.h
index e3b927991851..a383383bc4d4 100644
--- a/include/asm-ppc64/udbg.h
+++ b/include/asm-powerpc/udbg.h
@@ -1,9 +1,3 @@
1#ifndef __UDBG_HDR
2#define __UDBG_HDR
3
4#include <linux/compiler.h>
5#include <linux/init.h>
6
7/* 1/*
8 * c 2001 PPC 64 Team, IBM Corp 2 * c 2001 PPC 64 Team, IBM Corp
9 * 3 *
@@ -13,6 +7,12 @@
13 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
14 */ 8 */
15 9
10#ifndef _ASM_POWERPC_UDBG_H
11#define _ASM_POWERPC_UDBG_H
12
13#include <linux/compiler.h>
14#include <linux/init.h>
15
16extern void (*udbg_putc)(unsigned char c); 16extern void (*udbg_putc)(unsigned char c);
17extern unsigned char (*udbg_getc)(void); 17extern unsigned char (*udbg_getc)(void);
18extern int (*udbg_getc_poll)(void); 18extern int (*udbg_getc_poll)(void);
@@ -28,4 +28,4 @@ extern void udbg_init_uart(void __iomem *comport, unsigned int speed);
28 28
29struct device_node; 29struct device_node;
30extern void udbg_init_scc(struct device_node *np); 30extern void udbg_init_scc(struct device_node *np);
31#endif 31#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/include/asm-ppc64/vdso.h b/include/asm-powerpc/vdso.h
index 85d8a7be25c4..85d8a7be25c4 100644
--- a/include/asm-ppc64/vdso.h
+++ b/include/asm-powerpc/vdso.h
diff --git a/include/asm-powerpc/vdso_datapage.h b/include/asm-powerpc/vdso_datapage.h
new file mode 100644
index 000000000000..fc323b51366b
--- /dev/null
+++ b/include/asm-powerpc/vdso_datapage.h
@@ -0,0 +1,108 @@
1#ifndef _VDSO_DATAPAGE_H
2#define _VDSO_DATAPAGE_H
3
4/*
5 * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM
6 * Copyright (C) 2005 Benjamin Herrenschmidy <benh@kernel.crashing.org>,
7 * IBM Corp.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15
16/*
17 * Note about this structure:
18 *
19 * This structure was historically called systemcfg and exposed to
20 * userland via /proc/ppc64/systemcfg. Unfortunately, this became an
21 * ABI issue as some proprietary software started relying on being able
22 * to mmap() it, thus we have to keep the base layout at least for a
23 * few kernel versions.
24 *
25 * However, since ppc32 doesn't suffer from this backward handicap,
26 * a simpler version of the data structure is used there with only the
27 * fields actually used by the vDSO.
28 *
29 */
30
31/*
32 * If the major version changes we are incompatible.
33 * Minor version changes are a hint.
34 */
35#define SYSTEMCFG_MAJOR 1
36#define SYSTEMCFG_MINOR 1
37
38#ifndef __ASSEMBLY__
39
40#include <linux/unistd.h>
41
42#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32)
43
44/*
45 * So here is the ppc64 backward compatible version
46 */
47
48#ifdef CONFIG_PPC64
49
50struct vdso_data {
51 __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */
52 struct { /* Systemcfg version numbers */
53 __u32 major; /* Major number 0x10 */
54 __u32 minor; /* Minor number 0x14 */
55 } version;
56
57 __u32 platform; /* Platform flags 0x18 */
58 __u32 processor; /* Processor type 0x1C */
59 __u64 processorCount; /* # of physical processors 0x20 */
60 __u64 physicalMemorySize; /* Size of real memory(B) 0x28 */
61 __u64 tb_orig_stamp; /* Timebase at boot 0x30 */
62 __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */
63 __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */
64 __u64 stamp_xsec; /* 0x48 */
65 __u64 tb_update_count; /* Timebase atomicity ctr 0x50 */
66 __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */
67 __u32 tz_dsttime; /* Type of dst correction 0x5C */
68 __u32 dcache_size; /* L1 d-cache size 0x60 */
69 __u32 dcache_line_size; /* L1 d-cache line size 0x64 */
70 __u32 icache_size; /* L1 i-cache size 0x68 */
71 __u32 icache_line_size; /* L1 i-cache line size 0x6C */
72
73 /* those additional ones don't have to be located anywhere
74 * special as they were not part of the original systemcfg
75 */
76 __s64 wtom_clock_sec; /* Wall to monotonic clock */
77 __s32 wtom_clock_nsec;
78 __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
79 __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
80};
81
82#else /* CONFIG_PPC64 */
83
84/*
85 * And here is the simpler 32 bits version
86 */
87struct vdso_data {
88 __u64 tb_orig_stamp; /* Timebase at boot 0x30 */
89 __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */
90 __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */
91 __u64 stamp_xsec; /* 0x48 */
92 __u32 tb_update_count; /* Timebase atomicity ctr 0x50 */
93 __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */
94 __u32 tz_dsttime; /* Type of dst correction 0x5C */
95 __s32 wtom_clock_sec; /* Wall to monotonic clock */
96 __s32 wtom_clock_nsec;
97 __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
98};
99
100#endif /* CONFIG_PPC64 */
101
102#ifdef __KERNEL__
103extern struct vdso_data *vdso_data;
104#endif
105
106#endif /* __ASSEMBLY__ */
107
108#endif /* _SYSTEMCFG_H */
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
index ace2072d4a83..43f7129984c7 100644
--- a/include/asm-powerpc/xmon.h
+++ b/include/asm-powerpc/xmon.h
@@ -7,7 +7,6 @@ struct pt_regs;
7extern int xmon(struct pt_regs *excp); 7extern int xmon(struct pt_regs *excp);
8extern void xmon_printf(const char *fmt, ...); 8extern void xmon_printf(const char *fmt, ...);
9extern void xmon_init(int); 9extern void xmon_init(int);
10extern void xmon_map_scc(void);
11 10
12#endif 11#endif
13#endif 12#endif
diff --git a/include/asm-ppc/cacheflush.h b/include/asm-ppc/cacheflush.h
deleted file mode 100644
index 6a243efb3317..000000000000
--- a/include/asm-ppc/cacheflush.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * include/asm-ppc/cacheflush.h
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#ifdef __KERNEL__
10#ifndef _PPC_CACHEFLUSH_H
11#define _PPC_CACHEFLUSH_H
12
13#include <linux/mm.h>
14
15/*
16 * No cache flushing is required when address mappings are
17 * changed, because the caches on PowerPCs are physically
18 * addressed. -- paulus
19 * Also, when SMP we use the coherency (M) bit of the
20 * BATs and PTEs. -- Cort
21 */
22#define flush_cache_all() do { } while (0)
23#define flush_cache_mm(mm) do { } while (0)
24#define flush_cache_range(vma, a, b) do { } while (0)
25#define flush_cache_page(vma, p, pfn) do { } while (0)
26#define flush_icache_page(vma, page) do { } while (0)
27#define flush_cache_vmap(start, end) do { } while (0)
28#define flush_cache_vunmap(start, end) do { } while (0)
29
30extern void flush_dcache_page(struct page *page);
31#define flush_dcache_mmap_lock(mapping) do { } while (0)
32#define flush_dcache_mmap_unlock(mapping) do { } while (0)
33
34extern void flush_icache_range(unsigned long, unsigned long);
35extern void flush_icache_user_range(struct vm_area_struct *vma,
36 struct page *page, unsigned long addr, int len);
37
38#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
39do { memcpy(dst, src, len); \
40 flush_icache_user_range(vma, page, vaddr, len); \
41} while (0)
42#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
43 memcpy(dst, src, len)
44
45extern void __flush_dcache_icache(void *page_va);
46extern void __flush_dcache_icache_phys(unsigned long physaddr);
47extern void flush_dcache_icache_page(struct page *page);
48#endif /* _PPC_CACHEFLUSH_H */
49#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/current.h b/include/asm-ppc/current.h
deleted file mode 100644
index 8d41501ba10d..000000000000
--- a/include/asm-ppc/current.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifdef __KERNEL__
2#ifndef _PPC_CURRENT_H
3#define _PPC_CURRENT_H
4
5/*
6 * We keep `current' in r2 for speed.
7 */
8register struct task_struct *current asm ("r2");
9
10#endif /* !(_PPC_CURRENT_H) */
11#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index bb1b0576c947..ce212201db2a 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -107,6 +107,7 @@ enum ppc_sys_devices {
107 MPC83xx_SEC2, 107 MPC83xx_SEC2,
108 MPC83xx_USB2_DR, 108 MPC83xx_USB2_DR,
109 MPC83xx_USB2_MPH, 109 MPC83xx_USB2_MPH,
110 MPC83xx_MDIO,
110}; 111};
111 112
112#endif /* CONFIG_83xx */ 113#endif /* CONFIG_83xx */
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index fc44f7ca62d7..538e0c8ab243 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -1,9 +1,12 @@
1#ifndef _PPC_PAGE_H 1#ifndef _PPC_PAGE_H
2#define _PPC_PAGE_H 2#define _PPC_PAGE_H
3 3
4#include <linux/config.h>
5#include <asm/asm-compat.h>
6
4/* PAGE_SHIFT determines the page size */ 7/* PAGE_SHIFT determines the page size */
5#define PAGE_SHIFT 12 8#define PAGE_SHIFT 12
6#define PAGE_SIZE (1UL << PAGE_SHIFT) 9#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
7 10
8/* 11/*
9 * Subtle: this is an int (not an unsigned long) and so it 12 * Subtle: this is an int (not an unsigned long) and so it
@@ -169,5 +172,8 @@ extern __inline__ int get_order(unsigned long size)
169#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ 172#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
170 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 173 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
171 174
175/* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
176#define __HAVE_ARCH_GATE_AREA 1
177
172#endif /* __KERNEL__ */ 178#endif /* __KERNEL__ */
173#endif /* _PPC_PAGE_H */ 179#endif /* _PPC_PAGE_H */
diff --git a/include/asm-ppc64/cache.h b/include/asm-ppc64/cache.h
deleted file mode 100644
index 92140a7efbd1..000000000000
--- a/include/asm-ppc64/cache.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version
5 * 2 of the License, or (at your option) any later version.
6 */
7#ifndef __ARCH_PPC64_CACHE_H
8#define __ARCH_PPC64_CACHE_H
9
10#include <asm/types.h>
11
12/* bytes per L1 cache line */
13#define L1_CACHE_SHIFT 7
14#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
15
16#define SMP_CACHE_BYTES L1_CACHE_BYTES
17#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */
18
19#ifndef __ASSEMBLY__
20
21struct ppc64_caches {
22 u32 dsize; /* L1 d-cache size */
23 u32 dline_size; /* L1 d-cache line size */
24 u32 log_dline_size;
25 u32 dlines_per_page;
26 u32 isize; /* L1 i-cache size */
27 u32 iline_size; /* L1 i-cache line size */
28 u32 log_iline_size;
29 u32 ilines_per_page;
30};
31
32extern struct ppc64_caches ppc64_caches;
33
34#endif
35
36#endif
diff --git a/include/asm-ppc64/current.h b/include/asm-ppc64/current.h
deleted file mode 100644
index 52ddc60c8b65..000000000000
--- a/include/asm-ppc64/current.h
+++ /dev/null
@@ -1,16 +0,0 @@
1#ifndef _PPC64_CURRENT_H
2#define _PPC64_CURRENT_H
3
4#include <asm/paca.h>
5
6/*
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#define get_current() (get_paca()->__current)
14#define current get_current()
15
16#endif /* !(_PPC64_CURRENT_H) */
diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
index 40c8eb57493e..89f26ab31908 100644
--- a/include/asm-ppc64/eeh.h
+++ b/include/asm-ppc64/eeh.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * eeh.h 2 * eeh.h
3 * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation. 3 * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation.
4 * 4 *
@@ -6,12 +6,12 @@
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or 7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version. 8 * (at your option) any later version.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -27,8 +27,6 @@
27 27
28struct pci_dev; 28struct pci_dev;
29struct device_node; 29struct device_node;
30struct device_node;
31struct notifier_block;
32 30
33#ifdef CONFIG_EEH 31#ifdef CONFIG_EEH
34 32
@@ -37,6 +35,10 @@ struct notifier_block;
37#define EEH_MODE_NOCHECK (1<<1) 35#define EEH_MODE_NOCHECK (1<<1)
38#define EEH_MODE_ISOLATED (1<<2) 36#define EEH_MODE_ISOLATED (1<<2)
39 37
38/* Max number of EEH freezes allowed before we consider the device
39 * to be permanently disabled. */
40#define EEH_MAX_ALLOWED_FREEZES 5
41
40void __init eeh_init(void); 42void __init eeh_init(void);
41unsigned long eeh_check_failure(const volatile void __iomem *token, 43unsigned long eeh_check_failure(const volatile void __iomem *token,
42 unsigned long val); 44 unsigned long val);
@@ -59,36 +61,14 @@ void eeh_add_device_late(struct pci_dev *);
59 * eeh_remove_device - undo EEH setup for the indicated pci device 61 * eeh_remove_device - undo EEH setup for the indicated pci device
60 * @dev: pci device to be removed 62 * @dev: pci device to be removed
61 * 63 *
62 * This routine should be when a device is removed from a running 64 * This routine should be called when a device is removed from
63 * system (e.g. by hotplug or dlpar). 65 * a running system (e.g. by hotplug or dlpar). It unregisters
66 * the PCI device from the EEH subsystem. I/O errors affecting
67 * this device will no longer be detected after this call; thus,
68 * i/o errors affecting this slot may leave this device unusable.
64 */ 69 */
65void eeh_remove_device(struct pci_dev *); 70void eeh_remove_device(struct pci_dev *);
66 71
67#define EEH_DISABLE 0
68#define EEH_ENABLE 1
69#define EEH_RELEASE_LOADSTORE 2
70#define EEH_RELEASE_DMA 3
71
72/**
73 * Notifier event flags.
74 */
75#define EEH_NOTIFY_FREEZE 1
76
77/** EEH event -- structure holding pci slot data that describes
78 * a change in the isolation status of a PCI slot. A pointer
79 * to this struct is passed as the data pointer in a notify callback.
80 */
81struct eeh_event {
82 struct list_head list;
83 struct pci_dev *dev;
84 struct device_node *dn;
85 int reset_state;
86};
87
88/** Register to find out about EEH events. */
89int eeh_register_notifier(struct notifier_block *nb);
90int eeh_unregister_notifier(struct notifier_block *nb);
91
92/** 72/**
93 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. 73 * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
94 * 74 *
@@ -129,7 +109,7 @@ static inline void eeh_remove_device(struct pci_dev *dev) { }
129#define EEH_IO_ERROR_VALUE(size) (-1UL) 109#define EEH_IO_ERROR_VALUE(size) (-1UL)
130#endif /* CONFIG_EEH */ 110#endif /* CONFIG_EEH */
131 111
132/* 112/*
133 * MMIO read/write operations with EEH support. 113 * MMIO read/write operations with EEH support.
134 */ 114 */
135static inline u8 eeh_readb(const volatile void __iomem *addr) 115static inline u8 eeh_readb(const volatile void __iomem *addr)
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index 4c18a5cb69f5..1a7e0afa2dc6 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -14,7 +14,7 @@
14#define _PPC64_MMU_H_ 14#define _PPC64_MMU_H_
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17#include <asm/ppc_asm.h> /* for ASM_CONST */ 17#include <asm/asm-compat.h>
18#include <asm/page.h> 18#include <asm/page.h>
19 19
20/* 20/*
@@ -224,9 +224,12 @@ extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
224 unsigned long pstart, unsigned long mode, 224 unsigned long pstart, unsigned long mode,
225 int psize); 225 int psize);
226 226
227extern void htab_initialize(void);
228extern void htab_initialize_secondary(void);
227extern void hpte_init_native(void); 229extern void hpte_init_native(void);
228extern void hpte_init_lpar(void); 230extern void hpte_init_lpar(void);
229extern void hpte_init_iSeries(void); 231extern void hpte_init_iSeries(void);
232extern void mm_init_ppc64(void);
230 233
231extern long pSeries_lpar_hpte_insert(unsigned long hpte_group, 234extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
232 unsigned long va, unsigned long prpn, 235 unsigned long va, unsigned long prpn,
@@ -245,6 +248,7 @@ extern long iSeries_hpte_insert(unsigned long hpte_group,
245 248
246extern void stabs_alloc(void); 249extern void stabs_alloc(void);
247extern void slb_initialize(void); 250extern void slb_initialize(void);
251extern void stab_initialize(unsigned long stab);
248 252
249#endif /* __ASSEMBLY__ */ 253#endif /* __ASSEMBLY__ */
250 254
diff --git a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
index 80a708e7093a..54958d6cae04 100644
--- a/include/asm-ppc64/mmzone.h
+++ b/include/asm-ppc64/mmzone.h
@@ -8,15 +8,14 @@
8#define _ASM_MMZONE_H_ 8#define _ASM_MMZONE_H_
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <asm/smp.h>
12 11
13/* generic non-linear memory support: 12/*
13 * generic non-linear memory support:
14 * 14 *
15 * 1) we will not split memory into more chunks than will fit into the 15 * 1) we will not split memory into more chunks than will fit into the
16 * flags field of the struct page 16 * flags field of the struct page
17 */ 17 */
18 18
19
20#ifdef CONFIG_NEED_MULTIPLE_NODES 19#ifdef CONFIG_NEED_MULTIPLE_NODES
21 20
22extern struct pglist_data *node_data[]; 21extern struct pglist_data *node_data[];
@@ -30,36 +29,11 @@ extern struct pglist_data *node_data[];
30 */ 29 */
31 30
32extern int numa_cpu_lookup_table[]; 31extern int numa_cpu_lookup_table[];
33extern char *numa_memory_lookup_table;
34extern cpumask_t numa_cpumask_lookup_table[]; 32extern cpumask_t numa_cpumask_lookup_table[];
35extern int nr_cpus_in_node[]; 33#ifdef CONFIG_MEMORY_HOTPLUG
36 34extern unsigned long max_pfn;
37/* 16MB regions */
38#define MEMORY_INCREMENT_SHIFT 24
39#define MEMORY_INCREMENT (1UL << MEMORY_INCREMENT_SHIFT)
40
41/* NUMA debugging, will not work on a DLPAR machine */
42#undef DEBUG_NUMA
43
44static inline int pa_to_nid(unsigned long pa)
45{
46 int nid;
47
48 nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT];
49
50#ifdef DEBUG_NUMA
51 /* the physical address passed in is not in the map for the system */
52 if (nid == -1) {
53 printk("bad address: %lx\n", pa);
54 BUG();
55 }
56#endif 35#endif
57 36
58 return nid;
59}
60
61#define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn)
62
63/* 37/*
64 * Following are macros that each numa implmentation must define. 38 * Following are macros that each numa implmentation must define.
65 */ 39 */
@@ -67,39 +41,10 @@ static inline int pa_to_nid(unsigned long pa)
67#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 41#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
68#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn) 42#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn)
69 43
70#ifdef CONFIG_DISCONTIGMEM
71
72/*
73 * Given a kernel address, find the home node of the underlying memory.
74 */
75#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
76
77#define pfn_to_nid(pfn) pa_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
78
79/* Written this way to avoid evaluating arguments twice */
80#define discontigmem_pfn_to_page(pfn) \
81({ \
82 unsigned long __tmp = pfn; \
83 (NODE_DATA(pfn_to_nid(__tmp))->node_mem_map + \
84 node_localnr(__tmp, pfn_to_nid(__tmp))); \
85})
86
87#define discontigmem_page_to_pfn(p) \
88({ \
89 struct page *__tmp = p; \
90 (((__tmp) - page_zone(__tmp)->zone_mem_map) + \
91 page_zone(__tmp)->zone_start_pfn); \
92})
93
94/* XXX fix for discontiguous physical memory */
95#define discontigmem_pfn_valid(pfn) ((pfn) < num_physpages)
96
97#endif /* CONFIG_DISCONTIGMEM */
98
99#endif /* CONFIG_NEED_MULTIPLE_NODES */ 44#endif /* CONFIG_NEED_MULTIPLE_NODES */
100 45
101#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID 46#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
102#define early_pfn_to_nid(pfn) pa_to_nid(((unsigned long)pfn) << PAGE_SHIFT) 47extern int __init early_pfn_to_nid(unsigned long pfn);
103#endif 48#endif
104 49
105#endif /* _ASM_MMZONE_H_ */ 50#endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
index 82ce187e5be8..3efc3288f7e9 100644
--- a/include/asm-ppc64/page.h
+++ b/include/asm-ppc64/page.h
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include <linux/config.h> 13#include <linux/config.h>
14#include <asm/ppc_asm.h> /* for ASM_CONST */ 14#include <asm/asm-compat.h>
15 15
16/* 16/*
17 * We support either 4k or 64k software page size. When using 64k pages 17 * We support either 4k or 64k software page size. When using 64k pages
@@ -279,11 +279,6 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */
279 279
280#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) 280#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
281 281
282#ifdef CONFIG_DISCONTIGMEM
283#define page_to_pfn(page) discontigmem_page_to_pfn(page)
284#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
285#define pfn_valid(pfn) discontigmem_pfn_valid(pfn)
286#endif
287#ifdef CONFIG_FLATMEM 282#ifdef CONFIG_FLATMEM
288#define pfn_to_page(pfn) (mem_map + (pfn)) 283#define pfn_to_page(pfn) (mem_map + (pfn))
289#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) 284#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
index 60cf8c838af0..efbdaece0cf0 100644
--- a/include/asm-ppc64/pci-bridge.h
+++ b/include/asm-ppc64/pci-bridge.h
@@ -63,7 +63,6 @@ struct pci_dn {
63 int devfn; /* for pci devices */ 63 int devfn; /* for pci devices */
64 int eeh_mode; /* See eeh.h for possible EEH_MODEs */ 64 int eeh_mode; /* See eeh.h for possible EEH_MODEs */
65 int eeh_config_addr; 65 int eeh_config_addr;
66 int eeh_capable; /* from firmware */
67 int eeh_check_count; /* # times driver ignored error */ 66 int eeh_check_count; /* # times driver ignored error */
68 int eeh_freeze_count; /* # times this device froze up. */ 67 int eeh_freeze_count; /* # times this device froze up. */
69 int eeh_is_bridge; /* device is pci-to-pci bridge */ 68 int eeh_is_bridge; /* device is pci-to-pci bridge */
diff --git a/include/asm-ppc64/pgalloc.h b/include/asm-ppc64/pgalloc.h
index 98da0e4262bd..dcf3622d1946 100644
--- a/include/asm-ppc64/pgalloc.h
+++ b/include/asm-ppc64/pgalloc.h
@@ -10,8 +10,8 @@ extern kmem_cache_t *pgtable_cache[];
10 10
11#ifdef CONFIG_PPC_64K_PAGES 11#ifdef CONFIG_PPC_64K_PAGES
12#define PTE_CACHE_NUM 0 12#define PTE_CACHE_NUM 0
13#define PMD_CACHE_NUM 0 13#define PMD_CACHE_NUM 1
14#define PGD_CACHE_NUM 1 14#define PGD_CACHE_NUM 2
15#else 15#else
16#define PTE_CACHE_NUM 0 16#define PTE_CACHE_NUM 0
17#define PMD_CACHE_NUM 1 17#define PMD_CACHE_NUM 1
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index 76bb0266d67c..ddfe186589fa 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -204,6 +204,8 @@ extern void of_detach_node(const struct device_node *);
204extern unsigned long prom_init(unsigned long, unsigned long, unsigned long, 204extern unsigned long prom_init(unsigned long, unsigned long, unsigned long,
205 unsigned long, unsigned long); 205 unsigned long, unsigned long);
206extern void finish_device_tree(void); 206extern void finish_device_tree(void);
207extern void unflatten_device_tree(void);
208extern void early_init_devtree(void *);
207extern int device_is_compatible(struct device_node *device, const char *); 209extern int device_is_compatible(struct device_node *device, const char *);
208extern int machine_is_compatible(const char *compat); 210extern int machine_is_compatible(const char *compat);
209extern unsigned char *get_property(struct device_node *node, const char *name, 211extern unsigned char *get_property(struct device_node *node, const char *name,
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
deleted file mode 100644
index 432df7dd355d..000000000000
--- a/include/asm-ppc64/signal.h
+++ /dev/null
@@ -1,132 +0,0 @@
1#ifndef _ASMPPC64_SIGNAL_H
2#define _ASMPPC64_SIGNAL_H
3
4#include <linux/types.h>
5#include <linux/compiler.h>
6#include <asm/siginfo.h>
7
8/* Avoid too many header ordering problems. */
9struct siginfo;
10
11#define _NSIG 64
12#define _NSIG_BPW 64
13#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
14
15typedef unsigned long old_sigset_t; /* at least 32 bits */
16
17typedef struct {
18 unsigned long sig[_NSIG_WORDS];
19} sigset_t;
20
21#define SIGHUP 1
22#define SIGINT 2
23#define SIGQUIT 3
24#define SIGILL 4
25#define SIGTRAP 5
26#define SIGABRT 6
27#define SIGIOT 6
28#define SIGBUS 7
29#define SIGFPE 8
30#define SIGKILL 9
31#define SIGUSR1 10
32#define SIGSEGV 11
33#define SIGUSR2 12
34#define SIGPIPE 13
35#define SIGALRM 14
36#define SIGTERM 15
37#define SIGSTKFLT 16
38#define SIGCHLD 17
39#define SIGCONT 18
40#define SIGSTOP 19
41#define SIGTSTP 20
42#define SIGTTIN 21
43#define SIGTTOU 22
44#define SIGURG 23
45#define SIGXCPU 24
46#define SIGXFSZ 25
47#define SIGVTALRM 26
48#define SIGPROF 27
49#define SIGWINCH 28
50#define SIGIO 29
51#define SIGPOLL SIGIO
52/*
53#define SIGLOST 29
54*/
55#define SIGPWR 30
56#define SIGSYS 31
57#define SIGUNUSED 31
58
59/* These should not be considered constants from userland. */
60#define SIGRTMIN 32
61#define SIGRTMAX _NSIG
62
63/*
64 * SA_FLAGS values:
65 *
66 * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
67 * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
68 * SA_RESTART flag to get restarting signals (which were the default long ago)
69 * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
70 * SA_RESETHAND clears the handler when the signal is delivered.
71 * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
72 * SA_NODEFER prevents the current signal from being masked in the handler.
73 *
74 * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
75 * Unix names RESETHAND and NODEFER respectively.
76 */
77#define SA_NOCLDSTOP 0x00000001u
78#define SA_NOCLDWAIT 0x00000002u
79#define SA_SIGINFO 0x00000004u
80#define SA_ONSTACK 0x08000000u
81#define SA_RESTART 0x10000000u
82#define SA_NODEFER 0x40000000u
83#define SA_RESETHAND 0x80000000u
84
85#define SA_NOMASK SA_NODEFER
86#define SA_ONESHOT SA_RESETHAND
87#define SA_INTERRUPT 0x20000000u /* dummy -- ignored */
88
89#define SA_RESTORER 0x04000000u
90
91/*
92 * sigaltstack controls
93 */
94#define SS_ONSTACK 1
95#define SS_DISABLE 2
96
97#define MINSIGSTKSZ 2048
98#define SIGSTKSZ 8192
99
100#include <asm-generic/signal.h>
101
102struct old_sigaction {
103 __sighandler_t sa_handler;
104 old_sigset_t sa_mask;
105 unsigned long sa_flags;
106 __sigrestore_t sa_restorer;
107};
108
109struct sigaction {
110 __sighandler_t sa_handler;
111 unsigned long sa_flags;
112 __sigrestore_t sa_restorer;
113 sigset_t sa_mask; /* mask last for extensibility */
114};
115
116struct k_sigaction {
117 struct sigaction sa;
118};
119
120typedef struct sigaltstack {
121 void __user *ss_sp;
122 int ss_flags;
123 size_t ss_size;
124} stack_t;
125
126struct pt_regs;
127struct timespec;
128extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
129extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
130#define ptrace_signal_deliver(regs, cookie) do { } while (0)
131
132#endif /* _ASMPPC64_SIGNAL_H */
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
index 0cdd66c9f4b7..bf9a6aba19c9 100644
--- a/include/asm-ppc64/system.h
+++ b/include/asm-ppc64/system.h
@@ -149,6 +149,8 @@ struct thread_struct;
149extern struct task_struct * _switch(struct thread_struct *prev, 149extern struct task_struct * _switch(struct thread_struct *prev,
150 struct thread_struct *next); 150 struct thread_struct *next);
151 151
152extern unsigned long klimit;
153
152extern int powersave_nap; /* set if nap mode can be used in idle loop */ 154extern int powersave_nap; /* set if nap mode can be used in idle loop */
153 155
154/* 156/*
diff --git a/include/asm-ppc64/systemcfg.h b/include/asm-ppc64/systemcfg.h
deleted file mode 100644
index 9b86b53129aa..000000000000
--- a/include/asm-ppc64/systemcfg.h
+++ /dev/null
@@ -1,64 +0,0 @@
1#ifndef _SYSTEMCFG_H
2#define _SYSTEMCFG_H
3
4/*
5 * Copyright (C) 2002 Peter Bergner <bergner@vnet.ibm.com>, IBM
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13/* Change Activity:
14 * 2002/09/30 : bergner : Created
15 * End Change Activity
16 */
17
18/*
19 * If the major version changes we are incompatible.
20 * Minor version changes are a hint.
21 */
22#define SYSTEMCFG_MAJOR 1
23#define SYSTEMCFG_MINOR 1
24
25#ifndef __ASSEMBLY__
26
27#include <linux/unistd.h>
28
29#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32)
30
31struct systemcfg {
32 __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */
33 struct { /* Systemcfg version numbers */
34 __u32 major; /* Major number 0x10 */
35 __u32 minor; /* Minor number 0x14 */
36 } version;
37
38 __u32 platform; /* Platform flags 0x18 */
39 __u32 processor; /* Processor type 0x1C */
40 __u64 processorCount; /* # of physical processors 0x20 */
41 __u64 physicalMemorySize; /* Size of real memory(B) 0x28 */
42 __u64 tb_orig_stamp; /* Timebase at boot 0x30 */
43 __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */
44 __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */
45 __u64 stamp_xsec; /* 0x48 */
46 __u64 tb_update_count; /* Timebase atomicity ctr 0x50 */
47 __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */
48 __u32 tz_dsttime; /* Type of dst correction 0x5C */
49 /* next four are no longer used except to be exported to /proc */
50 __u32 dcache_size; /* L1 d-cache size 0x60 */
51 __u32 dcache_line_size; /* L1 d-cache line size 0x64 */
52 __u32 icache_size; /* L1 i-cache size 0x68 */
53 __u32 icache_line_size; /* L1 i-cache line size 0x6C */
54 __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of available syscalls 0x70 */
55 __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of available syscalls */
56};
57
58#ifdef __KERNEL__
59extern struct systemcfg *systemcfg;
60#endif
61
62#endif /* __ASSEMBLY__ */
63
64#endif /* _SYSTEMCFG_H */
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h
index 7127030ae162..23450ed4b571 100644
--- a/include/asm-s390/debug.h
+++ b/include/asm-s390/debug.h
@@ -129,7 +129,7 @@ void debug_set_level(debug_info_t* id, int new_level);
129 129
130void debug_stop_all(void); 130void debug_stop_all(void);
131 131
132extern inline debug_entry_t* 132static inline debug_entry_t*
133debug_event(debug_info_t* id, int level, void* data, int length) 133debug_event(debug_info_t* id, int level, void* data, int length)
134{ 134{
135 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 135 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -137,7 +137,7 @@ debug_event(debug_info_t* id, int level, void* data, int length)
137 return debug_event_common(id,level,data,length); 137 return debug_event_common(id,level,data,length);
138} 138}
139 139
140extern inline debug_entry_t* 140static inline debug_entry_t*
141debug_int_event(debug_info_t* id, int level, unsigned int tag) 141debug_int_event(debug_info_t* id, int level, unsigned int tag)
142{ 142{
143 unsigned int t=tag; 143 unsigned int t=tag;
@@ -146,7 +146,7 @@ debug_int_event(debug_info_t* id, int level, unsigned int tag)
146 return debug_event_common(id,level,&t,sizeof(unsigned int)); 146 return debug_event_common(id,level,&t,sizeof(unsigned int));
147} 147}
148 148
149extern inline debug_entry_t * 149static inline debug_entry_t *
150debug_long_event (debug_info_t* id, int level, unsigned long tag) 150debug_long_event (debug_info_t* id, int level, unsigned long tag)
151{ 151{
152 unsigned long t=tag; 152 unsigned long t=tag;
@@ -155,7 +155,7 @@ debug_long_event (debug_info_t* id, int level, unsigned long tag)
155 return debug_event_common(id,level,&t,sizeof(unsigned long)); 155 return debug_event_common(id,level,&t,sizeof(unsigned long));
156} 156}
157 157
158extern inline debug_entry_t* 158static inline debug_entry_t*
159debug_text_event(debug_info_t* id, int level, const char* txt) 159debug_text_event(debug_info_t* id, int level, const char* txt)
160{ 160{
161 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 161 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -168,7 +168,7 @@ debug_sprintf_event(debug_info_t* id,int level,char *string,...)
168 __attribute__ ((format(printf, 3, 4))); 168 __attribute__ ((format(printf, 3, 4)));
169 169
170 170
171extern inline debug_entry_t* 171static inline debug_entry_t*
172debug_exception(debug_info_t* id, int level, void* data, int length) 172debug_exception(debug_info_t* id, int level, void* data, int length)
173{ 173{
174 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 174 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -176,7 +176,7 @@ debug_exception(debug_info_t* id, int level, void* data, int length)
176 return debug_exception_common(id,level,data,length); 176 return debug_exception_common(id,level,data,length);
177} 177}
178 178
179extern inline debug_entry_t* 179static inline debug_entry_t*
180debug_int_exception(debug_info_t* id, int level, unsigned int tag) 180debug_int_exception(debug_info_t* id, int level, unsigned int tag)
181{ 181{
182 unsigned int t=tag; 182 unsigned int t=tag;
@@ -185,7 +185,7 @@ debug_int_exception(debug_info_t* id, int level, unsigned int tag)
185 return debug_exception_common(id,level,&t,sizeof(unsigned int)); 185 return debug_exception_common(id,level,&t,sizeof(unsigned int));
186} 186}
187 187
188extern inline debug_entry_t * 188static inline debug_entry_t *
189debug_long_exception (debug_info_t* id, int level, unsigned long tag) 189debug_long_exception (debug_info_t* id, int level, unsigned long tag)
190{ 190{
191 unsigned long t=tag; 191 unsigned long t=tag;
@@ -194,7 +194,7 @@ debug_long_exception (debug_info_t* id, int level, unsigned long tag)
194 return debug_exception_common(id,level,&t,sizeof(unsigned long)); 194 return debug_exception_common(id,level,&t,sizeof(unsigned long));
195} 195}
196 196
197extern inline debug_entry_t* 197static inline debug_entry_t*
198debug_text_exception(debug_info_t* id, int level, const char* txt) 198debug_text_exception(debug_info_t* id, int level, const char* txt)
199{ 199{
200 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 200 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
diff --git a/include/asm-s390/ebcdic.h b/include/asm-s390/ebcdic.h
index 20e81e885821..4cbc336e4d60 100644
--- a/include/asm-s390/ebcdic.h
+++ b/include/asm-s390/ebcdic.h
@@ -21,7 +21,7 @@ extern __u8 _ebcasc[]; /* EBCDIC -> ASCII conversion table */
21extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */ 21extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */
22extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */ 22extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */
23 23
24extern __inline__ void 24static inline void
25codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr) 25codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
26{ 26{
27 if (nr-- <= 0) 27 if (nr-- <= 0)
diff --git a/include/asm-s390/io.h b/include/asm-s390/io.h
index 8188fdc9884f..71f55eb2350a 100644
--- a/include/asm-s390/io.h
+++ b/include/asm-s390/io.h
@@ -24,7 +24,7 @@
24 * Change virtual addresses to physical addresses and vv. 24 * Change virtual addresses to physical addresses and vv.
25 * These are pretty trivial 25 * These are pretty trivial
26 */ 26 */
27extern inline unsigned long virt_to_phys(volatile void * address) 27static inline unsigned long virt_to_phys(volatile void * address)
28{ 28{
29 unsigned long real_address; 29 unsigned long real_address;
30 __asm__ ( 30 __asm__ (
@@ -42,7 +42,7 @@ extern inline unsigned long virt_to_phys(volatile void * address)
42 return real_address; 42 return real_address;
43} 43}
44 44
45extern inline void * phys_to_virt(unsigned long address) 45static inline void * phys_to_virt(unsigned long address)
46{ 46{
47 return __io_virt(address); 47 return __io_virt(address);
48} 48}
@@ -54,7 +54,7 @@ extern inline void * phys_to_virt(unsigned long address)
54 54
55extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); 55extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
56 56
57extern inline void * ioremap (unsigned long offset, unsigned long size) 57static inline void * ioremap (unsigned long offset, unsigned long size)
58{ 58{
59 return __ioremap(offset, size, 0); 59 return __ioremap(offset, size, 0);
60} 60}
@@ -64,7 +64,7 @@ extern inline void * ioremap (unsigned long offset, unsigned long size)
64 * it's useful if some control registers are in such an area and write combining 64 * it's useful if some control registers are in such an area and write combining
65 * or read caching is not desirable: 65 * or read caching is not desirable:
66 */ 66 */
67extern inline void * ioremap_nocache (unsigned long offset, unsigned long size) 67static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
68{ 68{
69 return __ioremap(offset, size, 0); 69 return __ioremap(offset, size, 0);
70} 70}
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index c6f51c9ce3ff..db0606c1abd4 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -346,7 +346,7 @@ struct _lowcore
346#define S390_lowcore (*((struct _lowcore *) 0)) 346#define S390_lowcore (*((struct _lowcore *) 0))
347extern struct _lowcore *lowcore_ptr[]; 347extern struct _lowcore *lowcore_ptr[];
348 348
349extern __inline__ void set_prefix(__u32 address) 349static inline void set_prefix(__u32 address)
350{ 350{
351 __asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" ); 351 __asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" );
352} 352}
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h
index 3a3bb3f2dad5..bcf24a873874 100644
--- a/include/asm-s390/mmu_context.h
+++ b/include/asm-s390/mmu_context.h
@@ -44,7 +44,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
44 44
45#define deactivate_mm(tsk,mm) do { } while (0) 45#define deactivate_mm(tsk,mm) do { } while (0)
46 46
47extern inline void activate_mm(struct mm_struct *prev, 47static inline void activate_mm(struct mm_struct *prev,
48 struct mm_struct *next) 48 struct mm_struct *next)
49{ 49{
50 switch_mm(prev, next, current); 50 switch_mm(prev, next, current);
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 9be741bb1496..859b5e969826 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -319,7 +319,7 @@ extern char empty_zero_page[PAGE_SIZE];
319 * within a page table are directly modified. Thus, the following 319 * within a page table are directly modified. Thus, the following
320 * hook is made available. 320 * hook is made available.
321 */ 321 */
322extern inline void set_pte(pte_t *pteptr, pte_t pteval) 322static inline void set_pte(pte_t *pteptr, pte_t pteval)
323{ 323{
324 *pteptr = pteval; 324 *pteptr = pteval;
325} 325}
@@ -330,63 +330,63 @@ extern inline void set_pte(pte_t *pteptr, pte_t pteval)
330 */ 330 */
331#ifndef __s390x__ 331#ifndef __s390x__
332 332
333extern inline int pgd_present(pgd_t pgd) { return 1; } 333static inline int pgd_present(pgd_t pgd) { return 1; }
334extern inline int pgd_none(pgd_t pgd) { return 0; } 334static inline int pgd_none(pgd_t pgd) { return 0; }
335extern inline int pgd_bad(pgd_t pgd) { return 0; } 335static inline int pgd_bad(pgd_t pgd) { return 0; }
336 336
337extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; } 337static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
338extern inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; } 338static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; }
339extern inline int pmd_bad(pmd_t pmd) 339static inline int pmd_bad(pmd_t pmd)
340{ 340{
341 return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE; 341 return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
342} 342}
343 343
344#else /* __s390x__ */ 344#else /* __s390x__ */
345 345
346extern inline int pgd_present(pgd_t pgd) 346static inline int pgd_present(pgd_t pgd)
347{ 347{
348 return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY; 348 return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
349} 349}
350 350
351extern inline int pgd_none(pgd_t pgd) 351static inline int pgd_none(pgd_t pgd)
352{ 352{
353 return pgd_val(pgd) & _PGD_ENTRY_INV; 353 return pgd_val(pgd) & _PGD_ENTRY_INV;
354} 354}
355 355
356extern inline int pgd_bad(pgd_t pgd) 356static inline int pgd_bad(pgd_t pgd)
357{ 357{
358 return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY; 358 return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
359} 359}
360 360
361extern inline int pmd_present(pmd_t pmd) 361static inline int pmd_present(pmd_t pmd)
362{ 362{
363 return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY; 363 return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
364} 364}
365 365
366extern inline int pmd_none(pmd_t pmd) 366static inline int pmd_none(pmd_t pmd)
367{ 367{
368 return pmd_val(pmd) & _PMD_ENTRY_INV; 368 return pmd_val(pmd) & _PMD_ENTRY_INV;
369} 369}
370 370
371extern inline int pmd_bad(pmd_t pmd) 371static inline int pmd_bad(pmd_t pmd)
372{ 372{
373 return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY; 373 return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
374} 374}
375 375
376#endif /* __s390x__ */ 376#endif /* __s390x__ */
377 377
378extern inline int pte_none(pte_t pte) 378static inline int pte_none(pte_t pte)
379{ 379{
380 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY; 380 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY;
381} 381}
382 382
383extern inline int pte_present(pte_t pte) 383static inline int pte_present(pte_t pte)
384{ 384{
385 return !(pte_val(pte) & _PAGE_INVALID) || 385 return !(pte_val(pte) & _PAGE_INVALID) ||
386 (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE; 386 (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE;
387} 387}
388 388
389extern inline int pte_file(pte_t pte) 389static inline int pte_file(pte_t pte)
390{ 390{
391 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE; 391 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE;
392} 392}
@@ -397,12 +397,12 @@ extern inline int pte_file(pte_t pte)
397 * query functions pte_write/pte_dirty/pte_young only work if 397 * query functions pte_write/pte_dirty/pte_young only work if
398 * pte_present() is true. Undefined behaviour if not.. 398 * pte_present() is true. Undefined behaviour if not..
399 */ 399 */
400extern inline int pte_write(pte_t pte) 400static inline int pte_write(pte_t pte)
401{ 401{
402 return (pte_val(pte) & _PAGE_RO) == 0; 402 return (pte_val(pte) & _PAGE_RO) == 0;
403} 403}
404 404
405extern inline int pte_dirty(pte_t pte) 405static inline int pte_dirty(pte_t pte)
406{ 406{
407 /* A pte is neither clean nor dirty on s/390. The dirty bit 407 /* A pte is neither clean nor dirty on s/390. The dirty bit
408 * is in the storage key. See page_test_and_clear_dirty for 408 * is in the storage key. See page_test_and_clear_dirty for
@@ -411,7 +411,7 @@ extern inline int pte_dirty(pte_t pte)
411 return 0; 411 return 0;
412} 412}
413 413
414extern inline int pte_young(pte_t pte) 414static inline int pte_young(pte_t pte)
415{ 415{
416 /* A pte is neither young nor old on s/390. The young bit 416 /* A pte is neither young nor old on s/390. The young bit
417 * is in the storage key. See page_test_and_clear_young for 417 * is in the storage key. See page_test_and_clear_young for
@@ -420,7 +420,7 @@ extern inline int pte_young(pte_t pte)
420 return 0; 420 return 0;
421} 421}
422 422
423extern inline int pte_read(pte_t pte) 423static inline int pte_read(pte_t pte)
424{ 424{
425 /* All pages are readable since we don't use the fetch 425 /* All pages are readable since we don't use the fetch
426 * protection bit in the storage key. 426 * protection bit in the storage key.
@@ -434,9 +434,9 @@ extern inline int pte_read(pte_t pte)
434 434
435#ifndef __s390x__ 435#ifndef __s390x__
436 436
437extern inline void pgd_clear(pgd_t * pgdp) { } 437static inline void pgd_clear(pgd_t * pgdp) { }
438 438
439extern inline void pmd_clear(pmd_t * pmdp) 439static inline void pmd_clear(pmd_t * pmdp)
440{ 440{
441 pmd_val(pmdp[0]) = _PAGE_TABLE_INV; 441 pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
442 pmd_val(pmdp[1]) = _PAGE_TABLE_INV; 442 pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
@@ -446,12 +446,12 @@ extern inline void pmd_clear(pmd_t * pmdp)
446 446
447#else /* __s390x__ */ 447#else /* __s390x__ */
448 448
449extern inline void pgd_clear(pgd_t * pgdp) 449static inline void pgd_clear(pgd_t * pgdp)
450{ 450{
451 pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY; 451 pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
452} 452}
453 453
454extern inline void pmd_clear(pmd_t * pmdp) 454static inline void pmd_clear(pmd_t * pmdp)
455{ 455{
456 pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY; 456 pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
457 pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY; 457 pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
@@ -459,7 +459,7 @@ extern inline void pmd_clear(pmd_t * pmdp)
459 459
460#endif /* __s390x__ */ 460#endif /* __s390x__ */
461 461
462extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 462static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
463{ 463{
464 pte_val(*ptep) = _PAGE_INVALID_EMPTY; 464 pte_val(*ptep) = _PAGE_INVALID_EMPTY;
465} 465}
@@ -468,14 +468,14 @@ extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
468 * The following pte modification functions only work if 468 * The following pte modification functions only work if
469 * pte_present() is true. Undefined behaviour if not.. 469 * pte_present() is true. Undefined behaviour if not..
470 */ 470 */
471extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 471static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
472{ 472{
473 pte_val(pte) &= PAGE_MASK; 473 pte_val(pte) &= PAGE_MASK;
474 pte_val(pte) |= pgprot_val(newprot); 474 pte_val(pte) |= pgprot_val(newprot);
475 return pte; 475 return pte;
476} 476}
477 477
478extern inline pte_t pte_wrprotect(pte_t pte) 478static inline pte_t pte_wrprotect(pte_t pte)
479{ 479{
480 /* Do not clobber _PAGE_INVALID_NONE pages! */ 480 /* Do not clobber _PAGE_INVALID_NONE pages! */
481 if (!(pte_val(pte) & _PAGE_INVALID)) 481 if (!(pte_val(pte) & _PAGE_INVALID))
@@ -483,13 +483,13 @@ extern inline pte_t pte_wrprotect(pte_t pte)
483 return pte; 483 return pte;
484} 484}
485 485
486extern inline pte_t pte_mkwrite(pte_t pte) 486static inline pte_t pte_mkwrite(pte_t pte)
487{ 487{
488 pte_val(pte) &= ~_PAGE_RO; 488 pte_val(pte) &= ~_PAGE_RO;
489 return pte; 489 return pte;
490} 490}
491 491
492extern inline pte_t pte_mkclean(pte_t pte) 492static inline pte_t pte_mkclean(pte_t pte)
493{ 493{
494 /* The only user of pte_mkclean is the fork() code. 494 /* The only user of pte_mkclean is the fork() code.
495 We must *not* clear the *physical* page dirty bit 495 We must *not* clear the *physical* page dirty bit
@@ -498,7 +498,7 @@ extern inline pte_t pte_mkclean(pte_t pte)
498 return pte; 498 return pte;
499} 499}
500 500
501extern inline pte_t pte_mkdirty(pte_t pte) 501static inline pte_t pte_mkdirty(pte_t pte)
502{ 502{
503 /* We do not explicitly set the dirty bit because the 503 /* We do not explicitly set the dirty bit because the
504 * sske instruction is slow. It is faster to let the 504 * sske instruction is slow. It is faster to let the
@@ -507,7 +507,7 @@ extern inline pte_t pte_mkdirty(pte_t pte)
507 return pte; 507 return pte;
508} 508}
509 509
510extern inline pte_t pte_mkold(pte_t pte) 510static inline pte_t pte_mkold(pte_t pte)
511{ 511{
512 /* S/390 doesn't keep its dirty/referenced bit in the pte. 512 /* S/390 doesn't keep its dirty/referenced bit in the pte.
513 * There is no point in clearing the real referenced bit. 513 * There is no point in clearing the real referenced bit.
@@ -515,7 +515,7 @@ extern inline pte_t pte_mkold(pte_t pte)
515 return pte; 515 return pte;
516} 516}
517 517
518extern inline pte_t pte_mkyoung(pte_t pte) 518static inline pte_t pte_mkyoung(pte_t pte)
519{ 519{
520 /* S/390 doesn't keep its dirty/referenced bit in the pte. 520 /* S/390 doesn't keep its dirty/referenced bit in the pte.
521 * There is no point in setting the real referenced bit. 521 * There is no point in setting the real referenced bit.
@@ -695,7 +695,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
695#ifndef __s390x__ 695#ifndef __s390x__
696 696
697/* Find an entry in the second-level page table.. */ 697/* Find an entry in the second-level page table.. */
698extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) 698static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
699{ 699{
700 return (pmd_t *) dir; 700 return (pmd_t *) dir;
701} 701}
@@ -758,7 +758,7 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
758#else 758#else
759#define __SWP_OFFSET_MASK (~0UL >> 11) 759#define __SWP_OFFSET_MASK (~0UL >> 11)
760#endif 760#endif
761extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) 761static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
762{ 762{
763 pte_t pte; 763 pte_t pte;
764 offset &= __SWP_OFFSET_MASK; 764 offset &= __SWP_OFFSET_MASK;
diff --git a/include/asm-s390/sigp.h b/include/asm-s390/sigp.h
index 3979bc3858e2..fc56458aff66 100644
--- a/include/asm-s390/sigp.h
+++ b/include/asm-s390/sigp.h
@@ -67,7 +67,7 @@ typedef enum
67/* 67/*
68 * Signal processor 68 * Signal processor
69 */ 69 */
70extern __inline__ sigp_ccode 70static inline sigp_ccode
71signal_processor(__u16 cpu_addr, sigp_order_code order_code) 71signal_processor(__u16 cpu_addr, sigp_order_code order_code)
72{ 72{
73 sigp_ccode ccode; 73 sigp_ccode ccode;
@@ -86,7 +86,7 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code)
86/* 86/*
87 * Signal processor with parameter 87 * Signal processor with parameter
88 */ 88 */
89extern __inline__ sigp_ccode 89static inline sigp_ccode
90signal_processor_p(__u32 parameter, __u16 cpu_addr, 90signal_processor_p(__u32 parameter, __u16 cpu_addr,
91 sigp_order_code order_code) 91 sigp_order_code order_code)
92{ 92{
@@ -107,7 +107,7 @@ signal_processor_p(__u32 parameter, __u16 cpu_addr,
107/* 107/*
108 * Signal processor with parameter and return status 108 * Signal processor with parameter and return status
109 */ 109 */
110extern __inline__ sigp_ccode 110static inline sigp_ccode
111signal_processor_ps(__u32 *statusptr, __u32 parameter, 111signal_processor_ps(__u32 *statusptr, __u32 parameter,
112 __u16 cpu_addr, sigp_order_code order_code) 112 __u16 cpu_addr, sigp_order_code order_code)
113{ 113{
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index dd50e57a928f..a2ae7628bbaa 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -52,7 +52,7 @@ extern int smp_call_function_on(void (*func) (void *info), void *info,
52extern int smp_get_cpu(cpumask_t cpu_map); 52extern int smp_get_cpu(cpumask_t cpu_map);
53extern void smp_put_cpu(int cpu); 53extern void smp_put_cpu(int cpu);
54 54
55extern __inline__ __u16 hard_smp_processor_id(void) 55static inline __u16 hard_smp_processor_id(void)
56{ 56{
57 __u16 cpu_address; 57 __u16 cpu_address;
58 58
diff --git a/include/asm-sh/ide.h b/include/asm-sh/ide.h
index f42cf3977a57..711dad4cb48b 100644
--- a/include/asm-sh/ide.h
+++ b/include/asm-sh/ide.h
@@ -16,10 +16,6 @@
16 16
17#include <linux/config.h> 17#include <linux/config.h>
18 18
19#ifndef MAX_HWIFS
20#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
21#endif
22
23#define ide_default_io_ctl(base) (0) 19#define ide_default_io_ctl(base) (0)
24 20
25#include <asm-generic/ide_iops.h> 21#include <asm-generic/ide_iops.h>
diff --git a/include/asm-sh64/ide.h b/include/asm-sh64/ide.h
index 6fd514daa1ba..852f50afe39c 100644
--- a/include/asm-sh64/ide.h
+++ b/include/asm-sh64/ide.h
@@ -17,10 +17,6 @@
17 17
18#include <linux/config.h> 18#include <linux/config.h>
19 19
20#ifndef MAX_HWIFS
21#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
22#endif
23
24/* Without this, the initialisation of PCI IDE cards end up calling 20/* Without this, the initialisation of PCI IDE cards end up calling
25 * ide_init_hwif_ports, which won't work. */ 21 * ide_init_hwif_ports, which won't work. */
26#ifdef CONFIG_BLK_DEV_IDEPCI 22#ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-x86_64/msi.h b/include/asm-x86_64/msi.h
index 85c427e472bf..356e0e82f50b 100644
--- a/include/asm-x86_64/msi.h
+++ b/include/asm-x86_64/msi.h
@@ -11,8 +11,6 @@
11#include <asm/smp.h> 11#include <asm/smp.h>
12 12
13#define LAST_DEVICE_VECTOR 232 13#define LAST_DEVICE_VECTOR 232
14#define MSI_DEST_MODE MSI_LOGICAL_MODE 14#define MSI_TARGET_CPU_SHIFT 12
15#define MSI_TARGET_CPU_SHIFT 12
16#define MSI_TARGET_CPU logical_smp_processor_id()
17 15
18#endif /* ASM_MSI_H */ 16#endif /* ASM_MSI_H */
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index c57ce4071342..b9fb2173ef99 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -135,5 +135,11 @@ static __inline int logical_smp_processor_id(void)
135} 135}
136#endif 136#endif
137 137
138#ifdef CONFIG_SMP
139#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
140#else
141#define cpu_physical_id(cpu) boot_cpu_id
142#endif
143
138#endif 144#endif
139 145
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index ecb0d39c0798..2209ad3499a3 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -10,6 +10,10 @@
10#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl) 10#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)
11#endif 11#endif
12 12
13
14COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
15COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
16
13/* Big T */ 17/* Big T */
14COMPATIBLE_IOCTL(TCGETA) 18COMPATIBLE_IOCTL(TCGETA)
15COMPATIBLE_IOCTL(TCSETA) 19COMPATIBLE_IOCTL(TCSETA)
@@ -52,13 +56,6 @@ ULONG_IOCTL(TIOCSCTTY)
52COMPATIBLE_IOCTL(TIOCGPTN) 56COMPATIBLE_IOCTL(TIOCGPTN)
53COMPATIBLE_IOCTL(TIOCSPTLCK) 57COMPATIBLE_IOCTL(TIOCSPTLCK)
54COMPATIBLE_IOCTL(TIOCSERGETLSR) 58COMPATIBLE_IOCTL(TIOCSERGETLSR)
55/* Big F */
56COMPATIBLE_IOCTL(FBIOBLANK)
57COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
58COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
59COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
60COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
61COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
62/* Little f */ 59/* Little f */
63COMPATIBLE_IOCTL(FIOCLEX) 60COMPATIBLE_IOCTL(FIOCLEX)
64COMPATIBLE_IOCTL(FIONCLEX) 61COMPATIBLE_IOCTL(FIONCLEX)
@@ -81,6 +78,8 @@ COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
81COMPATIBLE_IOCTL(HDIO_DRIVE_TASK) 78COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
82COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE) 79COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
83COMPATIBLE_IOCTL(HDIO_SET_NICE) 80COMPATIBLE_IOCTL(HDIO_SET_NICE)
81COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
82COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
84/* 0x02 -- Floppy ioctls */ 83/* 0x02 -- Floppy ioctls */
85COMPATIBLE_IOCTL(FDMSGON) 84COMPATIBLE_IOCTL(FDMSGON)
86COMPATIBLE_IOCTL(FDMSGOFF) 85COMPATIBLE_IOCTL(FDMSGOFF)
@@ -99,6 +98,7 @@ COMPATIBLE_IOCTL(FDTWADDLE)
99COMPATIBLE_IOCTL(FDFMTTRK) 98COMPATIBLE_IOCTL(FDFMTTRK)
100COMPATIBLE_IOCTL(FDRAWCMD) 99COMPATIBLE_IOCTL(FDRAWCMD)
101/* 0x12 */ 100/* 0x12 */
101COMPATIBLE_IOCTL(BLKRASET)
102COMPATIBLE_IOCTL(BLKROSET) 102COMPATIBLE_IOCTL(BLKROSET)
103COMPATIBLE_IOCTL(BLKROGET) 103COMPATIBLE_IOCTL(BLKROGET)
104COMPATIBLE_IOCTL(BLKRRPART) 104COMPATIBLE_IOCTL(BLKRRPART)
@@ -262,6 +262,7 @@ COMPATIBLE_IOCTL(RTC_WKALM_RD)
262/* Little m */ 262/* Little m */
263COMPATIBLE_IOCTL(MTIOCTOP) 263COMPATIBLE_IOCTL(MTIOCTOP)
264/* Socket level stuff */ 264/* Socket level stuff */
265COMPATIBLE_IOCTL(FIOQSIZE)
265COMPATIBLE_IOCTL(FIOSETOWN) 266COMPATIBLE_IOCTL(FIOSETOWN)
266COMPATIBLE_IOCTL(SIOCSPGRP) 267COMPATIBLE_IOCTL(SIOCSPGRP)
267COMPATIBLE_IOCTL(FIOGETOWN) 268COMPATIBLE_IOCTL(FIOGETOWN)
diff --git a/include/linux/connector.h b/include/linux/connector.h
index c5769c6585f4..ad1a22c1c42e 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -32,6 +32,8 @@
32 */ 32 */
33#define CN_IDX_PROC 0x1 33#define CN_IDX_PROC 0x1
34#define CN_VAL_PROC 0x1 34#define CN_VAL_PROC 0x1
35#define CN_IDX_CIFS 0x2
36#define CN_VAL_CIFS 0x1
35 37
36#define CN_NETLINK_USERS 1 38#define CN_NETLINK_USERS 1
37 39
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 1f7b2c097503..43c44530ef9d 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -42,6 +42,7 @@ struct notifier_block;
42/* Need to know about CPUs going up/down? */ 42/* Need to know about CPUs going up/down? */
43extern int register_cpu_notifier(struct notifier_block *nb); 43extern int register_cpu_notifier(struct notifier_block *nb);
44extern void unregister_cpu_notifier(struct notifier_block *nb); 44extern void unregister_cpu_notifier(struct notifier_block *nb);
45extern int current_in_cpu_hotplug(void);
45 46
46int cpu_up(unsigned int cpu); 47int cpu_up(unsigned int cpu);
47 48
@@ -54,6 +55,10 @@ static inline int register_cpu_notifier(struct notifier_block *nb)
54static inline void unregister_cpu_notifier(struct notifier_block *nb) 55static inline void unregister_cpu_notifier(struct notifier_block *nb)
55{ 56{
56} 57}
58static inline int current_in_cpu_hotplug(void)
59{
60 return 0;
61}
57 62
58#endif /* CONFIG_SMP */ 63#endif /* CONFIG_SMP */
59extern struct sysdev_class cpu_sysdev_class; 64extern struct sysdev_class cpu_sysdev_class;
diff --git a/include/linux/eeprom.h b/include/linux/eeprom.h
deleted file mode 100644
index 38afd9da1dfe..000000000000
--- a/include/linux/eeprom.h
+++ /dev/null
@@ -1,136 +0,0 @@
1/* credit winbond-840.c
2 */
3#include <asm/io.h>
4struct eeprom_ops {
5 void (*set_cs)(void *ee);
6 void (*clear_cs)(void *ee);
7};
8
9#define EEPOL_EEDI 0x01
10#define EEPOL_EEDO 0x02
11#define EEPOL_EECLK 0x04
12#define EEPOL_EESEL 0x08
13
14struct eeprom {
15 void *dev;
16 struct eeprom_ops *ops;
17
18 void __iomem * addr;
19
20 unsigned ee_addr_bits;
21
22 unsigned eesel;
23 unsigned eeclk;
24 unsigned eedo;
25 unsigned eedi;
26 unsigned polarity;
27 unsigned ee_state;
28
29 spinlock_t *lock;
30 u32 *cache;
31};
32
33
34u8 eeprom_readb(struct eeprom *ee, unsigned address);
35void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes,
36 unsigned count);
37void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data);
38void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes,
39 unsigned count);
40
41/* The EEPROM commands include the alway-set leading bit. */
42enum EEPROM_Cmds {
43 EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
44};
45
46void setup_ee_mem_bitbanger(struct eeprom *ee, void __iomem *memaddr, int eesel_bit, int eeclk_bit, int eedo_bit, int eedi_bit, unsigned polarity)
47{
48 ee->addr = memaddr;
49 ee->eesel = 1 << eesel_bit;
50 ee->eeclk = 1 << eeclk_bit;
51 ee->eedo = 1 << eedo_bit;
52 ee->eedi = 1 << eedi_bit;
53
54 ee->polarity = polarity;
55
56 *ee->cache = readl(ee->addr);
57}
58
59/* foo. put this in a .c file */
60static inline void eeprom_update(struct eeprom *ee, u32 mask, int pol)
61{
62 unsigned long flags;
63 u32 data;
64
65 spin_lock_irqsave(ee->lock, flags);
66 data = *ee->cache;
67
68 data &= ~mask;
69 if (pol)
70 data |= mask;
71
72 *ee->cache = data;
73//printk("update: %08x\n", data);
74 writel(data, ee->addr);
75 spin_unlock_irqrestore(ee->lock, flags);
76}
77
78void eeprom_clk_lo(struct eeprom *ee)
79{
80 int pol = !!(ee->polarity & EEPOL_EECLK);
81
82 eeprom_update(ee, ee->eeclk, pol);
83 udelay(2);
84}
85
86void eeprom_clk_hi(struct eeprom *ee)
87{
88 int pol = !!(ee->polarity & EEPOL_EECLK);
89
90 eeprom_update(ee, ee->eeclk, !pol);
91 udelay(2);
92}
93
94void eeprom_send_addr(struct eeprom *ee, unsigned address)
95{
96 int pol = !!(ee->polarity & EEPOL_EEDI);
97 unsigned i;
98 address |= 6 << 6;
99
100 /* Shift the read command bits out. */
101 for (i=0; i<11; i++) {
102 eeprom_update(ee, ee->eedi, ((address >> 10) & 1) ^ pol);
103 address <<= 1;
104 eeprom_clk_hi(ee);
105 eeprom_clk_lo(ee);
106 }
107 eeprom_update(ee, ee->eedi, pol);
108}
109
110u16 eeprom_readw(struct eeprom *ee, unsigned address)
111{
112 unsigned i;
113 u16 res = 0;
114
115 eeprom_clk_lo(ee);
116 eeprom_update(ee, ee->eesel, 1 ^ !!(ee->polarity & EEPOL_EESEL));
117 eeprom_send_addr(ee, address);
118
119 for (i=0; i<16; i++) {
120 u32 data;
121 eeprom_clk_hi(ee);
122 res <<= 1;
123 data = readl(ee->addr);
124//printk("eeprom_readw: %08x\n", data);
125 res |= !!(data & ee->eedo) ^ !!(ee->polarity & EEPOL_EEDO);
126 eeprom_clk_lo(ee);
127 }
128 eeprom_update(ee, ee->eesel, 0 ^ !!(ee->polarity & EEPOL_EESEL));
129
130 return res;
131}
132
133
134void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data)
135{
136}
diff --git a/include/linux/fb.h b/include/linux/fb.h
index e7ff98e395f6..04a58f33ec53 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -201,6 +201,14 @@ struct fb_bitfield {
201#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ 201#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
202#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ 202#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
203 203
204/*
205 * Display rotation support
206 */
207#define FB_ROTATE_UR 0
208#define FB_ROTATE_CW 1
209#define FB_ROTATE_UD 2
210#define FB_ROTATE_CCW 3
211
204#define PICOS2KHZ(a) (1000000000UL/(a)) 212#define PICOS2KHZ(a) (1000000000UL/(a))
205#define KHZ2PICOS(a) (1000000000UL/(a)) 213#define KHZ2PICOS(a) (1000000000UL/(a))
206 214
@@ -489,9 +497,9 @@ struct fb_cursor_user {
489#define FB_EVENT_MODE_DELETE 0x04 497#define FB_EVENT_MODE_DELETE 0x04
490/* A driver registered itself */ 498/* A driver registered itself */
491#define FB_EVENT_FB_REGISTERED 0x05 499#define FB_EVENT_FB_REGISTERED 0x05
492/* get console to framebuffer mapping */ 500/* CONSOLE-SPECIFIC: get console to framebuffer mapping */
493#define FB_EVENT_GET_CONSOLE_MAP 0x06 501#define FB_EVENT_GET_CONSOLE_MAP 0x06
494/* set console to framebuffer mapping */ 502/* CONSOLE-SPECIFIC: set console to framebuffer mapping */
495#define FB_EVENT_SET_CONSOLE_MAP 0x07 503#define FB_EVENT_SET_CONSOLE_MAP 0x07
496/* A display blank is requested */ 504/* A display blank is requested */
497#define FB_EVENT_BLANK 0x08 505#define FB_EVENT_BLANK 0x08
@@ -500,6 +508,12 @@ struct fb_cursor_user {
500/* The resolution of the passed in fb_info about to change and 508/* The resolution of the passed in fb_info about to change and
501 all vc's should be changed */ 509 all vc's should be changed */
502#define FB_EVENT_MODE_CHANGE_ALL 0x0A 510#define FB_EVENT_MODE_CHANGE_ALL 0x0A
511/* CONSOLE-SPECIFIC: set console rotation */
512#define FB_EVENT_SET_CON_ROTATE 0x0B
513/* CONSOLE-SPECIFIC: get console rotation */
514#define FB_EVENT_GET_CON_ROTATE 0x0C
515/* CONSOLE-SPECIFIC: rotate all consoles */
516#define FB_EVENT_SET_CON_ROTATE_ALL 0x0D
503 517
504struct fb_event { 518struct fb_event {
505 struct fb_info *info; 519 struct fb_info *info;
@@ -817,8 +831,8 @@ extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
817/* drivers/video/fbmem.c */ 831/* drivers/video/fbmem.c */
818extern int register_framebuffer(struct fb_info *fb_info); 832extern int register_framebuffer(struct fb_info *fb_info);
819extern int unregister_framebuffer(struct fb_info *fb_info); 833extern int unregister_framebuffer(struct fb_info *fb_info);
820extern int fb_prepare_logo(struct fb_info *fb_info); 834extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
821extern int fb_show_logo(struct fb_info *fb_info); 835extern int fb_show_logo(struct fb_info *fb_info, int rotate);
822extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); 836extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
823extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, 837extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
824 u32 height, u32 shift_high, u32 shift_low, u32 mod); 838 u32 height, u32 shift_high, u32 shift_low, u32 mod);
@@ -828,6 +842,7 @@ extern int fb_get_color_depth(struct fb_var_screeninfo *var,
828 struct fb_fix_screeninfo *fix); 842 struct fb_fix_screeninfo *fix);
829extern int fb_get_options(char *name, char **option); 843extern int fb_get_options(char *name, char **option);
830extern int fb_new_modelist(struct fb_info *info); 844extern int fb_new_modelist(struct fb_info *info);
845extern int fb_con_duit(struct fb_info *info, int event, void *data);
831 846
832extern struct fb_info *registered_fb[FB_MAX]; 847extern struct fb_info *registered_fb[FB_MAX];
833extern int num_registered_fb; 848extern int num_registered_fb;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1b5f502a4b8f..cc35b6ac778d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -874,6 +874,7 @@ static inline void unlock_super(struct super_block * sb)
874/* 874/*
875 * VFS helper functions.. 875 * VFS helper functions..
876 */ 876 */
877extern int vfs_permission(struct nameidata *, int);
877extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); 878extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
878extern int vfs_mkdir(struct inode *, struct dentry *, int); 879extern int vfs_mkdir(struct inode *, struct dentry *, int);
879extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); 880extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
@@ -889,6 +890,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de
889extern void dentry_unhash(struct dentry *dentry); 890extern void dentry_unhash(struct dentry *dentry);
890 891
891/* 892/*
893 * VFS file helper functions.
894 */
895extern int file_permission(struct file *, int);
896
897/*
892 * File types 898 * File types
893 * 899 *
894 * NOTE! These match bits 12..15 of stat.st_mode 900 * NOTE! These match bits 12..15 of stat.st_mode
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index bef23bbf8690..783c476b8674 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -16,7 +16,6 @@
16#ifndef FS_ENET_PD_H 16#ifndef FS_ENET_PD_H
17#define FS_ENET_PD_H 17#define FS_ENET_PD_H
18 18
19#include <linux/version.h>
20#include <asm/types.h> 19#include <asm/types.h>
21 20
22#define FS_ENET_NAME "fs_enet" 21#define FS_ENET_NAME "fs_enet"
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h
new file mode 100644
index 000000000000..84f12a41dc01
--- /dev/null
+++ b/include/linux/genetlink.h
@@ -0,0 +1,51 @@
1#ifndef __LINUX_GENERIC_NETLINK_H
2#define __LINUX_GENERIC_NETLINK_H
3
4#include <linux/netlink.h>
5
6#define GENL_NAMSIZ 16 /* length of family name */
7
8#define GENL_MIN_ID NLMSG_MIN_TYPE
9#define GENL_MAX_ID 1023
10
11struct genlmsghdr {
12 __u8 cmd;
13 __u8 version;
14 __u16 reserved;
15};
16
17#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
18
19/*
20 * List of reserved static generic netlink identifiers:
21 */
22#define GENL_ID_GENERATE 0
23#define GENL_ID_CTRL NLMSG_MIN_TYPE
24
25/**************************************************************************
26 * Controller
27 **************************************************************************/
28
29enum {
30 CTRL_CMD_UNSPEC,
31 CTRL_CMD_NEWFAMILY,
32 CTRL_CMD_DELFAMILY,
33 CTRL_CMD_GETFAMILY,
34 CTRL_CMD_NEWOPS,
35 CTRL_CMD_DELOPS,
36 CTRL_CMD_GETOPS,
37 __CTRL_CMD_MAX,
38};
39
40#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
41
42enum {
43 CTRL_ATTR_UNSPEC,
44 CTRL_ATTR_FAMILY_ID,
45 CTRL_ATTR_FAMILY_NAME,
46 __CTRL_ATTR_MAX,
47};
48
49#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
50
51#endif /* __LINUX_GENERIC_NETLINK_H */
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 1ce4b54caa21..74abaecdb572 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -27,10 +27,10 @@
27 * ---- Driver types ----------------------------------------------------- 27 * ---- Driver types -----------------------------------------------------
28 * device id name + number function description, i2c address(es) 28 * device id name + number function description, i2c address(es)
29 * 29 *
30 * Range 1000-1999 range is defined in sensors/sensors.h 30 * Range 1000-1999 range is defined in sensors/sensors.h
31 * Range 0x100 - 0x1ff is for V4L2 Common Components 31 * Range 0x100 - 0x1ff is for V4L2 Common Components
32 * Range 0xf000 - 0xffff is reserved for local experimentation, and should 32 * Range 0xf000 - 0xffff is reserved for local experimentation, and should
33 * never be used in official drivers 33 * never be used in official drivers
34 */ 34 */
35 35
36#define I2C_DRIVERID_MSP3400 1 36#define I2C_DRIVERID_MSP3400 1
@@ -99,7 +99,14 @@
99#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ 99#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
100#define I2C_DRIVERID_SAA7114H 64 /* video decoder */ 100#define I2C_DRIVERID_SAA7114H 64 /* video decoder */
101#define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */ 101#define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */
102 102#define I2C_DRIVERID_TDA9874 66 /* TV sound decoder */
103#define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */
104#define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */
105#define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */
106#define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */
107#define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */
108#define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */
109#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */
103 110
104#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */ 111#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
105#define I2C_DRIVERID_EXP1 0xF1 112#define I2C_DRIVERID_EXP1 0xF1
@@ -111,7 +118,7 @@
111#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ 118#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
112#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ 119#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */
113 120
114/* IDs -- Use DRIVERIDs 1000-1999 for sensors. 121/* IDs -- Use DRIVERIDs 1000-1999 for sensors.
115 These were originally in sensors.h in the lm_sensors package */ 122 These were originally in sensors.h in the lm_sensors package */
116#define I2C_DRIVERID_LM78 1002 123#define I2C_DRIVERID_LM78 1002
117#define I2C_DRIVERID_LM75 1003 124#define I2C_DRIVERID_LM75 1003
@@ -190,6 +197,7 @@
190#define I2C_HW_B_NVIDIA 0x01001c /* nvidia framebuffer driver */ 197#define I2C_HW_B_NVIDIA 0x01001c /* nvidia framebuffer driver */
191#define I2C_HW_B_SAVAGE 0x01001d /* savage framebuffer driver */ 198#define I2C_HW_B_SAVAGE 0x01001d /* savage framebuffer driver */
192#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */ 199#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */
200#define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */
193 201
194/* --- PCF 8584 based algorithms */ 202/* --- PCF 8584 based algorithms */
195#define I2C_HW_P_LP 0x020000 /* Parallel port interface */ 203#define I2C_HW_P_LP 0x020000 /* Parallel port interface */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 3461abc1e854..ac8b25fa6506 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -230,6 +230,7 @@ typedef struct hw_regs_s {
230 int dma; /* our dma entry */ 230 int dma; /* our dma entry */
231 ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ 231 ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
232 hwif_chipset_t chipset; 232 hwif_chipset_t chipset;
233 struct device *dev;
233} hw_regs_t; 234} hw_regs_t;
234 235
235/* 236/*
@@ -266,6 +267,10 @@ static inline void ide_std_init_ports(hw_regs_t *hw,
266 267
267#include <asm/ide.h> 268#include <asm/ide.h>
268 269
270#ifndef MAX_HWIFS
271#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
272#endif
273
269/* needed on alpha, x86/x86_64, ia64, mips, ppc32 and sh */ 274/* needed on alpha, x86/x86_64, ia64, mips, ppc32 and sh */
270#ifndef IDE_ARCH_OBSOLETE_DEFAULTS 275#ifndef IDE_ARCH_OBSOLETE_DEFAULTS
271# define ide_default_io_base(index) (0) 276# define ide_default_io_base(index) (0)
@@ -1324,7 +1329,8 @@ void ide_init_disk(struct gendisk *, ide_drive_t *);
1324extern int ideprobe_init(void); 1329extern int ideprobe_init(void);
1325 1330
1326extern void ide_scan_pcibus(int scan_direction) __init; 1331extern void ide_scan_pcibus(int scan_direction) __init;
1327extern int ide_pci_register_driver(struct pci_driver *driver); 1332extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner);
1333#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE)
1328extern void ide_pci_unregister_driver(struct pci_driver *driver); 1334extern void ide_pci_unregister_driver(struct pci_driver *driver);
1329void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *); 1335void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
1330extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d); 1336extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index d21c305c6c64..fe26d431de87 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -21,6 +21,8 @@
21#ifndef _LINUX_IF_ETHER_H 21#ifndef _LINUX_IF_ETHER_H
22#define _LINUX_IF_ETHER_H 22#define _LINUX_IF_ETHER_H
23 23
24#include <linux/types.h>
25
24/* 26/*
25 * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble 27 * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
26 * and FCS/CRC (frame check sequence). 28 * and FCS/CRC (frame check sequence).
@@ -100,7 +102,7 @@
100struct ethhdr { 102struct ethhdr {
101 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ 103 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
102 unsigned char h_source[ETH_ALEN]; /* source ether addr */ 104 unsigned char h_source[ETH_ALEN]; /* source ether addr */
103 unsigned short h_proto; /* packet type ID field */ 105 __be16 h_proto; /* packet type ID field */
104} __attribute__((packed)); 106} __attribute__((packed));
105 107
106#ifdef __KERNEL__ 108#ifdef __KERNEL__
diff --git a/include/linux/if_wanpipe_common.h b/include/linux/if_wanpipe_common.h
index f25fec8ee2ca..6e5461d69fdd 100644
--- a/include/linux/if_wanpipe_common.h
+++ b/include/linux/if_wanpipe_common.h
@@ -17,8 +17,6 @@
17#ifndef _WANPIPE_SOCK_DRIVER_COMMON_H 17#ifndef _WANPIPE_SOCK_DRIVER_COMMON_H
18#define _WANPIPE_SOCK_DRIVER_COMMON_H 18#define _WANPIPE_SOCK_DRIVER_COMMON_H
19 19
20#include <linux/version.h>
21
22typedef struct { 20typedef struct {
23 struct net_device *slave; 21 struct net_device *slave;
24 atomic_t packet_sent; 22 atomic_t packet_sent;
diff --git a/include/linux/istallion.h b/include/linux/istallion.h
index 5f4ee646c119..1f996621bc9c 100644
--- a/include/linux/istallion.h
+++ b/include/linux/istallion.h
@@ -21,8 +21,6 @@
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */ 22 */
23 23
24#include <linux/version.h>
25
26/*****************************************************************************/ 24/*****************************************************************************/
27#ifndef _ISTALLION_H 25#ifndef _ISTALLION_H
28#define _ISTALLION_H 26#define _ISTALLION_H
diff --git a/include/linux/libata.h b/include/linux/libata.h
index dcd17e7458ab..6f0752219f64 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -214,7 +214,7 @@ struct ata_probe_ent {
214 struct list_head node; 214 struct list_head node;
215 struct device *dev; 215 struct device *dev;
216 const struct ata_port_operations *port_ops; 216 const struct ata_port_operations *port_ops;
217 Scsi_Host_Template *sht; 217 struct scsi_host_template *sht;
218 struct ata_ioports port[ATA_MAX_PORTS]; 218 struct ata_ioports port[ATA_MAX_PORTS];
219 unsigned int n_ports; 219 unsigned int n_ports;
220 unsigned int hard_port_no; 220 unsigned int hard_port_no;
@@ -398,7 +398,7 @@ struct ata_port_operations {
398}; 398};
399 399
400struct ata_port_info { 400struct ata_port_info {
401 Scsi_Host_Template *sht; 401 struct scsi_host_template *sht;
402 unsigned long host_flags; 402 unsigned long host_flags;
403 unsigned long pio_mask; 403 unsigned long pio_mask;
404 unsigned long mwdma_mask; 404 unsigned long mwdma_mask;
@@ -433,7 +433,7 @@ extern void ata_pci_remove_one (struct pci_dev *pdev);
433#endif /* CONFIG_PCI */ 433#endif /* CONFIG_PCI */
434extern int ata_device_add(const struct ata_probe_ent *ent); 434extern int ata_device_add(const struct ata_probe_ent *ent);
435extern void ata_host_set_remove(struct ata_host_set *host_set); 435extern void ata_host_set_remove(struct ata_host_set *host_set);
436extern int ata_scsi_detect(Scsi_Host_Template *sht); 436extern int ata_scsi_detect(struct scsi_host_template *sht);
437extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); 437extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
438extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); 438extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
439extern int ata_scsi_error(struct Scsi_Host *host); 439extern int ata_scsi_error(struct Scsi_Host *host);
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 39f1430bd6d5..3c9ea4b7adda 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -8,7 +8,6 @@
8#define __MTD_CFI_H__ 8#define __MTD_CFI_H__
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/delay.h> 11#include <linux/delay.h>
13#include <linux/types.h> 12#include <linux/types.h>
14#include <linux/interrupt.h> 13#include <linux/interrupt.h>
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index e95d0463a3e5..b6f2fdae65c6 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -14,7 +14,6 @@
14#endif 14#endif
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/version.h>
18#include <linux/types.h> 17#include <linux/types.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/uio.h> 19#include <linux/uio.h>
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 1c975d0d9e94..455660eafba9 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -74,7 +74,7 @@ extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
74extern void release_open_intent(struct nameidata *); 74extern void release_open_intent(struct nameidata *);
75 75
76extern struct dentry * lookup_one_len(const char *, struct dentry *, int); 76extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
77extern struct dentry * lookup_hash(struct qstr *, struct dentry *); 77extern struct dentry * lookup_hash(struct nameidata *);
78 78
79extern int follow_down(struct vfsmount **, struct dentry **); 79extern int follow_down(struct vfsmount **, struct dentry **);
80extern int follow_up(struct vfsmount **, struct dentry **); 80extern int follow_up(struct vfsmount **, struct dentry **);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c6efce4a04a4..936f8b76114e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -927,6 +927,13 @@ extern int netdev_max_backlog;
927extern int weight_p; 927extern int weight_p;
928extern int netdev_set_master(struct net_device *dev, struct net_device *master); 928extern int netdev_set_master(struct net_device *dev, struct net_device *master);
929extern int skb_checksum_help(struct sk_buff *skb, int inward); 929extern int skb_checksum_help(struct sk_buff *skb, int inward);
930#ifdef CONFIG_BUG
931extern void netdev_rx_csum_fault(struct net_device *dev);
932#else
933static inline void netdev_rx_csum_fault(struct net_device *dev)
934{
935}
936#endif
930/* rx skb timestamps */ 937/* rx skb timestamps */
931extern void net_enable_timestamp(void); 938extern void net_enable_timestamp(void);
932extern void net_disable_timestamp(void); 939extern void net_disable_timestamp(void);
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
new file mode 100644
index 000000000000..6d39b518486b
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -0,0 +1,159 @@
1#ifndef _NF_CONNTRACK_COMMON_H
2#define _NF_CONNTRACK_COMMON_H
3/* Connection state tracking for netfilter. This is separated from,
4 but required by, the NAT layer; it can also be used by an iptables
5 extension. */
6enum ip_conntrack_info
7{
8 /* Part of an established connection (either direction). */
9 IP_CT_ESTABLISHED,
10
11 /* Like NEW, but related to an existing connection, or ICMP error
12 (in either direction). */
13 IP_CT_RELATED,
14
15 /* Started a new connection to track (only
16 IP_CT_DIR_ORIGINAL); may be a retransmission. */
17 IP_CT_NEW,
18
19 /* >= this indicates reply direction */
20 IP_CT_IS_REPLY,
21
22 /* Number of distinct IP_CT types (no NEW in reply dirn). */
23 IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
24};
25
26/* Bitset representing status of connection. */
27enum ip_conntrack_status {
28 /* It's an expected connection: bit 0 set. This bit never changed */
29 IPS_EXPECTED_BIT = 0,
30 IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
31
32 /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
33 IPS_SEEN_REPLY_BIT = 1,
34 IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
35
36 /* Conntrack should never be early-expired. */
37 IPS_ASSURED_BIT = 2,
38 IPS_ASSURED = (1 << IPS_ASSURED_BIT),
39
40 /* Connection is confirmed: originating packet has left box */
41 IPS_CONFIRMED_BIT = 3,
42 IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
43
44 /* Connection needs src nat in orig dir. This bit never changed. */
45 IPS_SRC_NAT_BIT = 4,
46 IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
47
48 /* Connection needs dst nat in orig dir. This bit never changed. */
49 IPS_DST_NAT_BIT = 5,
50 IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
51
52 /* Both together. */
53 IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
54
55 /* Connection needs TCP sequence adjusted. */
56 IPS_SEQ_ADJUST_BIT = 6,
57 IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
58
59 /* NAT initialization bits. */
60 IPS_SRC_NAT_DONE_BIT = 7,
61 IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
62
63 IPS_DST_NAT_DONE_BIT = 8,
64 IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
65
66 /* Both together */
67 IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
68
69 /* Connection is dying (removed from lists), can not be unset. */
70 IPS_DYING_BIT = 9,
71 IPS_DYING = (1 << IPS_DYING_BIT),
72};
73
74/* Connection tracking event bits */
75enum ip_conntrack_events
76{
77 /* New conntrack */
78 IPCT_NEW_BIT = 0,
79 IPCT_NEW = (1 << IPCT_NEW_BIT),
80
81 /* Expected connection */
82 IPCT_RELATED_BIT = 1,
83 IPCT_RELATED = (1 << IPCT_RELATED_BIT),
84
85 /* Destroyed conntrack */
86 IPCT_DESTROY_BIT = 2,
87 IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
88
89 /* Timer has been refreshed */
90 IPCT_REFRESH_BIT = 3,
91 IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
92
93 /* Status has changed */
94 IPCT_STATUS_BIT = 4,
95 IPCT_STATUS = (1 << IPCT_STATUS_BIT),
96
97 /* Update of protocol info */
98 IPCT_PROTOINFO_BIT = 5,
99 IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
100
101 /* Volatile protocol info */
102 IPCT_PROTOINFO_VOLATILE_BIT = 6,
103 IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
104
105 /* New helper for conntrack */
106 IPCT_HELPER_BIT = 7,
107 IPCT_HELPER = (1 << IPCT_HELPER_BIT),
108
109 /* Update of helper info */
110 IPCT_HELPINFO_BIT = 8,
111 IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
112
113 /* Volatile helper info */
114 IPCT_HELPINFO_VOLATILE_BIT = 9,
115 IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
116
117 /* NAT info */
118 IPCT_NATINFO_BIT = 10,
119 IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
120
121 /* Counter highest bit has been set */
122 IPCT_COUNTER_FILLING_BIT = 11,
123 IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
124};
125
126enum ip_conntrack_expect_events {
127 IPEXP_NEW_BIT = 0,
128 IPEXP_NEW = (1 << IPEXP_NEW_BIT),
129};
130
131#ifdef __KERNEL__
132struct ip_conntrack_counter
133{
134 u_int32_t packets;
135 u_int32_t bytes;
136};
137
138struct ip_conntrack_stat
139{
140 unsigned int searched;
141 unsigned int found;
142 unsigned int new;
143 unsigned int invalid;
144 unsigned int ignore;
145 unsigned int delete;
146 unsigned int delete_list;
147 unsigned int insert;
148 unsigned int insert_failed;
149 unsigned int drop;
150 unsigned int early_drop;
151 unsigned int error;
152 unsigned int expect_new;
153 unsigned int expect_create;
154 unsigned int expect_delete;
155};
156
157#endif /* __KERNEL__ */
158
159#endif /* _NF_CONNTRACK_COMMON_H */
diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h
new file mode 100644
index 000000000000..ad4a41c9ce93
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_ftp.h
@@ -0,0 +1,44 @@
1#ifndef _NF_CONNTRACK_FTP_H
2#define _NF_CONNTRACK_FTP_H
3/* FTP tracking. */
4
5/* This enum is exposed to userspace */
6enum ip_ct_ftp_type
7{
8 /* PORT command from client */
9 IP_CT_FTP_PORT,
10 /* PASV response from server */
11 IP_CT_FTP_PASV,
12 /* EPRT command from client */
13 IP_CT_FTP_EPRT,
14 /* EPSV response from server */
15 IP_CT_FTP_EPSV,
16};
17
18#ifdef __KERNEL__
19
20#define FTP_PORT 21
21
22#define NUM_SEQ_TO_REMEMBER 2
23/* This structure exists only once per master */
24struct ip_ct_ftp_master {
25 /* Valid seq positions for cmd matching after newline */
26 u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
27 /* 0 means seq_match_aft_nl not set */
28 int seq_aft_nl_num[IP_CT_DIR_MAX];
29};
30
31struct ip_conntrack_expect;
32
33/* For NAT to hook in when we find a packet which describes what other
34 * connection we should expect. */
35extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
36 enum ip_conntrack_info ctinfo,
37 enum ip_ct_ftp_type type,
38 unsigned int matchoff,
39 unsigned int matchlen,
40 struct ip_conntrack_expect *exp,
41 u32 *seq);
42#endif /* __KERNEL__ */
43
44#endif /* _NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/linux/netfilter/nf_conntrack_sctp.h
new file mode 100644
index 000000000000..b8994d9fd1a9
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_sctp.h
@@ -0,0 +1,27 @@
1#ifndef _NF_CONNTRACK_SCTP_H
2#define _NF_CONNTRACK_SCTP_H
3/* SCTP tracking. */
4
5#include <linux/netfilter/nf_conntrack_tuple_common.h>
6
7enum sctp_conntrack {
8 SCTP_CONNTRACK_NONE,
9 SCTP_CONNTRACK_CLOSED,
10 SCTP_CONNTRACK_COOKIE_WAIT,
11 SCTP_CONNTRACK_COOKIE_ECHOED,
12 SCTP_CONNTRACK_ESTABLISHED,
13 SCTP_CONNTRACK_SHUTDOWN_SENT,
14 SCTP_CONNTRACK_SHUTDOWN_RECD,
15 SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
16 SCTP_CONNTRACK_MAX
17};
18
19struct ip_ct_sctp
20{
21 enum sctp_conntrack state;
22
23 u_int32_t vtag[IP_CT_DIR_MAX];
24 u_int32_t ttag[IP_CT_DIR_MAX];
25};
26
27#endif /* _NF_CONNTRACK_SCTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
new file mode 100644
index 000000000000..b2feeffde384
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -0,0 +1,56 @@
1#ifndef _NF_CONNTRACK_TCP_H
2#define _NF_CONNTRACK_TCP_H
3/* TCP tracking. */
4
5/* This is exposed to userspace (ctnetlink) */
6enum tcp_conntrack {
7 TCP_CONNTRACK_NONE,
8 TCP_CONNTRACK_SYN_SENT,
9 TCP_CONNTRACK_SYN_RECV,
10 TCP_CONNTRACK_ESTABLISHED,
11 TCP_CONNTRACK_FIN_WAIT,
12 TCP_CONNTRACK_CLOSE_WAIT,
13 TCP_CONNTRACK_LAST_ACK,
14 TCP_CONNTRACK_TIME_WAIT,
15 TCP_CONNTRACK_CLOSE,
16 TCP_CONNTRACK_LISTEN,
17 TCP_CONNTRACK_MAX,
18 TCP_CONNTRACK_IGNORE
19};
20
21/* Window scaling is advertised by the sender */
22#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
23
24/* SACK is permitted by the sender */
25#define IP_CT_TCP_FLAG_SACK_PERM 0x02
26
27/* This sender sent FIN first */
28#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
29
30#ifdef __KERNEL__
31
32struct ip_ct_tcp_state {
33 u_int32_t td_end; /* max of seq + len */
34 u_int32_t td_maxend; /* max of ack + max(win, 1) */
35 u_int32_t td_maxwin; /* max(win) */
36 u_int8_t td_scale; /* window scale factor */
37 u_int8_t loose; /* used when connection picked up from the middle */
38 u_int8_t flags; /* per direction options */
39};
40
41struct ip_ct_tcp
42{
43 struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */
44 u_int8_t state; /* state of the connection (enum tcp_conntrack) */
45 /* For detecting stale connections */
46 u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
47 u_int8_t retrans; /* Number of retransmitted packets */
48 u_int8_t last_index; /* Index of the last packet */
49 u_int32_t last_seq; /* Last sequence number seen in dir */
50 u_int32_t last_ack; /* Last sequence number seen in opposite dir */
51 u_int32_t last_end; /* Last seq + len */
52};
53
54#endif /* __KERNEL__ */
55
56#endif /* _NF_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/linux/netfilter/nf_conntrack_tuple_common.h
new file mode 100644
index 000000000000..8e145f0d61cb
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_tuple_common.h
@@ -0,0 +1,13 @@
1#ifndef _NF_CONNTRACK_TUPLE_COMMON_H
2#define _NF_CONNTRACK_TUPLE_COMMON_H
3
4enum ip_conntrack_dir
5{
6 IP_CT_DIR_ORIGINAL,
7 IP_CT_DIR_REPLY,
8 IP_CT_DIR_MAX
9};
10
11#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
12
13#endif /* _NF_CONNTRACK_TUPLE_COMMON_H */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index f08e870100f4..72975fa8795d 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -146,7 +146,7 @@ extern void nfnl_unlock(void);
146extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n); 146extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
147extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n); 147extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
148 148
149extern int nfattr_parse(struct nfattr *tb[], int maxattr, 149extern void nfattr_parse(struct nfattr *tb[], int maxattr,
150 struct nfattr *nfa, int len); 150 struct nfattr *nfa, int len);
151 151
152#define nfattr_parse_nested(tb, max, nfa) \ 152#define nfattr_parse_nested(tb, max, nfa) \
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index d078bb91d9e5..b3432ab59a17 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -1,132 +1,7 @@
1#ifndef _IP_CONNTRACK_H 1#ifndef _IP_CONNTRACK_H
2#define _IP_CONNTRACK_H 2#define _IP_CONNTRACK_H
3/* Connection state tracking for netfilter. This is separated from,
4 but required by, the NAT layer; it can also be used by an iptables
5 extension. */
6enum ip_conntrack_info
7{
8 /* Part of an established connection (either direction). */
9 IP_CT_ESTABLISHED,
10
11 /* Like NEW, but related to an existing connection, or ICMP error
12 (in either direction). */
13 IP_CT_RELATED,
14
15 /* Started a new connection to track (only
16 IP_CT_DIR_ORIGINAL); may be a retransmission. */
17 IP_CT_NEW,
18
19 /* >= this indicates reply direction */
20 IP_CT_IS_REPLY,
21
22 /* Number of distinct IP_CT types (no NEW in reply dirn). */
23 IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
24};
25
26/* Bitset representing status of connection. */
27enum ip_conntrack_status {
28 /* It's an expected connection: bit 0 set. This bit never changed */
29 IPS_EXPECTED_BIT = 0,
30 IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
31
32 /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
33 IPS_SEEN_REPLY_BIT = 1,
34 IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
35
36 /* Conntrack should never be early-expired. */
37 IPS_ASSURED_BIT = 2,
38 IPS_ASSURED = (1 << IPS_ASSURED_BIT),
39
40 /* Connection is confirmed: originating packet has left box */
41 IPS_CONFIRMED_BIT = 3,
42 IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
43
44 /* Connection needs src nat in orig dir. This bit never changed. */
45 IPS_SRC_NAT_BIT = 4,
46 IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
47
48 /* Connection needs dst nat in orig dir. This bit never changed. */
49 IPS_DST_NAT_BIT = 5,
50 IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
51
52 /* Both together. */
53 IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
54
55 /* Connection needs TCP sequence adjusted. */
56 IPS_SEQ_ADJUST_BIT = 6,
57 IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
58
59 /* NAT initialization bits. */
60 IPS_SRC_NAT_DONE_BIT = 7,
61 IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
62
63 IPS_DST_NAT_DONE_BIT = 8,
64 IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
65
66 /* Both together */
67 IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
68
69 /* Connection is dying (removed from lists), can not be unset. */
70 IPS_DYING_BIT = 9,
71 IPS_DYING = (1 << IPS_DYING_BIT),
72};
73
74/* Connection tracking event bits */
75enum ip_conntrack_events
76{
77 /* New conntrack */
78 IPCT_NEW_BIT = 0,
79 IPCT_NEW = (1 << IPCT_NEW_BIT),
80
81 /* Expected connection */
82 IPCT_RELATED_BIT = 1,
83 IPCT_RELATED = (1 << IPCT_RELATED_BIT),
84
85 /* Destroyed conntrack */
86 IPCT_DESTROY_BIT = 2,
87 IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
88
89 /* Timer has been refreshed */
90 IPCT_REFRESH_BIT = 3,
91 IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
92
93 /* Status has changed */
94 IPCT_STATUS_BIT = 4,
95 IPCT_STATUS = (1 << IPCT_STATUS_BIT),
96
97 /* Update of protocol info */
98 IPCT_PROTOINFO_BIT = 5,
99 IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
100
101 /* Volatile protocol info */
102 IPCT_PROTOINFO_VOLATILE_BIT = 6,
103 IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
104
105 /* New helper for conntrack */
106 IPCT_HELPER_BIT = 7,
107 IPCT_HELPER = (1 << IPCT_HELPER_BIT),
108
109 /* Update of helper info */
110 IPCT_HELPINFO_BIT = 8,
111 IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
112
113 /* Volatile helper info */
114 IPCT_HELPINFO_VOLATILE_BIT = 9,
115 IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
116 3
117 /* NAT info */ 4#include <linux/netfilter/nf_conntrack_common.h>
118 IPCT_NATINFO_BIT = 10,
119 IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
120
121 /* Counter highest bit has been set */
122 IPCT_COUNTER_FILLING_BIT = 11,
123 IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
124};
125
126enum ip_conntrack_expect_events {
127 IPEXP_NEW_BIT = 0,
128 IPEXP_NEW = (1 << IPEXP_NEW_BIT),
129};
130 5
131#ifdef __KERNEL__ 6#ifdef __KERNEL__
132#include <linux/config.h> 7#include <linux/config.h>
@@ -194,12 +69,6 @@ do { \
194#define IP_NF_ASSERT(x) 69#define IP_NF_ASSERT(x)
195#endif 70#endif
196 71
197struct ip_conntrack_counter
198{
199 u_int32_t packets;
200 u_int32_t bytes;
201};
202
203struct ip_conntrack_helper; 72struct ip_conntrack_helper;
204 73
205struct ip_conntrack 74struct ip_conntrack
@@ -426,25 +295,6 @@ static inline int is_dying(struct ip_conntrack *ct)
426 295
427extern unsigned int ip_conntrack_htable_size; 296extern unsigned int ip_conntrack_htable_size;
428 297
429struct ip_conntrack_stat
430{
431 unsigned int searched;
432 unsigned int found;
433 unsigned int new;
434 unsigned int invalid;
435 unsigned int ignore;
436 unsigned int delete;
437 unsigned int delete_list;
438 unsigned int insert;
439 unsigned int insert_failed;
440 unsigned int drop;
441 unsigned int early_drop;
442 unsigned int error;
443 unsigned int expect_new;
444 unsigned int expect_create;
445 unsigned int expect_delete;
446};
447
448#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++) 298#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
449 299
450#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS 300#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
index 5f06429b9047..63811934de4d 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
@@ -1,43 +1,6 @@
1#ifndef _IP_CONNTRACK_FTP_H 1#ifndef _IP_CONNTRACK_FTP_H
2#define _IP_CONNTRACK_FTP_H 2#define _IP_CONNTRACK_FTP_H
3/* FTP tracking. */
4 3
5#ifdef __KERNEL__ 4#include <linux/netfilter/nf_conntrack_ftp.h>
6 5
7#define FTP_PORT 21
8
9#endif /* __KERNEL__ */
10
11enum ip_ct_ftp_type
12{
13 /* PORT command from client */
14 IP_CT_FTP_PORT,
15 /* PASV response from server */
16 IP_CT_FTP_PASV,
17 /* EPRT command from client */
18 IP_CT_FTP_EPRT,
19 /* EPSV response from server */
20 IP_CT_FTP_EPSV,
21};
22
23#define NUM_SEQ_TO_REMEMBER 2
24/* This structure exists only once per master */
25struct ip_ct_ftp_master {
26 /* Valid seq positions for cmd matching after newline */
27 u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
28 /* 0 means seq_match_aft_nl not set */
29 int seq_aft_nl_num[IP_CT_DIR_MAX];
30};
31
32struct ip_conntrack_expect;
33
34/* For NAT to hook in when we find a packet which describes what other
35 * connection we should expect. */
36extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
37 enum ip_conntrack_info ctinfo,
38 enum ip_ct_ftp_type type,
39 unsigned int matchoff,
40 unsigned int matchlen,
41 struct ip_conntrack_expect *exp,
42 u32 *seq);
43#endif /* _IP_CONNTRACK_FTP_H */ 6#endif /* _IP_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
index f1664abbe392..eed5ee3e4744 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
@@ -1,11 +1,6 @@
1#ifndef _IP_CONNTRACK_ICMP_H 1#ifndef _IP_CONNTRACK_ICMP_H
2#define _IP_CONNTRACK_ICMP_H 2#define _IP_CONNTRACK_ICMP_H
3/* ICMP tracking. */
4#include <asm/atomic.h>
5 3
6struct ip_ct_icmp 4#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
7{ 5
8 /* Optimization: when number in == number out, forget immediately. */
9 atomic_t count;
10};
11#endif /* _IP_CONNTRACK_ICMP_H */ 6#endif /* _IP_CONNTRACK_ICMP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
index 7a8d869321f7..4099a041a32a 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
@@ -1,25 +1,6 @@
1#ifndef _IP_CONNTRACK_SCTP_H 1#ifndef _IP_CONNTRACK_SCTP_H
2#define _IP_CONNTRACK_SCTP_H 2#define _IP_CONNTRACK_SCTP_H
3/* SCTP tracking. */
4 3
5enum sctp_conntrack { 4#include <linux/netfilter/nf_conntrack_sctp.h>
6 SCTP_CONNTRACK_NONE,
7 SCTP_CONNTRACK_CLOSED,
8 SCTP_CONNTRACK_COOKIE_WAIT,
9 SCTP_CONNTRACK_COOKIE_ECHOED,
10 SCTP_CONNTRACK_ESTABLISHED,
11 SCTP_CONNTRACK_SHUTDOWN_SENT,
12 SCTP_CONNTRACK_SHUTDOWN_RECD,
13 SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
14 SCTP_CONNTRACK_MAX
15};
16
17struct ip_ct_sctp
18{
19 enum sctp_conntrack state;
20
21 u_int32_t vtag[IP_CT_DIR_MAX];
22 u_int32_t ttag[IP_CT_DIR_MAX];
23};
24 5
25#endif /* _IP_CONNTRACK_SCTP_H */ 6#endif /* _IP_CONNTRACK_SCTP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
index 16da044d97a7..876b8fb17e68 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
@@ -1,51 +1,6 @@
1#ifndef _IP_CONNTRACK_TCP_H 1#ifndef _IP_CONNTRACK_TCP_H
2#define _IP_CONNTRACK_TCP_H 2#define _IP_CONNTRACK_TCP_H
3/* TCP tracking. */
4 3
5enum tcp_conntrack { 4#include <linux/netfilter/nf_conntrack_tcp.h>
6 TCP_CONNTRACK_NONE,
7 TCP_CONNTRACK_SYN_SENT,
8 TCP_CONNTRACK_SYN_RECV,
9 TCP_CONNTRACK_ESTABLISHED,
10 TCP_CONNTRACK_FIN_WAIT,
11 TCP_CONNTRACK_CLOSE_WAIT,
12 TCP_CONNTRACK_LAST_ACK,
13 TCP_CONNTRACK_TIME_WAIT,
14 TCP_CONNTRACK_CLOSE,
15 TCP_CONNTRACK_LISTEN,
16 TCP_CONNTRACK_MAX,
17 TCP_CONNTRACK_IGNORE
18};
19
20/* Window scaling is advertised by the sender */
21#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
22
23/* SACK is permitted by the sender */
24#define IP_CT_TCP_FLAG_SACK_PERM 0x02
25
26/* This sender sent FIN first */
27#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
28
29struct ip_ct_tcp_state {
30 u_int32_t td_end; /* max of seq + len */
31 u_int32_t td_maxend; /* max of ack + max(win, 1) */
32 u_int32_t td_maxwin; /* max(win) */
33 u_int8_t td_scale; /* window scale factor */
34 u_int8_t loose; /* used when connection picked up from the middle */
35 u_int8_t flags; /* per direction options */
36};
37
38struct ip_ct_tcp
39{
40 struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */
41 u_int8_t state; /* state of the connection (enum tcp_conntrack) */
42 /* For detecting stale connections */
43 u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
44 u_int8_t retrans; /* Number of retransmitted packets */
45 u_int8_t last_index; /* Index of the last packet */
46 u_int32_t last_seq; /* Last sequence number seen in dir */
47 u_int32_t last_ack; /* Last sequence number seen in opposite dir */
48 u_int32_t last_end; /* Last seq + len */
49};
50 5
51#endif /* _IP_CONNTRACK_TCP_H */ 6#endif /* _IP_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
index 3232db11a4e5..2fdabdb4c0ef 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -2,6 +2,7 @@
2#define _IP_CONNTRACK_TUPLE_H 2#define _IP_CONNTRACK_TUPLE_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/netfilter/nf_conntrack_tuple_common.h>
5 6
6/* A `tuple' is a structure containing the information to uniquely 7/* A `tuple' is a structure containing the information to uniquely
7 identify a connection. ie. if two packets have the same tuple, they 8 identify a connection. ie. if two packets have the same tuple, they
@@ -88,13 +89,6 @@ struct ip_conntrack_tuple
88 (tuple)->dst.u.all = 0; \ 89 (tuple)->dst.u.all = 0; \
89 } while (0) 90 } while (0)
90 91
91enum ip_conntrack_dir
92{
93 IP_CT_DIR_ORIGINAL,
94 IP_CT_DIR_REPLY,
95 IP_CT_DIR_MAX
96};
97
98#ifdef __KERNEL__ 92#ifdef __KERNEL__
99 93
100#define DUMP_TUPLE(tp) \ 94#define DUMP_TUPLE(tp) \
@@ -103,8 +97,6 @@ DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \
103 NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ 97 NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \
104 NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) 98 NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all))
105 99
106#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
107
108/* If we're the first tuple, it's the original dir. */ 100/* If we're the first tuple, it's the original dir. */
109#define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir) 101#define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
110 102
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index edcc2c6eb5c7..53b2983f6278 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -59,6 +59,7 @@
59 59
60enum nf_ip6_hook_priorities { 60enum nf_ip6_hook_priorities {
61 NF_IP6_PRI_FIRST = INT_MIN, 61 NF_IP6_PRI_FIRST = INT_MIN,
62 NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
62 NF_IP6_PRI_SELINUX_FIRST = -225, 63 NF_IP6_PRI_SELINUX_FIRST = -225,
63 NF_IP6_PRI_CONNTRACK = -200, 64 NF_IP6_PRI_CONNTRACK = -200,
64 NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175, 65 NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index ba25ca874c20..6a2ccf78a356 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -71,7 +71,8 @@ struct nlmsghdr
71 71
72#define NLMSG_ALIGNTO 4 72#define NLMSG_ALIGNTO 4
73#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) 73#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
74#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(sizeof(struct nlmsghdr))) 74#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
75#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
75#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) 76#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
76#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0))) 77#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
77#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ 78#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
@@ -86,6 +87,8 @@ struct nlmsghdr
86#define NLMSG_DONE 0x3 /* End of a dump */ 87#define NLMSG_DONE 0x3 /* End of a dump */
87#define NLMSG_OVERRUN 0x4 /* Data lost */ 88#define NLMSG_OVERRUN 0x4 /* Data lost */
88 89
90#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
91
89struct nlmsgerr 92struct nlmsgerr
90{ 93{
91 int error; 94 int error;
@@ -108,6 +111,25 @@ enum {
108 NETLINK_CONNECTED, 111 NETLINK_CONNECTED,
109}; 112};
110 113
114/*
115 * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
116 * +---------------------+- - -+- - - - - - - - - -+- - -+
117 * | Header | Pad | Payload | Pad |
118 * | (struct nlattr) | ing | | ing |
119 * +---------------------+- - -+- - - - - - - - - -+- - -+
120 * <-------------- nlattr->nla_len -------------->
121 */
122
123struct nlattr
124{
125 __u16 nla_len;
126 __u16 nla_type;
127};
128
129#define NLA_ALIGNTO 4
130#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
131#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
132
111#ifdef __KERNEL__ 133#ifdef __KERNEL__
112 134
113#include <linux/capability.h> 135#include <linux/capability.h>
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 857126a36ecc..4877e35ae202 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -47,14 +47,15 @@
47 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) 47 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
48 48
49#ifdef CONFIG_ACPI 49#ifdef CONFIG_ACPI
50extern acpi_status pci_osc_control_set(u32 flags); 50extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags);
51extern acpi_status pci_osc_support_set(u32 flags); 51extern acpi_status pci_osc_support_set(u32 flags);
52#else 52#else
53#if !defined(acpi_status) 53#if !defined(acpi_status)
54typedef u32 acpi_status; 54typedef u32 acpi_status;
55#define AE_ERROR (acpi_status) (0x0001) 55#define AE_ERROR (acpi_status) (0x0001)
56#endif 56#endif
57static inline acpi_status pci_osc_control_set(u32 flags) {return AE_ERROR;} 57static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
58{return AE_ERROR;}
58static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;} 59static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;}
59#endif 60#endif
60 61
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 3596ac94ecff..de690ca73d58 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -236,7 +236,6 @@ struct module;
236struct pci_driver { 236struct pci_driver {
237 struct list_head node; 237 struct list_head node;
238 char *name; 238 char *name;
239 struct module *owner;
240 const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */ 239 const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
241 int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ 240 int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
242 void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ 241 void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
@@ -338,6 +337,7 @@ struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const
338struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from); 337struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from);
339struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); 338struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
340int pci_find_capability (struct pci_dev *dev, int cap); 339int pci_find_capability (struct pci_dev *dev, int cap);
340int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
341int pci_find_ext_capability (struct pci_dev *dev, int cap); 341int pci_find_ext_capability (struct pci_dev *dev, int cap);
342struct pci_bus * pci_find_next_bus(const struct pci_bus *from); 342struct pci_bus * pci_find_next_bus(const struct pci_bus *from);
343 343
@@ -432,8 +432,13 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
432 void *alignf_data); 432 void *alignf_data);
433void pci_enable_bridges(struct pci_bus *bus); 433void pci_enable_bridges(struct pci_bus *bus);
434 434
435/* New-style probing supporting hot-pluggable devices */ 435/* Proper probing supporting hot-pluggable devices */
436int pci_register_driver(struct pci_driver *); 436int __pci_register_driver(struct pci_driver *, struct module *);
437static inline int pci_register_driver(struct pci_driver *driver)
438{
439 return __pci_register_driver(driver, THIS_MODULE);
440}
441
437void pci_unregister_driver(struct pci_driver *); 442void pci_unregister_driver(struct pci_driver *);
438void pci_remove_behind_bridge(struct pci_dev *); 443void pci_remove_behind_bridge(struct pci_dev *);
439struct pci_driver *pci_dev_driver(const struct pci_dev *); 444struct pci_driver *pci_dev_driver(const struct pci_dev *);
@@ -547,9 +552,11 @@ static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
547static inline void pci_disable_device(struct pci_dev *dev) { } 552static inline void pci_disable_device(struct pci_dev *dev) { }
548static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; } 553static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
549static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;} 554static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
555static inline int __pci_register_driver(struct pci_driver *drv, struct module *owner) { return 0;}
550static inline int pci_register_driver(struct pci_driver *drv) { return 0;} 556static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
551static inline void pci_unregister_driver(struct pci_driver *drv) { } 557static inline void pci_unregister_driver(struct pci_driver *drv) { }
552static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } 558static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
559static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; }
553static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } 560static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; }
554static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } 561static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
555 562
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 9a96f0588393..4e06eb0f4451 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -387,6 +387,7 @@
387#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 387#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511
388#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 388#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515
389#define PCI_DEVICE_ID_NS_87410 0xd001 389#define PCI_DEVICE_ID_NS_87410 0xd001
390#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d
390 391
391#define PCI_VENDOR_ID_TSENG 0x100c 392#define PCI_VENDOR_ID_TSENG 0x100c
392#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 393#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
@@ -487,6 +488,8 @@
487#define PCI_DEVICE_ID_AMD_8151_0 0x7454 488#define PCI_DEVICE_ID_AMD_8151_0 0x7454
488#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450 489#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450
489 490
491#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
492
490#define PCI_VENDOR_ID_TRIDENT 0x1023 493#define PCI_VENDOR_ID_TRIDENT 0x1023
491#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 494#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
492#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001 495#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
diff --git a/include/linux/phonedev.h b/include/linux/phonedev.h
index d54049eed0c3..a0e31adf3abe 100644
--- a/include/linux/phonedev.h
+++ b/include/linux/phonedev.h
@@ -2,7 +2,6 @@
2#define __LINUX_PHONEDEV_H 2#define __LINUX_PHONEDEV_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/version.h>
6 5
7#ifdef __KERNEL__ 6#ifdef __KERNEL__
8 7
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 9de99198caf1..899437802aea 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -6,7 +6,13 @@
6#ifndef BITMAP_H 6#ifndef BITMAP_H
7#define BITMAP_H 1 7#define BITMAP_H 1
8 8
9#define BITMAP_MAJOR 3 9#define BITMAP_MAJOR_LO 3
10/* version 4 insists the bitmap is in little-endian order
11 * with version 3, it is host-endian which is non-portable
12 */
13#define BITMAP_MAJOR_HI 4
14#define BITMAP_MAJOR_HOSTENDIAN 3
15
10#define BITMAP_MINOR 39 16#define BITMAP_MINOR 39
11 17
12/* 18/*
@@ -133,7 +139,8 @@ typedef __u16 bitmap_counter_t;
133/* use these for bitmap->flags and bitmap->sb->state bit-fields */ 139/* use these for bitmap->flags and bitmap->sb->state bit-fields */
134enum bitmap_state { 140enum bitmap_state {
135 BITMAP_ACTIVE = 0x001, /* the bitmap is in use */ 141 BITMAP_ACTIVE = 0x001, /* the bitmap is in use */
136 BITMAP_STALE = 0x002 /* the bitmap file is out of date or had -EIO */ 142 BITMAP_STALE = 0x002, /* the bitmap file is out of date or had -EIO */
143 BITMAP_HOSTENDIAN = 0x8000,
137}; 144};
138 145
139/* the superblock at the front of the bitmap file -- little endian */ 146/* the superblock at the front of the bitmap file -- little endian */
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index ffa316ce4dc8..13e7c4b62367 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -66,8 +66,10 @@
66 * and major_version/minor_version accordingly 66 * and major_version/minor_version accordingly
67 * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT 67 * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
68 * in the super status byte 68 * in the super status byte
69 * >=3 means that bitmap superblock version 4 is supported, which uses
70 * little-ending representation rather than host-endian
69 */ 71 */
70#define MD_PATCHLEVEL_VERSION 2 72#define MD_PATCHLEVEL_VERSION 3
71 73
72extern int register_md_personality (int p_num, mdk_personality_t *p); 74extern int register_md_personality (int p_num, mdk_personality_t *p);
73extern int unregister_md_personality (int p_num); 75extern int unregister_md_personality (int p_num);
@@ -87,6 +89,7 @@ extern void md_print_devices (void);
87 89
88extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, 90extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
89 sector_t sector, int size, struct page *page); 91 sector_t sector, int size, struct page *page);
92extern void md_super_wait(mddev_t *mddev);
90extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, 93extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
91 struct page *page, int rw); 94 struct page *page, int rw);
92 95
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index ebce949b1443..46629a275ba9 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -105,6 +105,8 @@ struct mdk_rdev_s
105 int sb_size; /* bytes in the superblock */ 105 int sb_size; /* bytes in the superblock */
106 int preferred_minor; /* autorun support */ 106 int preferred_minor; /* autorun support */
107 107
108 struct kobject kobj;
109
108 /* A device can be in one of three states based on two flags: 110 /* A device can be in one of three states based on two flags:
109 * Not working: faulty==1 in_sync==0 111 * Not working: faulty==1 in_sync==0
110 * Fully working: faulty==0 in_sync==1 112 * Fully working: faulty==0 in_sync==1
@@ -115,11 +117,12 @@ struct mdk_rdev_s
115 * It can never have faulty==1, in_sync==1 117 * It can never have faulty==1, in_sync==1
116 * This reduces the burden of testing multiple flags in many cases 118 * This reduces the burden of testing multiple flags in many cases
117 */ 119 */
118 int faulty; /* if faulty do not issue IO requests */
119 int in_sync; /* device is a full member of the array */
120 120
121 unsigned long flags; /* Should include faulty and in_sync here. */ 121 unsigned long flags;
122#define Faulty 1 /* device is known to have a fault */
123#define In_sync 2 /* device is in_sync with rest of array */
122#define WriteMostly 4 /* Avoid reading if at all possible */ 124#define WriteMostly 4 /* Avoid reading if at all possible */
125#define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */
123 126
124 int desc_nr; /* descriptor index in the superblock */ 127 int desc_nr; /* descriptor index in the superblock */
125 int raid_disk; /* role of device in array */ 128 int raid_disk; /* role of device in array */
@@ -132,6 +135,9 @@ struct mdk_rdev_s
132 * only maintained for arrays that 135 * only maintained for arrays that
133 * support hot removal 136 * support hot removal
134 */ 137 */
138 atomic_t read_errors; /* number of consecutive read errors that
139 * we have tried to ignore.
140 */
135}; 141};
136 142
137typedef struct mdk_personality_s mdk_personality_t; 143typedef struct mdk_personality_s mdk_personality_t;
@@ -148,6 +154,8 @@ struct mddev_s
148 154
149 struct gendisk *gendisk; 155 struct gendisk *gendisk;
150 156
157 struct kobject kobj;
158
151 /* Superblock information */ 159 /* Superblock information */
152 int major_version, 160 int major_version,
153 minor_version, 161 minor_version,
@@ -171,6 +179,10 @@ struct mddev_s
171 sector_t resync_mark_cnt;/* blocks written at resync_mark */ 179 sector_t resync_mark_cnt;/* blocks written at resync_mark */
172 180
173 sector_t resync_max_sectors; /* may be set by personality */ 181 sector_t resync_max_sectors; /* may be set by personality */
182
183 sector_t resync_mismatches; /* count of sectors where
184 * parity/replica mismatch found
185 */
174 /* recovery/resync flags 186 /* recovery/resync flags
175 * NEEDED: we might need to start a resync/recover 187 * NEEDED: we might need to start a resync/recover
176 * RUNNING: a thread is running, or about to be started 188 * RUNNING: a thread is running, or about to be started
@@ -178,6 +190,8 @@ struct mddev_s
178 * ERR: and IO error was detected - abort the resync/recovery 190 * ERR: and IO error was detected - abort the resync/recovery
179 * INTR: someone requested a (clean) early abort. 191 * INTR: someone requested a (clean) early abort.
180 * DONE: thread is done and is waiting to be reaped 192 * DONE: thread is done and is waiting to be reaped
193 * REQUEST: user-space has requested a sync (used with SYNC)
194 * CHECK: user-space request for for check-only, no repair
181 */ 195 */
182#define MD_RECOVERY_RUNNING 0 196#define MD_RECOVERY_RUNNING 0
183#define MD_RECOVERY_SYNC 1 197#define MD_RECOVERY_SYNC 1
@@ -185,6 +199,8 @@ struct mddev_s
185#define MD_RECOVERY_INTR 3 199#define MD_RECOVERY_INTR 3
186#define MD_RECOVERY_DONE 4 200#define MD_RECOVERY_DONE 4
187#define MD_RECOVERY_NEEDED 5 201#define MD_RECOVERY_NEEDED 5
202#define MD_RECOVERY_REQUESTED 6
203#define MD_RECOVERY_CHECK 7
188 unsigned long recovery; 204 unsigned long recovery;
189 205
190 int in_sync; /* know to not need resync */ 206 int in_sync; /* know to not need resync */
@@ -195,6 +211,13 @@ struct mddev_s
195 int degraded; /* whether md should consider 211 int degraded; /* whether md should consider
196 * adding a spare 212 * adding a spare
197 */ 213 */
214 int barriers_work; /* initialised to true, cleared as soon
215 * as a barrier request to slave
216 * fails. Only supported
217 */
218 struct bio *biolist; /* bios that need to be retried
219 * because BIO_RW_BARRIER is not supported
220 */
198 221
199 atomic_t recovery_active; /* blocks scheduled, but not written */ 222 atomic_t recovery_active; /* blocks scheduled, but not written */
200 wait_queue_head_t recovery_wait; 223 wait_queue_head_t recovery_wait;
@@ -232,7 +255,7 @@ struct mddev_s
232 255
233static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev) 256static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
234{ 257{
235 int faulty = rdev->faulty; 258 int faulty = test_bit(Faulty, &rdev->flags);
236 if (atomic_dec_and_test(&rdev->nr_pending) && faulty) 259 if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
237 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 260 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
238} 261}
@@ -270,6 +293,13 @@ struct mdk_personality_s
270}; 293};
271 294
272 295
296struct md_sysfs_entry {
297 struct attribute attr;
298 ssize_t (*show)(mddev_t *, char *);
299 ssize_t (*store)(mddev_t *, const char *, size_t);
300};
301
302
273static inline char * mdname (mddev_t * mddev) 303static inline char * mdname (mddev_t * mddev)
274{ 304{
275 return mddev->gendisk ? mddev->gendisk->disk_name : "mdX"; 305 return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
@@ -304,10 +334,8 @@ typedef struct mdk_thread_s {
304 mddev_t *mddev; 334 mddev_t *mddev;
305 wait_queue_head_t wqueue; 335 wait_queue_head_t wqueue;
306 unsigned long flags; 336 unsigned long flags;
307 struct completion *event;
308 struct task_struct *tsk; 337 struct task_struct *tsk;
309 unsigned long timeout; 338 unsigned long timeout;
310 const char *name;
311} mdk_thread_t; 339} mdk_thread_t;
312 340
313#define THREAD_WAKEUP 0 341#define THREAD_WAKEUP 0
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 60e19b667548..292b98f2b408 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -110,7 +110,9 @@ struct r1bio_s {
110#define R1BIO_Uptodate 0 110#define R1BIO_Uptodate 0
111#define R1BIO_IsSync 1 111#define R1BIO_IsSync 1
112#define R1BIO_Degraded 2 112#define R1BIO_Degraded 2
113#define R1BIO_BehindIO 3 113#define R1BIO_BehindIO 3
114#define R1BIO_Barrier 4
115#define R1BIO_BarrierRetry 5
114/* For write-behind requests, we call bi_end_io when 116/* For write-behind requests, we call bi_end_io when
115 * the last non-write-behind device completes, providing 117 * the last non-write-behind device completes, providing
116 * any write was successful. Otherwise we call when 118 * any write was successful. Otherwise we call when
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 176fc653c284..f025ba6fb14c 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -154,6 +154,8 @@ struct stripe_head {
154#define R5_Wantwrite 5 154#define R5_Wantwrite 5
155#define R5_Syncio 6 /* this io need to be accounted as resync io */ 155#define R5_Syncio 6 /* this io need to be accounted as resync io */
156#define R5_Overlap 7 /* There is a pending overlapping request on this block */ 156#define R5_Overlap 7 /* There is a pending overlapping request on this block */
157#define R5_ReadError 8 /* seen a read error here recently */
158#define R5_ReWrite 9 /* have tried to over-write the readerror */
157 159
158/* 160/*
159 * Write method 161 * Write method
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 03b68a7b4b82..2bbf968b23d9 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -909,6 +909,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
909#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */ 909#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */
910#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ 910#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */
911#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */ 911#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */
912#define PF_HOTPLUG_CPU 0x01000000 /* Currently performing CPU hotplug */
912 913
913/* 914/*
914 * Only the _current_ task can read/write to tsk->flags, but other 915 * Only the _current_ task can read/write to tsk->flags, but other
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index fdfb8fe8c38c..0a8ea8b35816 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -274,6 +274,9 @@ struct sk_buff {
274#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 274#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
275 __u8 ipvs_property:1; 275 __u8 ipvs_property:1;
276#endif 276#endif
277#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
278 struct sk_buff *nfct_reasm;
279#endif
277#ifdef CONFIG_BRIDGE_NETFILTER 280#ifdef CONFIG_BRIDGE_NETFILTER
278 struct nf_bridge_info *nf_bridge; 281 struct nf_bridge_info *nf_bridge;
279#endif 282#endif
@@ -1233,8 +1236,7 @@ extern unsigned int datagram_poll(struct file *file, struct socket *sock,
1233extern int skb_copy_datagram_iovec(const struct sk_buff *from, 1236extern int skb_copy_datagram_iovec(const struct sk_buff *from,
1234 int offset, struct iovec *to, 1237 int offset, struct iovec *to,
1235 int size); 1238 int size);
1236extern int skb_copy_and_csum_datagram_iovec(const 1239extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
1237 struct sk_buff *skb,
1238 int hlen, 1240 int hlen,
1239 struct iovec *iov); 1241 struct iovec *iov);
1240extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); 1242extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
@@ -1302,6 +1304,30 @@ static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *
1302 1304
1303extern void __net_timestamp(struct sk_buff *skb); 1305extern void __net_timestamp(struct sk_buff *skb);
1304 1306
1307extern unsigned int __skb_checksum_complete(struct sk_buff *skb);
1308
1309/**
1310 * skb_checksum_complete - Calculate checksum of an entire packet
1311 * @skb: packet to process
1312 *
1313 * This function calculates the checksum over the entire packet plus
1314 * the value of skb->csum. The latter can be used to supply the
1315 * checksum of a pseudo header as used by TCP/UDP. It returns the
1316 * checksum.
1317 *
1318 * For protocols that contain complete checksums such as ICMP/TCP/UDP,
1319 * this function can be used to verify that checksum on received
1320 * packets. In that case the function should return zero if the
1321 * checksum is correct. In particular, this function will return zero
1322 * if skb->ip_summed is CHECKSUM_UNNECESSARY which indicates that the
1323 * hardware has already verified the correctness of the checksum.
1324 */
1325static inline unsigned int skb_checksum_complete(struct sk_buff *skb)
1326{
1327 return skb->ip_summed != CHECKSUM_UNNECESSARY &&
1328 __skb_checksum_complete(skb);
1329}
1330
1305#ifdef CONFIG_NETFILTER 1331#ifdef CONFIG_NETFILTER
1306static inline void nf_conntrack_put(struct nf_conntrack *nfct) 1332static inline void nf_conntrack_put(struct nf_conntrack *nfct)
1307{ 1333{
@@ -1313,10 +1339,26 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
1313 if (nfct) 1339 if (nfct)
1314 atomic_inc(&nfct->use); 1340 atomic_inc(&nfct->use);
1315} 1341}
1342#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
1343static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
1344{
1345 if (skb)
1346 atomic_inc(&skb->users);
1347}
1348static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
1349{
1350 if (skb)
1351 kfree_skb(skb);
1352}
1353#endif
1316static inline void nf_reset(struct sk_buff *skb) 1354static inline void nf_reset(struct sk_buff *skb)
1317{ 1355{
1318 nf_conntrack_put(skb->nfct); 1356 nf_conntrack_put(skb->nfct);
1319 skb->nfct = NULL; 1357 skb->nfct = NULL;
1358#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
1359 nf_conntrack_put_reasm(skb->nfct_reasm);
1360 skb->nfct_reasm = NULL;
1361#endif
1320} 1362}
1321 1363
1322#ifdef CONFIG_BRIDGE_NETFILTER 1364#ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/include/linux/stallion.h b/include/linux/stallion.h
index e89b77b6505a..13a37f137ea2 100644
--- a/include/linux/stallion.h
+++ b/include/linux/stallion.h
@@ -21,8 +21,6 @@
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */ 22 */
23 23
24#include <linux/version.h>
25
26/*****************************************************************************/ 24/*****************************************************************************/
27#ifndef _STALLION_H 25#ifndef _STALLION_H
28#define _STALLION_H 26#define _STALLION_H
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index fc131d6602b9..ab2791b3189d 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -205,6 +205,7 @@ enum
205 NET_ECONET=16, 205 NET_ECONET=16,
206 NET_SCTP=17, 206 NET_SCTP=17,
207 NET_LLC=18, 207 NET_LLC=18,
208 NET_NETFILTER=19,
208}; 209};
209 210
210/* /proc/sys/kernel/random */ 211/* /proc/sys/kernel/random */
@@ -270,6 +271,42 @@ enum
270 NET_UNIX_MAX_DGRAM_QLEN=3, 271 NET_UNIX_MAX_DGRAM_QLEN=3,
271}; 272};
272 273
274/* /proc/sys/net/netfilter */
275enum
276{
277 NET_NF_CONNTRACK_MAX=1,
278 NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
279 NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
280 NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
281 NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
282 NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
283 NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
284 NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
285 NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
286 NET_NF_CONNTRACK_UDP_TIMEOUT=10,
287 NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
288 NET_NF_CONNTRACK_ICMP_TIMEOUT=12,
289 NET_NF_CONNTRACK_GENERIC_TIMEOUT=13,
290 NET_NF_CONNTRACK_BUCKETS=14,
291 NET_NF_CONNTRACK_LOG_INVALID=15,
292 NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
293 NET_NF_CONNTRACK_TCP_LOOSE=17,
294 NET_NF_CONNTRACK_TCP_BE_LIBERAL=18,
295 NET_NF_CONNTRACK_TCP_MAX_RETRANS=19,
296 NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
297 NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
298 NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
299 NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
300 NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
301 NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
302 NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
303 NET_NF_CONNTRACK_COUNT=27,
304 NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28,
305 NET_NF_CONNTRACK_FRAG6_TIMEOUT=29,
306 NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30,
307 NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31,
308};
309
273/* /proc/sys/net/ipv4 */ 310/* /proc/sys/net/ipv4 */
274enum 311enum
275{ 312{
@@ -353,6 +390,7 @@ enum
353 NET_TCP_BIC_BETA=108, 390 NET_TCP_BIC_BETA=108,
354 NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109, 391 NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
355 NET_TCP_CONG_CONTROL=110, 392 NET_TCP_CONG_CONTROL=110,
393 NET_TCP_ABC=111,
356}; 394};
357 395
358enum { 396enum {
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index ac4ca44c75ca..0e1da6602e05 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -307,6 +307,21 @@ struct tcp_sock {
307 struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */ 307 struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */
308 struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/ 308 struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/
309 309
310 struct tcp_sack_block recv_sack_cache[4];
311
312 /* from STCP, retrans queue hinting */
313 struct sk_buff* lost_skb_hint;
314
315 struct sk_buff *scoreboard_skb_hint;
316 struct sk_buff *retransmit_skb_hint;
317 struct sk_buff *forward_skb_hint;
318 struct sk_buff *fastpath_skb_hint;
319
320 int fastpath_cnt_hint;
321 int lost_cnt_hint;
322 int retransmit_cnt_hint;
323 int forward_cnt_hint;
324
310 __u16 advmss; /* Advertised MSS */ 325 __u16 advmss; /* Advertised MSS */
311 __u16 prior_ssthresh; /* ssthresh saved at recovery start */ 326 __u16 prior_ssthresh; /* ssthresh saved at recovery start */
312 __u32 lost_out; /* Lost packets */ 327 __u32 lost_out; /* Lost packets */
@@ -326,6 +341,7 @@ struct tcp_sock {
326 __u32 snd_up; /* Urgent pointer */ 341 __u32 snd_up; /* Urgent pointer */
327 342
328 __u32 total_retrans; /* Total retransmits for entire connection */ 343 __u32 total_retrans; /* Total retransmits for entire connection */
344 __u32 bytes_acked; /* Appropriate Byte Counting - RFC3465 */
329 345
330 unsigned int keepalive_time; /* time before keep alive takes place */ 346 unsigned int keepalive_time; /* time before keep alive takes place */
331 unsigned int keepalive_intvl; /* time interval between keep alive probes */ 347 unsigned int keepalive_intvl; /* time interval between keep alive probes */
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 1cc8c31b7988..91140091ced2 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -1,57 +1,16 @@
1#ifndef __LINUX_VIDEODEV_H 1#ifndef __LINUX_VIDEODEV_H
2#define __LINUX_VIDEODEV_H 2#define __LINUX_VIDEODEV_H
3 3
4#include <linux/compiler.h>
5#include <linux/types.h> 4#include <linux/types.h>
6 5
7#define HAVE_V4L2 1 6#define HAVE_V4L1 1
7
8#include <linux/videodev2.h> 8#include <linux/videodev2.h>
9 9
10#ifdef __KERNEL__ 10#ifdef __KERNEL__
11 11
12#include <linux/poll.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
14#include <linux/device.h>
15
16struct video_device
17{
18 /* device info */
19 struct device *dev;
20 char name[32];
21 int type; /* v4l1 */
22 int type2; /* v4l2 */
23 int hardware;
24 int minor;
25
26 /* device ops + callbacks */
27 struct file_operations *fops;
28 void (*release)(struct video_device *vfd);
29
30
31 /* obsolete -- fops->owner is used instead */
32 struct module *owner;
33 /* dev->driver_data will be used instead some day.
34 * Use the video_{get|set}_drvdata() helper functions,
35 * so the switch over will be transparent for you.
36 * Or use {pci|usb}_{get|set}_drvdata() directly. */
37 void *priv;
38
39 /* for videodev.c intenal usage -- please don't touch */
40 int users; /* video_exclusive_{open|close} ... */
41 struct semaphore lock; /* ... helper function uses these */
42 char devfs_name[64]; /* devfs */
43 struct class_device class_dev; /* sysfs */
44};
45
46#define VIDEO_MAJOR 81
47
48#define VFL_TYPE_GRABBER 0
49#define VFL_TYPE_VBI 1
50#define VFL_TYPE_RADIO 2
51#define VFL_TYPE_VTX 3
52 13
53extern int video_register_device(struct video_device *, int type, int nr);
54extern void video_unregister_device(struct video_device *);
55extern struct video_device* video_devdata(struct file*); 14extern struct video_device* video_devdata(struct file*);
56 15
57#define to_video_device(cd) container_of(cd, struct video_device, class_dev) 16#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
@@ -68,11 +27,7 @@ video_device_remove_file(struct video_device *vfd,
68 class_device_remove_file(&vfd->class_dev, attr); 27 class_device_remove_file(&vfd->class_dev, attr);
69} 28}
70 29
71/* helper functions to alloc / release struct video_device, the 30#if OBSOLETE_OWNER /* to be removed in 2.6.15 */
72 later can be used for video_device->release() */
73struct video_device *video_device_alloc(void);
74void video_device_release(struct video_device *vfd);
75
76/* helper functions to access driver private data. */ 31/* helper functions to access driver private data. */
77static inline void *video_get_drvdata(struct video_device *dev) 32static inline void *video_get_drvdata(struct video_device *dev)
78{ 33{
@@ -83,30 +38,12 @@ static inline void video_set_drvdata(struct video_device *dev, void *data)
83{ 38{
84 dev->priv = data; 39 dev->priv = data;
85} 40}
41#endif
86 42
87extern int video_exclusive_open(struct inode *inode, struct file *file); 43extern int video_exclusive_open(struct inode *inode, struct file *file);
88extern int video_exclusive_release(struct inode *inode, struct file *file); 44extern int video_exclusive_release(struct inode *inode, struct file *file);
89extern int video_usercopy(struct inode *inode, struct file *file,
90 unsigned int cmd, unsigned long arg,
91 int (*func)(struct inode *inode, struct file *file,
92 unsigned int cmd, void *arg));
93#endif /* __KERNEL__ */ 45#endif /* __KERNEL__ */
94 46
95#define VID_TYPE_CAPTURE 1 /* Can capture */
96#define VID_TYPE_TUNER 2 /* Can tune */
97#define VID_TYPE_TELETEXT 4 /* Does teletext */
98#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
99#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
100#define VID_TYPE_CLIPPING 32 /* Can clip */
101#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
102#define VID_TYPE_SCALES 128 /* Scalable */
103#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
104#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
105#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
106#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
107#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
108#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
109
110struct video_capability 47struct video_capability
111{ 48{
112 char name[32]; 49 char name[32];
@@ -202,9 +139,9 @@ struct video_audio
202#define VIDEO_SOUND_STEREO 2 139#define VIDEO_SOUND_STEREO 2
203#define VIDEO_SOUND_LANG1 4 140#define VIDEO_SOUND_LANG1 4
204#define VIDEO_SOUND_LANG2 8 141#define VIDEO_SOUND_LANG2 8
205 __u16 mode; 142 __u16 mode;
206 __u16 balance; /* Stereo balance */ 143 __u16 balance; /* Stereo balance */
207 __u16 step; /* Step actual volume uses */ 144 __u16 step; /* Step actual volume uses */
208}; 145};
209 146
210struct video_clip 147struct video_clip
@@ -260,9 +197,6 @@ struct video_key
260 __u32 flags; 197 __u32 flags;
261}; 198};
262 199
263
264#define VIDEO_MAX_FRAME 32
265
266struct video_mbuf 200struct video_mbuf
267{ 201{
268 int size; /* Total memory to map */ 202 int size; /* Total memory to map */
@@ -270,10 +204,8 @@ struct video_mbuf
270 int offsets[VIDEO_MAX_FRAME]; 204 int offsets[VIDEO_MAX_FRAME];
271}; 205};
272 206
273
274#define VIDEO_NO_UNIT (-1) 207#define VIDEO_NO_UNIT (-1)
275 208
276
277struct video_unit 209struct video_unit
278{ 210{
279 int video; /* Video minor */ 211 int video; /* Video minor */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 89a055761bed..a114fff6568b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -15,16 +15,99 @@
15 */ 15 */
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17#include <linux/time.h> /* need struct timeval */ 17#include <linux/time.h> /* need struct timeval */
18#include <linux/poll.h>
19#include <linux/device.h>
18#endif 20#endif
19#include <linux/compiler.h> /* need __user */ 21#include <linux/compiler.h> /* need __user */
20 22
23
24#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.15 */
25#define HAVE_V4L2 1
26
27/*
28 * Common stuff for both V4L1 and V4L2
29 * Moved from videodev.h
30 */
31
32#define VIDEO_MAX_FRAME 32
33
34#define VID_TYPE_CAPTURE 1 /* Can capture */
35#define VID_TYPE_TUNER 2 /* Can tune */
36#define VID_TYPE_TELETEXT 4 /* Does teletext */
37#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
38#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
39#define VID_TYPE_CLIPPING 32 /* Can clip */
40#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
41#define VID_TYPE_SCALES 128 /* Scalable */
42#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
43#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
44#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
45#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
46#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
47#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
48
49#ifdef __KERNEL__
50
51#define VFL_TYPE_GRABBER 0
52#define VFL_TYPE_VBI 1
53#define VFL_TYPE_RADIO 2
54#define VFL_TYPE_VTX 3
55
56struct video_device
57{
58 /* device info */
59 struct device *dev;
60 char name[32];
61 int type; /* v4l1 */
62 int type2; /* v4l2 */
63 int hardware;
64 int minor;
65
66 /* device ops + callbacks */
67 struct file_operations *fops;
68 void (*release)(struct video_device *vfd);
69
70
71#if OBSOLETE_OWNER /* to be removed in 2.6.15 */
72 /* obsolete -- fops->owner is used instead */
73 struct module *owner;
74 /* dev->driver_data will be used instead some day.
75 * Use the video_{get|set}_drvdata() helper functions,
76 * so the switch over will be transparent for you.
77 * Or use {pci|usb}_{get|set}_drvdata() directly. */
78 void *priv;
79#endif
80
81 /* for videodev.c intenal usage -- please don't touch */
82 int users; /* video_exclusive_{open|close} ... */
83 struct semaphore lock; /* ... helper function uses these */
84 char devfs_name[64]; /* devfs */
85 struct class_device class_dev; /* sysfs */
86};
87
88#define VIDEO_MAJOR 81
89
90extern int video_register_device(struct video_device *, int type, int nr);
91extern void video_unregister_device(struct video_device *);
92extern int video_usercopy(struct inode *inode, struct file *file,
93 unsigned int cmd, unsigned long arg,
94 int (*func)(struct inode *inode, struct file *file,
95 unsigned int cmd, void *arg));
96
97/* helper functions to alloc / release struct video_device, the
98 later can be used for video_device->release() */
99struct video_device *video_device_alloc(void);
100void video_device_release(struct video_device *vfd);
101
102#endif
103
21/* 104/*
22 * M I S C E L L A N E O U S 105 * M I S C E L L A N E O U S
23 */ 106 */
24 107
25/* Four-character-code (FOURCC) */ 108/* Four-character-code (FOURCC) */
26#define v4l2_fourcc(a,b,c,d)\ 109#define v4l2_fourcc(a,b,c,d)\
27 (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) 110 (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
28 111
29/* 112/*
30 * E N U M S 113 * E N U M S
@@ -154,20 +237,20 @@ struct v4l2_capability
154}; 237};
155 238
156/* Values for 'capabilities' field */ 239/* Values for 'capabilities' field */
157#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ 240#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
158#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ 241#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
159#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ 242#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
160#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ 243#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
161#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ 244#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
162#if 1 245#if 1
163#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ 246#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
164#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ 247#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
165#endif 248#endif
166#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ 249#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
167 250
168#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ 251#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
169#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ 252#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
170#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ 253#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
171 254
172#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ 255#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
173#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ 256#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
@@ -179,13 +262,13 @@ struct v4l2_capability
179 262
180struct v4l2_pix_format 263struct v4l2_pix_format
181{ 264{
182 __u32 width; 265 __u32 width;
183 __u32 height; 266 __u32 height;
184 __u32 pixelformat; 267 __u32 pixelformat;
185 enum v4l2_field field; 268 enum v4l2_field field;
186 __u32 bytesperline; /* for padding, zero if unused */ 269 __u32 bytesperline; /* for padding, zero if unused */
187 __u32 sizeimage; 270 __u32 sizeimage;
188 enum v4l2_colorspace colorspace; 271 enum v4l2_colorspace colorspace;
189 __u32 priv; /* private data, depends on pixelformat */ 272 __u32 priv; /* private data, depends on pixelformat */
190}; 273};
191 274
@@ -238,12 +321,12 @@ struct v4l2_pix_format
238 */ 321 */
239struct v4l2_fmtdesc 322struct v4l2_fmtdesc
240{ 323{
241 __u32 index; /* Format number */ 324 __u32 index; /* Format number */
242 enum v4l2_buf_type type; /* buffer type */ 325 enum v4l2_buf_type type; /* buffer type */
243 __u32 flags; 326 __u32 flags;
244 __u8 description[32]; /* Description string */ 327 __u8 description[32]; /* Description string */
245 __u32 pixelformat; /* Format fourcc */ 328 __u32 pixelformat; /* Format fourcc */
246 __u32 reserved[4]; 329 __u32 reserved[4];
247}; 330};
248 331
249#define V4L2_FMT_FLAG_COMPRESSED 0x0001 332#define V4L2_FMT_FLAG_COMPRESSED 0x0001
@@ -393,7 +476,7 @@ struct v4l2_jpegcompression
393#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ 476#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
394#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ 477#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
395#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will 478#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
396 * allways use APP0 */ 479 * allways use APP0 */
397}; 480};
398 481
399 482
@@ -402,10 +485,10 @@ struct v4l2_jpegcompression
402 */ 485 */
403struct v4l2_requestbuffers 486struct v4l2_requestbuffers
404{ 487{
405 __u32 count; 488 __u32 count;
406 enum v4l2_buf_type type; 489 enum v4l2_buf_type type;
407 enum v4l2_memory memory; 490 enum v4l2_memory memory;
408 __u32 reserved[2]; 491 __u32 reserved[2];
409}; 492};
410 493
411struct v4l2_buffer 494struct v4l2_buffer
@@ -511,9 +594,9 @@ struct v4l2_outputparm
511 594
512struct v4l2_cropcap { 595struct v4l2_cropcap {
513 enum v4l2_buf_type type; 596 enum v4l2_buf_type type;
514 struct v4l2_rect bounds; 597 struct v4l2_rect bounds;
515 struct v4l2_rect defrect; 598 struct v4l2_rect defrect;
516 struct v4l2_fract pixelaspect; 599 struct v4l2_fract pixelaspect;
517}; 600};
518 601
519struct v4l2_crop { 602struct v4l2_crop {
@@ -544,6 +627,7 @@ typedef __u64 v4l2_std_id;
544 627
545#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) 628#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
546#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) 629#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
630#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
547 631
548#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) 632#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
549#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) 633#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
@@ -581,13 +665,14 @@ typedef __u64 v4l2_std_id;
581 665
582#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ 666#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
583 V4L2_STD_PAL_60 |\ 667 V4L2_STD_PAL_60 |\
584 V4L2_STD_NTSC) 668 V4L2_STD_NTSC |\
669 V4L2_STD_NTSC_443)
585#define V4L2_STD_625_50 (V4L2_STD_PAL |\ 670#define V4L2_STD_625_50 (V4L2_STD_PAL |\
586 V4L2_STD_PAL_N |\ 671 V4L2_STD_PAL_N |\
587 V4L2_STD_PAL_Nc |\ 672 V4L2_STD_PAL_Nc |\
588 V4L2_STD_SECAM) 673 V4L2_STD_SECAM)
589#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ 674#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\
590 V4L2_STD_ATSC_16_VSB) 675 V4L2_STD_ATSC_16_VSB)
591 676
592#define V4L2_STD_UNKNOWN 0 677#define V4L2_STD_UNKNOWN 0
593#define V4L2_STD_ALL (V4L2_STD_525_60 |\ 678#define V4L2_STD_ALL (V4L2_STD_525_60 |\
@@ -595,7 +680,7 @@ typedef __u64 v4l2_std_id;
595 680
596struct v4l2_standard 681struct v4l2_standard
597{ 682{
598 __u32 index; 683 __u32 index;
599 v4l2_std_id id; 684 v4l2_std_id id;
600 __u8 name[24]; 685 __u8 name[24];
601 struct v4l2_fract frameperiod; /* Frames, not fields */ 686 struct v4l2_fract frameperiod; /* Frames, not fields */
@@ -610,9 +695,9 @@ struct v4l2_standard
610struct v4l2_input 695struct v4l2_input
611{ 696{
612 __u32 index; /* Which input */ 697 __u32 index; /* Which input */
613 __u8 name[32]; /* Label */ 698 __u8 name[32]; /* Label */
614 __u32 type; /* Type of input */ 699 __u32 type; /* Type of input */
615 __u32 audioset; /* Associated audios (bitfield) */ 700 __u32 audioset; /* Associated audios (bitfield) */
616 __u32 tuner; /* Associated tuner */ 701 __u32 tuner; /* Associated tuner */
617 v4l2_std_id std; 702 v4l2_std_id std;
618 __u32 status; 703 __u32 status;
@@ -647,9 +732,9 @@ struct v4l2_input
647struct v4l2_output 732struct v4l2_output
648{ 733{
649 __u32 index; /* Which output */ 734 __u32 index; /* Which output */
650 __u8 name[32]; /* Label */ 735 __u8 name[32]; /* Label */
651 __u32 type; /* Type of output */ 736 __u32 type; /* Type of output */
652 __u32 audioset; /* Associated audios (bitfield) */ 737 __u32 audioset; /* Associated audios (bitfield) */
653 __u32 modulator; /* Associated modulator */ 738 __u32 modulator; /* Associated modulator */
654 v4l2_std_id std; 739 v4l2_std_id std;
655 __u32 reserved[4]; 740 __u32 reserved[4];
@@ -671,12 +756,12 @@ struct v4l2_control
671/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ 756/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
672struct v4l2_queryctrl 757struct v4l2_queryctrl
673{ 758{
674 __u32 id; 759 __u32 id;
675 enum v4l2_ctrl_type type; 760 enum v4l2_ctrl_type type;
676 __u8 name[32]; /* Whatever */ 761 __u8 name[32]; /* Whatever */
677 __s32 minimum; /* Note signedness */ 762 __s32 minimum; /* Note signedness */
678 __s32 maximum; 763 __s32 maximum;
679 __s32 step; 764 __s32 step;
680 __s32 default_value; 765 __s32 default_value;
681 __u32 flags; 766 __u32 flags;
682 __u32 reserved[2]; 767 __u32 reserved[2];
@@ -779,10 +864,10 @@ struct v4l2_modulator
779 864
780struct v4l2_frequency 865struct v4l2_frequency
781{ 866{
782 __u32 tuner; 867 __u32 tuner;
783 enum v4l2_tuner_type type; 868 enum v4l2_tuner_type type;
784 __u32 frequency; 869 __u32 frequency;
785 __u32 reserved[8]; 870 __u32 reserved[8];
786}; 871};
787 872
788/* 873/*
@@ -802,6 +887,7 @@ struct v4l2_audio
802 887
803/* Flags for the 'mode' field */ 888/* Flags for the 'mode' field */
804#define V4L2_AUDMODE_AVL 0x00001 889#define V4L2_AUDMODE_AVL 0x00001
890#define V4L2_AUDMODE_32BITS 0x00002
805 891
806struct v4l2_audioout 892struct v4l2_audioout
807{ 893{
@@ -846,14 +932,14 @@ struct v4l2_vbi_format
846 932
847struct v4l2_sliced_vbi_format 933struct v4l2_sliced_vbi_format
848{ 934{
849 __u16 service_set; 935 __u16 service_set;
850 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field 936 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
851 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field 937 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
852 (equals frame lines 313-336 for 625 line video 938 (equals frame lines 313-336 for 625 line video
853 standards, 263-286 for 525 line standards) */ 939 standards, 263-286 for 525 line standards) */
854 __u16 service_lines[2][24]; 940 __u16 service_lines[2][24];
855 __u32 io_size; 941 __u32 io_size;
856 __u32 reserved[2]; /* must be zero */ 942 __u32 reserved[2]; /* must be zero */
857}; 943};
858 944
859#define V4L2_SLICED_TELETEXT_B (0x0001) 945#define V4L2_SLICED_TELETEXT_B (0x0001)
@@ -866,22 +952,22 @@ struct v4l2_sliced_vbi_format
866 952
867struct v4l2_sliced_vbi_cap 953struct v4l2_sliced_vbi_cap
868{ 954{
869 __u16 service_set; 955 __u16 service_set;
870 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field 956 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
871 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field 957 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
872 (equals frame lines 313-336 for 625 line video 958 (equals frame lines 313-336 for 625 line video
873 standards, 263-286 for 525 line standards) */ 959 standards, 263-286 for 525 line standards) */
874 __u16 service_lines[2][24]; 960 __u16 service_lines[2][24];
875 __u32 reserved[4]; /* must be 0 */ 961 __u32 reserved[4]; /* must be 0 */
876}; 962};
877 963
878struct v4l2_sliced_vbi_data 964struct v4l2_sliced_vbi_data
879{ 965{
880 __u32 id; 966 __u32 id;
881 __u32 field; /* 0: first field, 1: second field */ 967 __u32 field; /* 0: first field, 1: second field */
882 __u32 line; /* 1-23 */ 968 __u32 line; /* 1-23 */
883 __u32 reserved; /* must be 0 */ 969 __u32 reserved; /* must be 0 */
884 __u8 data[48]; 970 __u8 data[48];
885}; 971};
886#endif 972#endif
887 973
@@ -896,9 +982,9 @@ struct v4l2_format
896 enum v4l2_buf_type type; 982 enum v4l2_buf_type type;
897 union 983 union
898 { 984 {
899 struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE 985 struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
900 struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY 986 struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
901 struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE 987 struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
902#if 1 988#if 1
903 struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE 989 struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
904#endif 990#endif
@@ -981,6 +1067,7 @@ struct v4l2_streamparm
981#if 1 1067#if 1
982#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap) 1068#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap)
983#endif 1069#endif
1070#define VIDIOC_LOG_STATUS _IO ('V', 70)
984 1071
985/* for compatibility, will go away some day */ 1072/* for compatibility, will go away some day */
986#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) 1073#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index a7ceee9fc5e9..b7d4b0930408 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -4,6 +4,23 @@
4#ifndef AUDIOCHIP_H 4#ifndef AUDIOCHIP_H
5#define AUDIOCHIP_H 5#define AUDIOCHIP_H
6 6
7enum audiochip {
8 AUDIO_CHIP_NONE,
9 AUDIO_CHIP_UNKNOWN,
10 /* Provided by video chip */
11 AUDIO_CHIP_INTERNAL,
12 /* Provided by tvaudio.c */
13 AUDIO_CHIP_TDA8425,
14 AUDIO_CHIP_TEA6300,
15 AUDIO_CHIP_TEA6420,
16 AUDIO_CHIP_TDA9840,
17 AUDIO_CHIP_TDA985X,
18 AUDIO_CHIP_TDA9874,
19 AUDIO_CHIP_PIC16C54,
20 /* Provided by msp3400.c */
21 AUDIO_CHIP_MSP34XX
22};
23
7/* ---------------------------------------------------------------------- */ 24/* ---------------------------------------------------------------------- */
8 25
9/* v4l device was opened in Radio mode */ 26/* v4l device was opened in Radio mode */
diff --git a/include/media/id.h b/include/media/id.h
deleted file mode 100644
index 6d02c94cdc0d..000000000000
--- a/include/media/id.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 */
3
4/* FIXME: this temporarely, until these are included in linux/i2c-id.h */
5
6/* drivers */
7#ifndef I2C_DRIVERID_TVMIXER
8# define I2C_DRIVERID_TVMIXER I2C_DRIVERID_EXP0
9#endif
10#ifndef I2C_DRIVERID_TVAUDIO
11# define I2C_DRIVERID_TVAUDIO I2C_DRIVERID_EXP1
12#endif
13
14/* chips */
15#ifndef I2C_DRIVERID_DPL3518
16# define I2C_DRIVERID_DPL3518 I2C_DRIVERID_EXP2
17#endif
18#ifndef I2C_DRIVERID_TDA9873
19# define I2C_DRIVERID_TDA9873 I2C_DRIVERID_EXP3
20#endif
21#ifndef I2C_DRIVERID_TDA9875
22# define I2C_DRIVERID_TDA9875 I2C_DRIVERID_EXP0+4
23#endif
24#ifndef I2C_DRIVERID_PIC16C54_PV951
25# define I2C_DRIVERID_PIC16C54_PV951 I2C_DRIVERID_EXP0+5
26#endif
27#ifndef I2C_DRIVERID_TDA7432
28# define I2C_DRIVERID_TDA7432 I2C_DRIVERID_EXP0+6
29#endif
30#ifndef I2C_DRIVERID_TDA9874
31# define I2C_DRIVERID_TDA9874 I2C_DRIVERID_EXP0+7
32#endif
33#ifndef I2C_DRIVERID_SAA6752HS
34# define I2C_DRIVERID_SAA6752HS I2C_DRIVERID_EXP0+8
35#endif
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 01b56822df4d..0f1ba95ec8d6 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -20,8 +20,10 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23#include <linux/input.h> 23#ifndef _IR_COMMON
24#define _IR_COMMON
24 25
26#include <linux/input.h>
25 27
26#define IR_TYPE_RC5 1 28#define IR_TYPE_RC5 1
27#define IR_TYPE_PD 2 /* Pulse distance encoded IR */ 29#define IR_TYPE_PD 2 /* Pulse distance encoded IR */
@@ -61,6 +63,8 @@ int ir_dump_samples(u32 *samples, int count);
61int ir_decode_biphase(u32 *samples, int count, int low, int high); 63int ir_decode_biphase(u32 *samples, int count, int low, int high);
62int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); 64int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
63 65
66#endif
67
64/* 68/*
65 * Local variables: 69 * Local variables:
66 * c-basic-offset: 8 70 * c-basic-offset: 8
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
new file mode 100644
index 000000000000..00fa57eb9fde
--- /dev/null
+++ b/include/media/ir-kbd-i2c.h
@@ -0,0 +1,22 @@
1#ifndef _IR_I2C
2#define _IR_I2C
3
4#include <media/ir-common.h>
5
6struct IR_i2c;
7
8struct IR_i2c {
9 IR_KEYTAB_TYPE *ir_codes;
10 struct i2c_client c;
11 struct input_dev *input;
12 struct ir_input_state ir;
13
14 /* Used to avoid fast repeating */
15 unsigned char old;
16
17 struct work_struct work;
18 struct timer_list timer;
19 char phys[32];
20 int (*get_key)(struct IR_i2c*, u32*, u32*);
21};
22#endif
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index f3aa24f8131c..64691753721e 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -1,7 +1,7 @@
1#ifndef __SAA7146_VV__ 1#ifndef __SAA7146_VV__
2#define __SAA7146_VV__ 2#define __SAA7146_VV__
3 3
4#include <linux/videodev2.h> 4#include <linux/videodev.h>
5 5
6#include <media/saa7146.h> 6#include <media/saa7146.h>
7#include <media/video-buf.h> 7#include <media/video-buf.h>
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 4ad08e24a1aa..9184e534b7ef 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -95,7 +95,7 @@
95#define TUNER_THOMSON_DTT7610 52 95#define TUNER_THOMSON_DTT7610 52
96#define TUNER_PHILIPS_FQ1286 53 96#define TUNER_PHILIPS_FQ1286 53
97#define TUNER_PHILIPS_TDA8290 54 97#define TUNER_PHILIPS_TDA8290 54
98#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */ 98#define TUNER_TCL_2002MB 55 /* Hauppauge PVR-150 PAL */
99 99
100#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ 100#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
101#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ 101#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
@@ -110,6 +110,9 @@
110#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ 110#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */
111#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ 111#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */
112#define TUNER_LG_NTSC_TALN_MINI 66 112#define TUNER_LG_NTSC_TALN_MINI 66
113#define TUNER_PHILIPS_TD1316 67
114
115#define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */
113 116
114#define NOTUNER 0 117#define NOTUNER 0
115#define PAL 1 /* PAL_BG */ 118#define PAL 1 /* PAL_BG */
@@ -145,6 +148,7 @@
145# define TDA9887_INTERCARRIER (1<<4) 148# define TDA9887_INTERCARRIER (1<<4)
146# define TDA9887_PORT1_ACTIVE (1<<5) 149# define TDA9887_PORT1_ACTIVE (1<<5)
147# define TDA9887_PORT2_ACTIVE (1<<6) 150# define TDA9887_PORT2_ACTIVE (1<<6)
151# define TDA9887_INTERCARRIER_NTSC (1<<7)
148/* config options */ 152/* config options */
149# define TDA9887_DEEMPHASIS_MASK (3<<16) 153# define TDA9887_DEEMPHASIS_MASK (3<<16)
150# define TDA9887_DEEMPHASIS_NONE (1<<16) 154# define TDA9887_DEEMPHASIS_NONE (1<<16)
@@ -188,8 +192,11 @@ struct tuner {
188 unsigned int radio_if2; 192 unsigned int radio_if2;
189 193
190 /* used by tda8290 */ 194 /* used by tda8290 */
191 unsigned char i2c_easy_mode[2]; 195 unsigned char tda8290_easy_mode;
192 unsigned char i2c_set_freq[8]; 196 unsigned char tda827x_lpsel;
197 unsigned char tda827x_addr;
198 unsigned char tda827x_ver;
199 unsigned int sgIF;
193 200
194 /* function ptrs */ 201 /* function ptrs */
195 void (*tv_freq)(struct i2c_client *c, unsigned int freq); 202 void (*tv_freq)(struct i2c_client *c, unsigned int freq);
@@ -204,20 +211,21 @@ extern unsigned const int tuner_count;
204 211
205extern int microtune_init(struct i2c_client *c); 212extern int microtune_init(struct i2c_client *c);
206extern int tda8290_init(struct i2c_client *c); 213extern int tda8290_init(struct i2c_client *c);
214extern int tda8290_probe(struct i2c_client *c);
207extern int tea5767_tuner_init(struct i2c_client *c); 215extern int tea5767_tuner_init(struct i2c_client *c);
208extern int default_tuner_init(struct i2c_client *c); 216extern int default_tuner_init(struct i2c_client *c);
209extern int tea5767_autodetection(struct i2c_client *c); 217extern int tea5767_autodetection(struct i2c_client *c);
210 218
211#define tuner_warn(fmt, arg...) do {\ 219#define tuner_warn(fmt, arg...) do {\
212 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \ 220 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \
213 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 221 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
214#define tuner_info(fmt, arg...) do {\ 222#define tuner_info(fmt, arg...) do {\
215 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \ 223 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \
216 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 224 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
217#define tuner_dbg(fmt, arg...) do {\ 225#define tuner_dbg(fmt, arg...) do {\
218 if (tuner_debug) \ 226 if (tuner_debug) \
219 printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \ 227 printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \
220 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 228 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
221 229
222#endif /* __KERNEL__ */ 230#endif /* __KERNEL__ */
223 231
diff --git a/include/media/video-buf.h b/include/media/video-buf.h
index ae8d7a000440..8ecfd78e0027 100644
--- a/include/media/video-buf.h
+++ b/include/media/video-buf.h
@@ -17,7 +17,7 @@
17 * (at your option) any later version. 17 * (at your option) any later version.
18 */ 18 */
19 19
20#include <linux/videodev.h> 20#include <linux/videodev2.h>
21 21
22#define UNSET (-1U) 22#define UNSET (-1U)
23 23
@@ -177,7 +177,7 @@ struct videobuf_queue_ops {
177}; 177};
178 178
179struct videobuf_queue { 179struct videobuf_queue {
180 struct semaphore lock; 180 struct semaphore lock;
181 spinlock_t *irqlock; 181 spinlock_t *irqlock;
182 struct pci_dev *pci; 182 struct pci_dev *pci;
183 183
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
new file mode 100644
index 000000000000..52d8b1a73d52
--- /dev/null
+++ b/include/net/genetlink.h
@@ -0,0 +1,154 @@
1#ifndef __NET_GENERIC_NETLINK_H
2#define __NET_GENERIC_NETLINK_H
3
4#include <linux/genetlink.h>
5#include <net/netlink.h>
6
7/**
8 * struct genl_family - generic netlink family
9 * @id: protocol family idenfitier
10 * @hdrsize: length of user specific header in bytes
11 * @name: name of family
12 * @version: protocol version
13 * @maxattr: maximum number of attributes supported
14 * @attrbuf: buffer to store parsed attributes
15 * @ops_list: list of all assigned operations
16 * @family_list: family list
17 */
18struct genl_family
19{
20 unsigned int id;
21 unsigned int hdrsize;
22 char name[GENL_NAMSIZ];
23 unsigned int version;
24 unsigned int maxattr;
25 struct module * owner;
26 struct nlattr ** attrbuf; /* private */
27 struct list_head ops_list; /* private */
28 struct list_head family_list; /* private */
29};
30
31#define GENL_ADMIN_PERM 0x01
32
33/**
34 * struct genl_info - receiving information
35 * @snd_seq: sending sequence number
36 * @snd_pid: netlink pid of sender
37 * @nlhdr: netlink message header
38 * @genlhdr: generic netlink message header
39 * @userhdr: user specific header
40 * @attrs: netlink attributes
41 */
42struct genl_info
43{
44 u32 snd_seq;
45 u32 snd_pid;
46 struct nlmsghdr * nlhdr;
47 struct genlmsghdr * genlhdr;
48 void * userhdr;
49 struct nlattr ** attrs;
50};
51
52/**
53 * struct genl_ops - generic netlink operations
54 * @cmd: command identifier
55 * @flags: flags
56 * @policy: attribute validation policy
57 * @doit: standard command callback
58 * @dumpit: callback for dumpers
59 * @ops_list: operations list
60 */
61struct genl_ops
62{
63 unsigned int cmd;
64 unsigned int flags;
65 struct nla_policy *policy;
66 int (*doit)(struct sk_buff *skb,
67 struct genl_info *info);
68 int (*dumpit)(struct sk_buff *skb,
69 struct netlink_callback *cb);
70 struct list_head ops_list;
71};
72
73extern int genl_register_family(struct genl_family *family);
74extern int genl_unregister_family(struct genl_family *family);
75extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
76extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
77
78extern struct sock *genl_sock;
79
80/**
81 * genlmsg_put - Add generic netlink header to netlink message
82 * @skb: socket buffer holding the message
83 * @pid: netlink pid the message is addressed to
84 * @seq: sequence number (usually the one of the sender)
85 * @type: netlink message type
86 * @hdrlen: length of the user specific header
87 * @flags netlink message flags
88 * @cmd: generic netlink command
89 * @version: version
90 *
91 * Returns pointer to user specific header
92 */
93static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
94 int type, int hdrlen, int flags,
95 u8 cmd, u8 version)
96{
97 struct nlmsghdr *nlh;
98 struct genlmsghdr *hdr;
99
100 nlh = nlmsg_put(skb, pid, seq, type, GENL_HDRLEN + hdrlen, flags);
101 if (nlh == NULL)
102 return NULL;
103
104 hdr = nlmsg_data(nlh);
105 hdr->cmd = cmd;
106 hdr->version = version;
107 hdr->reserved = 0;
108
109 return (char *) hdr + GENL_HDRLEN;
110}
111
112/**
113 * genlmsg_end - Finalize a generic netlink message
114 * @skb: socket buffer the message is stored in
115 * @hdr: user specific header
116 */
117static inline int genlmsg_end(struct sk_buff *skb, void *hdr)
118{
119 return nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
120}
121
122/**
123 * genlmsg_cancel - Cancel construction of a generic netlink message
124 * @skb: socket buffer the message is stored in
125 * @hdr: generic netlink message header
126 */
127static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr)
128{
129 return nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
130}
131
132/**
133 * genlmsg_multicast - multicast a netlink message
134 * @skb: netlink message as socket buffer
135 * @pid: own netlink pid to avoid sending to yourself
136 * @group: multicast group id
137 */
138static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
139 unsigned int group)
140{
141 return nlmsg_multicast(genl_sock, skb, pid, group);
142}
143
144/**
145 * genlmsg_unicast - unicast a netlink message
146 * @skb: netlink message as socket buffer
147 * @pid: netlink pid of the destination socket
148 */
149static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
150{
151 return nlmsg_unicast(genl_sock, skb, pid);
152}
153
154#endif /* __NET_GENERIC_NETLINK_H */
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 5e38dca1d082..b93fd8c1d884 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -29,7 +29,7 @@
29#include <linux/kernel.h> /* ARRAY_SIZE */ 29#include <linux/kernel.h> /* ARRAY_SIZE */
30#include <linux/wireless.h> 30#include <linux/wireless.h>
31 31
32#define IEEE80211_VERSION "git-1.1.6" 32#define IEEE80211_VERSION "git-1.1.7"
33 33
34#define IEEE80211_DATA_LEN 2304 34#define IEEE80211_DATA_LEN 2304
35/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section 35/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index 0a1c2d82ca4b..225fc751d464 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -31,6 +31,7 @@ enum {
31 31
32struct ieee80211_crypto_ops { 32struct ieee80211_crypto_ops {
33 const char *name; 33 const char *name;
34 struct list_head list;
34 35
35 /* init new crypto context (e.g., allocate private data space, 36 /* init new crypto context (e.g., allocate private data space,
36 * select IV, etc.); returns NULL on failure or pointer to allocated 37 * select IV, etc.); returns NULL on failure or pointer to allocated
diff --git a/include/net/netfilter/ipv4/nf_conntrack_icmp.h b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
new file mode 100644
index 000000000000..3dd22cff23ec
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
@@ -0,0 +1,11 @@
1#ifndef _NF_CONNTRACK_ICMP_H
2#define _NF_CONNTRACK_ICMP_H
3/* ICMP tracking. */
4#include <asm/atomic.h>
5
6struct ip_ct_icmp
7{
8 /* Optimization: when number in == number out, forget immediately. */
9 atomic_t count;
10};
11#endif /* _NF_CONNTRACK_ICMP_H */
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
new file mode 100644
index 000000000000..25b081a730e6
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -0,0 +1,43 @@
1/*
2 * IPv4 support for nf_conntrack.
3 *
4 * 23 Mar 2004: Yasuyuki Kozakai @ USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - move L3 protocol dependent part from include/linux/netfilter_ipv4/
6 * ip_conntarck.h
7 */
8
9#ifndef _NF_CONNTRACK_IPV4_H
10#define _NF_CONNTRACK_IPV4_H
11
12#ifdef CONFIG_IP_NF_NAT_NEEDED
13#include <linux/netfilter_ipv4/ip_nat.h>
14
15/* per conntrack: nat application helper private data */
16union ip_conntrack_nat_help {
17 /* insert nat helper private data here */
18};
19
20struct nf_conntrack_ipv4_nat {
21 struct ip_nat_info info;
22 union ip_conntrack_nat_help help;
23#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
24 defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
25 int masq_index;
26#endif
27};
28#endif /* CONFIG_IP_NF_NAT_NEEDED */
29
30struct nf_conntrack_ipv4 {
31#ifdef CONFIG_IP_NF_NAT_NEEDED
32 struct nf_conntrack_ipv4_nat *nat;
33#endif
34};
35
36/* Returns new sk_buff, or NULL */
37struct sk_buff *
38nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
39
40/* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */
41extern void need_ip_conntrack(void);
42
43#endif /*_NF_CONNTRACK_IPV4_H*/
diff --git a/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
new file mode 100644
index 000000000000..86591afda29c
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
@@ -0,0 +1,27 @@
1/*
2 * ICMPv6 tracking.
3 *
4 * 21 Apl 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - separated from nf_conntrack_icmp.h
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_icmp.h
8 */
9
10#ifndef _NF_CONNTRACK_ICMPV6_H
11#define _NF_CONNTRACK_ICMPV6_H
12#include <asm/atomic.h>
13
14#ifndef ICMPV6_NI_QUERY
15#define ICMPV6_NI_QUERY 139
16#endif
17#ifndef ICMPV6_NI_REPLY
18#define ICMPV6_NI_REPLY 140
19#endif
20
21struct nf_ct_icmpv6
22{
23 /* Optimization: when number in == number out, forget immediately. */
24 atomic_t count;
25};
26
27#endif /* _NF_CONNTRACK_ICMPV6_H */
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
new file mode 100644
index 000000000000..cc4825610795
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack.h
@@ -0,0 +1,354 @@
1/*
2 * Connection state tracking for netfilter. This is separated from,
3 * but required by, the (future) NAT layer; it can also be used by an iptables
4 * extension.
5 *
6 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
7 * - generalize L3 protocol dependent part.
8 *
9 * Derived from include/linux/netfiter_ipv4/ip_conntrack.h
10 */
11
12#ifndef _NF_CONNTRACK_H
13#define _NF_CONNTRACK_H
14
15#include <linux/netfilter/nf_conntrack_common.h>
16
17#ifdef __KERNEL__
18#include <linux/config.h>
19#include <linux/bitops.h>
20#include <linux/compiler.h>
21#include <asm/atomic.h>
22
23#include <linux/netfilter/nf_conntrack_tcp.h>
24#include <linux/netfilter/nf_conntrack_sctp.h>
25#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
26#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
27
28#include <net/netfilter/nf_conntrack_tuple.h>
29
30/* per conntrack: protocol private data */
31union nf_conntrack_proto {
32 /* insert conntrack proto private data here */
33 struct ip_ct_sctp sctp;
34 struct ip_ct_tcp tcp;
35 struct ip_ct_icmp icmp;
36 struct nf_ct_icmpv6 icmpv6;
37};
38
39union nf_conntrack_expect_proto {
40 /* insert expect proto private data here */
41};
42
43/* Add protocol helper include file here */
44#include <linux/netfilter/nf_conntrack_ftp.h>
45
46/* per conntrack: application helper private data */
47union nf_conntrack_help {
48 /* insert conntrack helper private data (master) here */
49 struct ip_ct_ftp_master ct_ftp_info;
50};
51
52#include <linux/types.h>
53#include <linux/skbuff.h>
54
55#ifdef CONFIG_NETFILTER_DEBUG
56#define NF_CT_ASSERT(x) \
57do { \
58 if (!(x)) \
59 /* Wooah! I'm tripping my conntrack in a frenzy of \
60 netplay... */ \
61 printk("NF_CT_ASSERT: %s:%i(%s)\n", \
62 __FILE__, __LINE__, __FUNCTION__); \
63} while(0)
64#else
65#define NF_CT_ASSERT(x)
66#endif
67
68struct nf_conntrack_helper;
69
70#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
71struct nf_conn
72{
73 /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
74 plus 1 for any connection(s) we are `master' for */
75 struct nf_conntrack ct_general;
76
77 /* XXX should I move this to the tail ? - Y.K */
78 /* These are my tuples; original and reply */
79 struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
80
81 /* Have we seen traffic both ways yet? (bitset) */
82 unsigned long status;
83
84 /* Timer function; drops refcnt when it goes off. */
85 struct timer_list timeout;
86
87#ifdef CONFIG_NF_CT_ACCT
88 /* Accounting Information (same cache line as other written members) */
89 struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
90#endif
91 /* If we were expected by an expectation, this will be it */
92 struct nf_conn *master;
93
94 /* Current number of expected connections */
95 unsigned int expecting;
96
97 /* Helper. if any */
98 struct nf_conntrack_helper *helper;
99
100 /* features - nat, helper, ... used by allocating system */
101 u_int32_t features;
102
103 /* Storage reserved for other modules: */
104
105 union nf_conntrack_proto proto;
106
107#if defined(CONFIG_NF_CONNTRACK_MARK)
108 u_int32_t mark;
109#endif
110
111 /* These members are dynamically allocated. */
112
113 union nf_conntrack_help *help;
114
115 /* Layer 3 dependent members. (ex: NAT) */
116 union {
117 struct nf_conntrack_ipv4 *ipv4;
118 } l3proto;
119 void *data[0];
120};
121
122struct nf_conntrack_expect
123{
124 /* Internal linked list (global expectation list) */
125 struct list_head list;
126
127 /* We expect this tuple, with the following mask */
128 struct nf_conntrack_tuple tuple, mask;
129
130 /* Function to call after setup and insertion */
131 void (*expectfn)(struct nf_conn *new,
132 struct nf_conntrack_expect *this);
133
134 /* The conntrack of the master connection */
135 struct nf_conn *master;
136
137 /* Timer function; deletes the expectation. */
138 struct timer_list timeout;
139
140 /* Usage count. */
141 atomic_t use;
142
143 /* Flags */
144 unsigned int flags;
145
146#ifdef CONFIG_NF_NAT_NEEDED
147 /* This is the original per-proto part, used to map the
148 * expected connection the way the recipient expects. */
149 union nf_conntrack_manip_proto saved_proto;
150 /* Direction relative to the master connection. */
151 enum ip_conntrack_dir dir;
152#endif
153};
154
155#define NF_CT_EXPECT_PERMANENT 0x1
156
157static inline struct nf_conn *
158nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
159{
160 return container_of(hash, struct nf_conn,
161 tuplehash[hash->tuple.dst.dir]);
162}
163
164/* get master conntrack via master expectation */
165#define master_ct(conntr) (conntr->master)
166
167/* Alter reply tuple (maybe alter helper). */
168extern void
169nf_conntrack_alter_reply(struct nf_conn *conntrack,
170 const struct nf_conntrack_tuple *newreply);
171
172/* Is this tuple taken? (ignoring any belonging to the given
173 conntrack). */
174extern int
175nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
176 const struct nf_conn *ignored_conntrack);
177
178/* Return conntrack_info and tuple hash for given skb. */
179static inline struct nf_conn *
180nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
181{
182 *ctinfo = skb->nfctinfo;
183 return (struct nf_conn *)skb->nfct;
184}
185
186/* decrement reference count on a conntrack */
187static inline void nf_ct_put(struct nf_conn *ct)
188{
189 NF_CT_ASSERT(ct);
190 nf_conntrack_put(&ct->ct_general);
191}
192
193/* call to create an explicit dependency on nf_conntrack. */
194extern void need_nf_conntrack(void);
195
196extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
197 const struct nf_conntrack_tuple *orig);
198
199extern void __nf_ct_refresh_acct(struct nf_conn *ct,
200 enum ip_conntrack_info ctinfo,
201 const struct sk_buff *skb,
202 unsigned long extra_jiffies,
203 int do_acct);
204
205/* Refresh conntrack for this many jiffies and do accounting */
206static inline void nf_ct_refresh_acct(struct nf_conn *ct,
207 enum ip_conntrack_info ctinfo,
208 const struct sk_buff *skb,
209 unsigned long extra_jiffies)
210{
211 __nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);
212}
213
214/* Refresh conntrack for this many jiffies */
215static inline void nf_ct_refresh(struct nf_conn *ct,
216 const struct sk_buff *skb,
217 unsigned long extra_jiffies)
218{
219 __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
220}
221
222/* These are for NAT. Icky. */
223/* Update TCP window tracking data when NAT mangles the packet */
224extern void nf_conntrack_tcp_update(struct sk_buff *skb,
225 unsigned int dataoff,
226 struct nf_conn *conntrack,
227 int dir);
228
229/* Call me when a conntrack is destroyed. */
230extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
231
232/* Fake conntrack entry for untracked connections */
233extern struct nf_conn nf_conntrack_untracked;
234
235extern int nf_ct_no_defrag;
236
237/* Iterate over all conntracks: if iter returns true, it's deleted. */
238extern void
239nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
240extern void nf_conntrack_free(struct nf_conn *ct);
241extern struct nf_conn *
242nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
243 const struct nf_conntrack_tuple *repl);
244
245/* It's confirmed if it is, or has been in the hash table. */
246static inline int nf_ct_is_confirmed(struct nf_conn *ct)
247{
248 return test_bit(IPS_CONFIRMED_BIT, &ct->status);
249}
250
251static inline int nf_ct_is_dying(struct nf_conn *ct)
252{
253 return test_bit(IPS_DYING_BIT, &ct->status);
254}
255
256extern unsigned int nf_conntrack_htable_size;
257
258#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++)
259
260#ifdef CONFIG_NF_CONNTRACK_EVENTS
261#include <linux/notifier.h>
262#include <linux/interrupt.h>
263
264struct nf_conntrack_ecache {
265 struct nf_conn *ct;
266 unsigned int events;
267};
268DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
269
270#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x)
271
272extern struct notifier_block *nf_conntrack_chain;
273extern struct notifier_block *nf_conntrack_expect_chain;
274
275static inline int nf_conntrack_register_notifier(struct notifier_block *nb)
276{
277 return notifier_chain_register(&nf_conntrack_chain, nb);
278}
279
280static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb)
281{
282 return notifier_chain_unregister(&nf_conntrack_chain, nb);
283}
284
285static inline int
286nf_conntrack_expect_register_notifier(struct notifier_block *nb)
287{
288 return notifier_chain_register(&nf_conntrack_expect_chain, nb);
289}
290
291static inline int
292nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
293{
294 return notifier_chain_unregister(&nf_conntrack_expect_chain, nb);
295}
296
297extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
298extern void __nf_ct_event_cache_init(struct nf_conn *ct);
299
300static inline void
301nf_conntrack_event_cache(enum ip_conntrack_events event,
302 const struct sk_buff *skb)
303{
304 struct nf_conn *ct = (struct nf_conn *)skb->nfct;
305 struct nf_conntrack_ecache *ecache;
306
307 local_bh_disable();
308 ecache = &__get_cpu_var(nf_conntrack_ecache);
309 if (ct != ecache->ct)
310 __nf_ct_event_cache_init(ct);
311 ecache->events |= event;
312 local_bh_enable();
313}
314
315static inline void nf_conntrack_event(enum ip_conntrack_events event,
316 struct nf_conn *ct)
317{
318 if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
319 notifier_call_chain(&nf_conntrack_chain, event, ct);
320}
321
322static inline void
323nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
324 struct nf_conntrack_expect *exp)
325{
326 notifier_call_chain(&nf_conntrack_expect_chain, event, exp);
327}
328#else /* CONFIG_NF_CONNTRACK_EVENTS */
329static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
330 const struct sk_buff *skb) {}
331static inline void nf_conntrack_event(enum ip_conntrack_events event,
332 struct nf_conn *ct) {}
333static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
334static inline void
335nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
336 struct nf_conntrack_expect *exp) {}
337#endif /* CONFIG_NF_CONNTRACK_EVENTS */
338
339/* no helper, no nat */
340#define NF_CT_F_BASIC 0
341/* for helper */
342#define NF_CT_F_HELP 1
343/* for nat. */
344#define NF_CT_F_NAT 2
345#define NF_CT_F_NUM 4
346
347extern int
348nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size,
349 int (*init_conntrack)(struct nf_conn *, u_int32_t));
350extern void
351nf_conntrack_unregister_cache(u_int32_t features);
352
353#endif /* __KERNEL__ */
354#endif /* _NF_CONNTRACK_H */
diff --git a/include/net/netfilter/nf_conntrack_compat.h b/include/net/netfilter/nf_conntrack_compat.h
new file mode 100644
index 000000000000..3cac19fb3648
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_compat.h
@@ -0,0 +1,108 @@
1#ifndef _NF_CONNTRACK_COMPAT_H
2#define _NF_CONNTRACK_COMPAT_H
3
4#ifdef __KERNEL__
5
6#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
7
8#include <linux/netfilter_ipv4/ip_conntrack.h>
9
10#ifdef CONFIG_IP_NF_CONNTRACK_MARK
11static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
12 u_int32_t *ctinfo)
13{
14 struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
15
16 if (ct)
17 return &ct->mark;
18 else
19 return NULL;
20}
21#endif /* CONFIG_IP_NF_CONNTRACK_MARK */
22
23#ifdef CONFIG_IP_NF_CT_ACCT
24static inline struct ip_conntrack_counter *
25nf_ct_get_counters(const struct sk_buff *skb)
26{
27 enum ip_conntrack_info ctinfo;
28 struct ip_conntrack *ct = ip_conntrack_get(skb, &ctinfo);
29
30 if (ct)
31 return ct->counters;
32 else
33 return NULL;
34}
35#endif /* CONFIG_IP_NF_CT_ACCT */
36
37static inline int nf_ct_is_untracked(const struct sk_buff *skb)
38{
39 return (skb->nfct == &ip_conntrack_untracked.ct_general);
40}
41
42static inline void nf_ct_untrack(struct sk_buff *skb)
43{
44 skb->nfct = &ip_conntrack_untracked.ct_general;
45}
46
47static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
48 enum ip_conntrack_info *ctinfo)
49{
50 struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
51 return (ct != NULL);
52}
53
54#else /* CONFIG_IP_NF_CONNTRACK */
55
56#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
57#include <net/netfilter/nf_conntrack.h>
58
59#ifdef CONFIG_NF_CONNTRACK_MARK
60
61static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
62 u_int32_t *ctinfo)
63{
64 struct nf_conn *ct = nf_ct_get(skb, ctinfo);
65
66 if (ct)
67 return &ct->mark;
68 else
69 return NULL;
70}
71#endif /* CONFIG_NF_CONNTRACK_MARK */
72
73#ifdef CONFIG_NF_CT_ACCT
74static inline struct ip_conntrack_counter *
75nf_ct_get_counters(const struct sk_buff *skb)
76{
77 enum ip_conntrack_info ctinfo;
78 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
79
80 if (ct)
81 return ct->counters;
82 else
83 return NULL;
84}
85#endif /* CONFIG_NF_CT_ACCT */
86
87static inline int nf_ct_is_untracked(const struct sk_buff *skb)
88{
89 return (skb->nfct == &nf_conntrack_untracked.ct_general);
90}
91
92static inline void nf_ct_untrack(struct sk_buff *skb)
93{
94 skb->nfct = &nf_conntrack_untracked.ct_general;
95}
96
97static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
98 enum ip_conntrack_info *ctinfo)
99{
100 struct nf_conn *ct = nf_ct_get(skb, ctinfo);
101 return (ct != NULL);
102}
103
104#endif /* CONFIG_IP_NF_CONNTRACK */
105
106#endif /* __KERNEL__ */
107
108#endif /* _NF_CONNTRACK_COMPAT_H */
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
new file mode 100644
index 000000000000..da254525a4ce
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -0,0 +1,76 @@
1/*
2 * This header is used to share core functionality between the
3 * standalone connection tracking module, and the compatibility layer's use
4 * of connection tracking.
5 *
6 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
7 * - generalize L3 protocol dependent part.
8 *
9 * Derived from include/linux/netfiter_ipv4/ip_conntrack_core.h
10 */
11
12#ifndef _NF_CONNTRACK_CORE_H
13#define _NF_CONNTRACK_CORE_H
14
15#include <linux/netfilter.h>
16
17/* This header is used to share core functionality between the
18 standalone connection tracking module, and the compatibility layer's use
19 of connection tracking. */
20extern unsigned int nf_conntrack_in(int pf,
21 unsigned int hooknum,
22 struct sk_buff **pskb);
23
24extern int nf_conntrack_init(void);
25extern void nf_conntrack_cleanup(void);
26
27struct nf_conntrack_l3proto;
28extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
29/* Like above, but you already have conntrack read lock. */
30extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto);
31
32struct nf_conntrack_protocol;
33
34extern int
35nf_ct_get_tuple(const struct sk_buff *skb,
36 unsigned int nhoff,
37 unsigned int dataoff,
38 u_int16_t l3num,
39 u_int8_t protonum,
40 struct nf_conntrack_tuple *tuple,
41 const struct nf_conntrack_l3proto *l3proto,
42 const struct nf_conntrack_protocol *protocol);
43
44extern int
45nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
46 const struct nf_conntrack_tuple *orig,
47 const struct nf_conntrack_l3proto *l3proto,
48 const struct nf_conntrack_protocol *protocol);
49
50/* Find a connection corresponding to a tuple. */
51extern struct nf_conntrack_tuple_hash *
52nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
53 const struct nf_conn *ignored_conntrack);
54
55extern int __nf_conntrack_confirm(struct sk_buff **pskb);
56
57/* Confirm a connection: returns NF_DROP if packet must be dropped. */
58static inline int nf_conntrack_confirm(struct sk_buff **pskb)
59{
60 struct nf_conn *ct = (struct nf_conn *)(*pskb)->nfct;
61 int ret = NF_ACCEPT;
62
63 if (ct) {
64 if (!nf_ct_is_confirmed(ct))
65 ret = __nf_conntrack_confirm(pskb);
66 nf_ct_deliver_cached_events(ct);
67 }
68 return ret;
69}
70
71extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb);
72
73extern struct list_head *nf_conntrack_hash;
74extern struct list_head nf_conntrack_expect_list;
75extern rwlock_t nf_conntrack_lock ;
76#endif /* _NF_CONNTRACK_CORE_H */
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
new file mode 100644
index 000000000000..5a66b2a3a623
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -0,0 +1,51 @@
1/*
2 * connection tracking helpers.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalize L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_helper.h
8 */
9
10#ifndef _NF_CONNTRACK_HELPER_H
11#define _NF_CONNTRACK_HELPER_H
12#include <net/netfilter/nf_conntrack.h>
13
14struct module;
15
16struct nf_conntrack_helper
17{
18 struct list_head list; /* Internal use. */
19
20 const char *name; /* name of the module */
21 struct module *me; /* pointer to self */
22 unsigned int max_expected; /* Maximum number of concurrent
23 * expected connections */
24 unsigned int timeout; /* timeout for expecteds */
25
26 /* Mask of things we will help (compared against server response) */
27 struct nf_conntrack_tuple tuple;
28 struct nf_conntrack_tuple mask;
29
30 /* Function to call when data passes; return verdict, or -1 to
31 invalidate. */
32 int (*help)(struct sk_buff **pskb,
33 unsigned int protoff,
34 struct nf_conn *ct,
35 enum ip_conntrack_info conntrackinfo);
36};
37
38extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
39extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
40
41/* Allocate space for an expectation: this is mandatory before calling
42 nf_conntrack_expect_related. You will have to call put afterwards. */
43extern struct nf_conntrack_expect *
44nf_conntrack_expect_alloc(struct nf_conn *master);
45extern void nf_conntrack_expect_put(struct nf_conntrack_expect *exp);
46
47/* Add an expected connection: can have more than one per connection */
48extern int nf_conntrack_expect_related(struct nf_conntrack_expect *exp);
49extern void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp);
50
51#endif /*_NF_CONNTRACK_HELPER_H*/
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
new file mode 100644
index 000000000000..01663e5b33df
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -0,0 +1,93 @@
1/*
2 * Copyright (C)2003,2004 USAGI/WIDE Project
3 *
4 * Header for use in defining a given L3 protocol for connection tracking.
5 *
6 * Author:
7 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
8 *
9 * Derived from include/netfilter_ipv4/ip_conntrack_protocol.h
10 */
11
12#ifndef _NF_CONNTRACK_L3PROTO_H
13#define _NF_CONNTRACK_L3PROTO_H
14#include <linux/seq_file.h>
15#include <net/netfilter/nf_conntrack.h>
16
17struct nf_conntrack_l3proto
18{
19 /* Next pointer. */
20 struct list_head list;
21
22 /* L3 Protocol Family number. ex) PF_INET */
23 u_int16_t l3proto;
24
25 /* Protocol name */
26 const char *name;
27
28 /*
29 * Try to fill in the third arg: nhoff is offset of l3 proto
30 * hdr. Return true if possible.
31 */
32 int (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff,
33 struct nf_conntrack_tuple *tuple);
34
35 /*
36 * Invert the per-proto part of the tuple: ie. turn xmit into reply.
37 * Some packets can't be inverted: return 0 in that case.
38 */
39 int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
40 const struct nf_conntrack_tuple *orig);
41
42 /* Print out the per-protocol part of the tuple. */
43 int (*print_tuple)(struct seq_file *s,
44 const struct nf_conntrack_tuple *);
45
46 /* Print out the private part of the conntrack. */
47 int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
48
49 /* Returns verdict for packet, or -1 for invalid. */
50 int (*packet)(struct nf_conn *conntrack,
51 const struct sk_buff *skb,
52 enum ip_conntrack_info ctinfo);
53
54 /*
55 * Called when a new connection for this protocol found;
56 * returns TRUE if it's OK. If so, packet() called next.
57 */
58 int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb);
59
60 /* Called when a conntrack entry is destroyed */
61 void (*destroy)(struct nf_conn *conntrack);
62
63 /*
64 * Called before tracking.
65 * *dataoff: offset of protocol header (TCP, UDP,...) in *pskb
66 * *protonum: protocol number
67 */
68 int (*prepare)(struct sk_buff **pskb, unsigned int hooknum,
69 unsigned int *dataoff, u_int8_t *protonum);
70
71 u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
72
73 /* Module (if any) which this is connected to. */
74 struct module *me;
75};
76
77extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
78
79/* Protocol registration. */
80extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
81extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
82
83static inline struct nf_conntrack_l3proto *
84nf_ct_find_l3proto(u_int16_t l3proto)
85{
86 return nf_ct_l3protos[l3proto];
87}
88
89/* Existing built-in protocols */
90extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
91extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
92extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
93#endif /*_NF_CONNTRACK_L3PROTO_H*/
diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_protocol.h
new file mode 100644
index 000000000000..b3afda35397a
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_protocol.h
@@ -0,0 +1,105 @@
1/*
2 * Header for use in defining a given protocol for connection tracking.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalized L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h
8 */
9
10#ifndef _NF_CONNTRACK_PROTOCOL_H
11#define _NF_CONNTRACK_PROTOCOL_H
12#include <net/netfilter/nf_conntrack.h>
13
14struct seq_file;
15
16struct nf_conntrack_protocol
17{
18 /* Next pointer. */
19 struct list_head list;
20
21 /* L3 Protocol number. */
22 u_int16_t l3proto;
23
24 /* Protocol number. */
25 u_int8_t proto;
26
27 /* Protocol name */
28 const char *name;
29
30 /* Try to fill in the third arg: dataoff is offset past network protocol
31 hdr. Return true if possible. */
32 int (*pkt_to_tuple)(const struct sk_buff *skb,
33 unsigned int dataoff,
34 struct nf_conntrack_tuple *tuple);
35
36 /* Invert the per-proto part of the tuple: ie. turn xmit into reply.
37 * Some packets can't be inverted: return 0 in that case.
38 */
39 int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
40 const struct nf_conntrack_tuple *orig);
41
42 /* Print out the per-protocol part of the tuple. Return like seq_* */
43 int (*print_tuple)(struct seq_file *s,
44 const struct nf_conntrack_tuple *);
45
46 /* Print out the private part of the conntrack. */
47 int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
48
49 /* Returns verdict for packet, or -1 for invalid. */
50 int (*packet)(struct nf_conn *conntrack,
51 const struct sk_buff *skb,
52 unsigned int dataoff,
53 enum ip_conntrack_info ctinfo,
54 int pf,
55 unsigned int hooknum);
56
57 /* Called when a new connection for this protocol found;
58 * returns TRUE if it's OK. If so, packet() called next. */
59 int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb,
60 unsigned int dataoff);
61
62 /* Called when a conntrack entry is destroyed */
63 void (*destroy)(struct nf_conn *conntrack);
64
65 int (*error)(struct sk_buff *skb, unsigned int dataoff,
66 enum ip_conntrack_info *ctinfo,
67 int pf, unsigned int hooknum);
68
69 /* Module (if any) which this is connected to. */
70 struct module *me;
71};
72
73/* Existing built-in protocols */
74extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
75extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
76extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
77extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
78
79#define MAX_NF_CT_PROTO 256
80extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
81
82extern struct nf_conntrack_protocol *
83nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol);
84
85/* Protocol registration. */
86extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto);
87extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto);
88
89/* Log invalid packets */
90extern unsigned int nf_ct_log_invalid;
91
92#ifdef CONFIG_SYSCTL
93#ifdef DEBUG_INVALID_PACKETS
94#define LOG_INVALID(proto) \
95 (nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW)
96#else
97#define LOG_INVALID(proto) \
98 ((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \
99 && net_ratelimit())
100#endif
101#else
102#define LOG_INVALID(proto) 0
103#endif /* CONFIG_SYSCTL */
104
105#endif /*_NF_CONNTRACK_PROTOCOL_H*/
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
new file mode 100644
index 000000000000..14ce790e5c65
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -0,0 +1,190 @@
1/*
2 * Definitions and Declarations for tuple.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalize L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
8 */
9
10#ifndef _NF_CONNTRACK_TUPLE_H
11#define _NF_CONNTRACK_TUPLE_H
12
13#include <linux/netfilter/nf_conntrack_tuple_common.h>
14
15/* A `tuple' is a structure containing the information to uniquely
16 identify a connection. ie. if two packets have the same tuple, they
17 are in the same connection; if not, they are not.
18
19 We divide the structure along "manipulatable" and
20 "non-manipulatable" lines, for the benefit of the NAT code.
21*/
22
23#define NF_CT_TUPLE_L3SIZE 4
24
25/* The l3 protocol-specific manipulable parts of the tuple: always in
26 network order! */
27union nf_conntrack_man_l3proto {
28 u_int32_t all[NF_CT_TUPLE_L3SIZE];
29 u_int32_t ip;
30 u_int32_t ip6[4];
31};
32
33/* The protocol-specific manipulable parts of the tuple: always in
34 network order! */
35union nf_conntrack_man_proto
36{
37 /* Add other protocols here. */
38 u_int16_t all;
39
40 struct {
41 u_int16_t port;
42 } tcp;
43 struct {
44 u_int16_t port;
45 } udp;
46 struct {
47 u_int16_t id;
48 } icmp;
49 struct {
50 u_int16_t port;
51 } sctp;
52};
53
54/* The manipulable part of the tuple. */
55struct nf_conntrack_man
56{
57 union nf_conntrack_man_l3proto u3;
58 union nf_conntrack_man_proto u;
59 /* Layer 3 protocol */
60 u_int16_t l3num;
61};
62
63/* This contains the information to distinguish a connection. */
64struct nf_conntrack_tuple
65{
66 struct nf_conntrack_man src;
67
68 /* These are the parts of the tuple which are fixed. */
69 struct {
70 union {
71 u_int32_t all[NF_CT_TUPLE_L3SIZE];
72 u_int32_t ip;
73 u_int32_t ip6[4];
74 } u3;
75 union {
76 /* Add other protocols here. */
77 u_int16_t all;
78
79 struct {
80 u_int16_t port;
81 } tcp;
82 struct {
83 u_int16_t port;
84 } udp;
85 struct {
86 u_int8_t type, code;
87 } icmp;
88 struct {
89 u_int16_t port;
90 } sctp;
91 } u;
92
93 /* The protocol. */
94 u_int8_t protonum;
95
96 /* The direction (for tuplehash) */
97 u_int8_t dir;
98 } dst;
99};
100
101/* This is optimized opposed to a memset of the whole structure. Everything we
102 * really care about is the source/destination unions */
103#define NF_CT_TUPLE_U_BLANK(tuple) \
104 do { \
105 (tuple)->src.u.all = 0; \
106 (tuple)->dst.u.all = 0; \
107 memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \
108 memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \
109 } while (0)
110
111#ifdef __KERNEL__
112
113#define NF_CT_DUMP_TUPLE(tp) \
114DEBUGP("tuple %p: %u %u %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu -> %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu\n", \
115 (tp), (tp)->src.l3num, (tp)->dst.protonum, \
116 NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
117 NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
118
119/* If we're the first tuple, it's the original dir. */
120#define NF_CT_DIRECTION(h) \
121 ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
122
123/* Connections have two entries in the hash table: one for each way */
124struct nf_conntrack_tuple_hash
125{
126 struct list_head list;
127
128 struct nf_conntrack_tuple tuple;
129};
130
131#endif /* __KERNEL__ */
132
133static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
134 const struct nf_conntrack_tuple *t2)
135{
136 return (t1->src.u3.all[0] == t2->src.u3.all[0] &&
137 t1->src.u3.all[1] == t2->src.u3.all[1] &&
138 t1->src.u3.all[2] == t2->src.u3.all[2] &&
139 t1->src.u3.all[3] == t2->src.u3.all[3] &&
140 t1->src.u.all == t2->src.u.all &&
141 t1->src.l3num == t2->src.l3num &&
142 t1->dst.protonum == t2->dst.protonum);
143}
144
145static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
146 const struct nf_conntrack_tuple *t2)
147{
148 return (t1->dst.u3.all[0] == t2->dst.u3.all[0] &&
149 t1->dst.u3.all[1] == t2->dst.u3.all[1] &&
150 t1->dst.u3.all[2] == t2->dst.u3.all[2] &&
151 t1->dst.u3.all[3] == t2->dst.u3.all[3] &&
152 t1->dst.u.all == t2->dst.u.all &&
153 t1->src.l3num == t2->src.l3num &&
154 t1->dst.protonum == t2->dst.protonum);
155}
156
157static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
158 const struct nf_conntrack_tuple *t2)
159{
160 return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
161}
162
163static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
164 const struct nf_conntrack_tuple *tuple,
165 const struct nf_conntrack_tuple *mask)
166{
167 int count = 0;
168
169 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
170 if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
171 mask->src.u3.all[count])
172 return 0;
173 }
174
175 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
176 if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
177 mask->dst.u3.all[count])
178 return 0;
179 }
180
181 if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
182 (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
183 (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
184 (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
185 return 0;
186
187 return 1;
188}
189
190#endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/include/net/netlink.h b/include/net/netlink.h
new file mode 100644
index 000000000000..640c26a90cf1
--- /dev/null
+++ b/include/net/netlink.h
@@ -0,0 +1,883 @@
1#ifndef __NET_NETLINK_H
2#define __NET_NETLINK_H
3
4#include <linux/types.h>
5#include <linux/netlink.h>
6
7/* ========================================================================
8 * Netlink Messages and Attributes Interface (As Seen On TV)
9 * ------------------------------------------------------------------------
10 * Messages Interface
11 * ------------------------------------------------------------------------
12 *
13 * Message Format:
14 * <--- nlmsg_total_size(payload) --->
15 * <-- nlmsg_msg_size(payload) ->
16 * +----------+- - -+-------------+- - -+-------- - -
17 * | nlmsghdr | Pad | Payload | Pad | nlmsghdr
18 * +----------+- - -+-------------+- - -+-------- - -
19 * nlmsg_data(nlh)---^ ^
20 * nlmsg_next(nlh)-----------------------+
21 *
22 * Payload Format:
23 * <---------------------- nlmsg_len(nlh) --------------------->
24 * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) ->
25 * +----------------------+- - -+--------------------------------+
26 * | Family Header | Pad | Attributes |
27 * +----------------------+- - -+--------------------------------+
28 * nlmsg_attrdata(nlh, hdrlen)---^
29 *
30 * Data Structures:
31 * struct nlmsghdr netlink message header
32 *
33 * Message Construction:
34 * nlmsg_new() create a new netlink message
35 * nlmsg_put() add a netlink message to an skb
36 * nlmsg_put_answer() callback based nlmsg_put()
37 * nlmsg_end() finanlize netlink message
38 * nlmsg_cancel() cancel message construction
39 * nlmsg_free() free a netlink message
40 *
41 * Message Sending:
42 * nlmsg_multicast() multicast message to several groups
43 * nlmsg_unicast() unicast a message to a single socket
44 *
45 * Message Length Calculations:
46 * nlmsg_msg_size(payload) length of message w/o padding
47 * nlmsg_total_size(payload) length of message w/ padding
48 * nlmsg_padlen(payload) length of padding at tail
49 *
50 * Message Payload Access:
51 * nlmsg_data(nlh) head of message payload
52 * nlmsg_len(nlh) length of message payload
53 * nlmsg_attrdata(nlh, hdrlen) head of attributes data
54 * nlmsg_attrlen(nlh, hdrlen) length of attributes data
55 *
56 * Message Parsing:
57 * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes?
58 * nlmsg_next(nlh, remaining) get next netlink message
59 * nlmsg_parse() parse attributes of a message
60 * nlmsg_find_attr() find an attribute in a message
61 * nlmsg_for_each_msg() loop over all messages
62 * nlmsg_validate() validate netlink message incl. attrs
63 * nlmsg_for_each_attr() loop over all attributes
64 *
65 * ------------------------------------------------------------------------
66 * Attributes Interface
67 * ------------------------------------------------------------------------
68 *
69 * Attribute Format:
70 * <------- nla_total_size(payload) ------->
71 * <---- nla_attr_size(payload) ----->
72 * +----------+- - -+- - - - - - - - - +- - -+-------- - -
73 * | Header | Pad | Payload | Pad | Header
74 * +----------+- - -+- - - - - - - - - +- - -+-------- - -
75 * <- nla_len(nla) -> ^
76 * nla_data(nla)----^ |
77 * nla_next(nla)-----------------------------'
78 *
79 * Data Structures:
80 * struct nlattr netlink attribtue header
81 *
82 * Attribute Construction:
83 * nla_reserve(skb, type, len) reserve skb tailroom for an attribute
84 * nla_put(skb, type, len, data) add attribute to skb
85 *
86 * Attribute Construction for Basic Types:
87 * nla_put_u8(skb, type, value) add u8 attribute to skb
88 * nla_put_u16(skb, type, value) add u16 attribute to skb
89 * nla_put_u32(skb, type, value) add u32 attribute to skb
90 * nla_put_u64(skb, type, value) add u64 attribute to skb
91 * nla_put_string(skb, type, str) add string attribute to skb
92 * nla_put_flag(skb, type) add flag attribute to skb
93 * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb
94 *
95 * Exceptions Based Attribute Construction:
96 * NLA_PUT(skb, type, len, data) add attribute to skb
97 * NLA_PUT_U8(skb, type, value) add u8 attribute to skb
98 * NLA_PUT_U16(skb, type, value) add u16 attribute to skb
99 * NLA_PUT_U32(skb, type, value) add u32 attribute to skb
100 * NLA_PUT_U64(skb, type, value) add u64 attribute to skb
101 * NLA_PUT_STRING(skb, type, str) add string attribute to skb
102 * NLA_PUT_FLAG(skb, type) add flag attribute to skb
103 * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb
104 *
105 * The meaning of these functions is equal to their lower case
106 * variants but they jump to the label nla_put_failure in case
107 * of a failure.
108 *
109 * Nested Attributes Construction:
110 * nla_nest_start(skb, type) start a nested attribute
111 * nla_nest_end(skb, nla) finalize a nested attribute
112 * nla_nest_cancel(skb, nla) cancel nested attribute construction
113 *
114 * Attribute Length Calculations:
115 * nla_attr_size(payload) length of attribute w/o padding
116 * nla_total_size(payload) length of attribute w/ padding
117 * nla_padlen(payload) length of padding
118 *
119 * Attribute Payload Access:
120 * nla_data(nla) head of attribute payload
121 * nla_len(nla) length of attribute payload
122 *
123 * Attribute Payload Access for Basic Types:
124 * nla_get_u8(nla) get payload for a u8 attribute
125 * nla_get_u16(nla) get payload for a u16 attribute
126 * nla_get_u32(nla) get payload for a u32 attribute
127 * nla_get_u64(nla) get payload for a u64 attribute
128 * nla_get_flag(nla) return 1 if flag is true
129 * nla_get_msecs(nla) get payload for a msecs attribute
130 *
131 * Attribute Misc:
132 * nla_memcpy(dest, nla, count) copy attribute into memory
133 * nla_memcmp(nla, data, size) compare attribute with memory area
134 * nla_strlcpy(dst, nla, size) copy attribute to a sized string
135 * nla_strcmp(nla, str) compare attribute with string
136 *
137 * Attribute Parsing:
138 * nla_ok(nla, remaining) does nla fit into remaining bytes?
139 * nla_next(nla, remaining) get next netlink attribute
140 * nla_validate() validate a stream of attributes
141 * nla_find() find attribute in stream of attributes
142 * nla_parse() parse and validate stream of attrs
143 * nla_parse_nested() parse nested attribuets
144 * nla_for_each_attr() loop over all attributes
145 *=========================================================================
146 */
147
148 /**
149 * Standard attribute types to specify validation policy
150 */
151enum {
152 NLA_UNSPEC,
153 NLA_U8,
154 NLA_U16,
155 NLA_U32,
156 NLA_U64,
157 NLA_STRING,
158 NLA_FLAG,
159 NLA_MSECS,
160 NLA_NESTED,
161 __NLA_TYPE_MAX,
162};
163
164#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
165
166/**
167 * struct nla_policy - attribute validation policy
168 * @type: Type of attribute or NLA_UNSPEC
169 * @minlen: Minimal length of payload required to be available
170 *
171 * Policies are defined as arrays of this struct, the array must be
172 * accessible by attribute type up to the highest identifier to be expected.
173 *
174 * Example:
175 * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = {
176 * [ATTR_FOO] = { .type = NLA_U16 },
177 * [ATTR_BAR] = { .type = NLA_STRING },
178 * [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) },
179 * };
180 */
181struct nla_policy {
182 u16 type;
183 u16 minlen;
184};
185
186extern void netlink_run_queue(struct sock *sk, unsigned int *qlen,
187 int (*cb)(struct sk_buff *,
188 struct nlmsghdr *, int *));
189extern void netlink_queue_skip(struct nlmsghdr *nlh,
190 struct sk_buff *skb);
191
192extern int nla_validate(struct nlattr *head, int len, int maxtype,
193 struct nla_policy *policy);
194extern int nla_parse(struct nlattr *tb[], int maxtype,
195 struct nlattr *head, int len,
196 struct nla_policy *policy);
197extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
198extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
199 size_t dstsize);
200extern int nla_memcpy(void *dest, struct nlattr *src, int count);
201extern int nla_memcmp(const struct nlattr *nla, const void *data,
202 size_t size);
203extern int nla_strcmp(const struct nlattr *nla, const char *str);
204extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype,
205 int attrlen);
206extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype,
207 int attrlen);
208extern void __nla_put(struct sk_buff *skb, int attrtype,
209 int attrlen, const void *data);
210extern int nla_put(struct sk_buff *skb, int attrtype,
211 int attrlen, const void *data);
212
213/**************************************************************************
214 * Netlink Messages
215 **************************************************************************/
216
217/**
218 * nlmsg_msg_size - length of netlink message not including padding
219 * @payload: length of message payload
220 */
221static inline int nlmsg_msg_size(int payload)
222{
223 return NLMSG_HDRLEN + payload;
224}
225
226/**
227 * nlmsg_total_size - length of netlink message including padding
228 * @payload: length of message payload
229 */
230static inline int nlmsg_total_size(int payload)
231{
232 return NLMSG_ALIGN(nlmsg_msg_size(payload));
233}
234
235/**
236 * nlmsg_padlen - length of padding at the message's tail
237 * @payload: length of message payload
238 */
239static inline int nlmsg_padlen(int payload)
240{
241 return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
242}
243
244/**
245 * nlmsg_data - head of message payload
246 * @nlh: netlink messsage header
247 */
248static inline void *nlmsg_data(const struct nlmsghdr *nlh)
249{
250 return (unsigned char *) nlh + NLMSG_HDRLEN;
251}
252
253/**
254 * nlmsg_len - length of message payload
255 * @nlh: netlink message header
256 */
257static inline int nlmsg_len(const struct nlmsghdr *nlh)
258{
259 return nlh->nlmsg_len - NLMSG_HDRLEN;
260}
261
262/**
263 * nlmsg_attrdata - head of attributes data
264 * @nlh: netlink message header
265 * @hdrlen: length of family specific header
266 */
267static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
268 int hdrlen)
269{
270 unsigned char *data = nlmsg_data(nlh);
271 return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
272}
273
274/**
275 * nlmsg_attrlen - length of attributes data
276 * @nlh: netlink message header
277 * @hdrlen: length of family specific header
278 */
279static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
280{
281 return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
282}
283
284/**
285 * nlmsg_ok - check if the netlink message fits into the remaining bytes
286 * @nlh: netlink message header
287 * @remaining: number of bytes remaining in message stream
288 */
289static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
290{
291 return (remaining >= sizeof(struct nlmsghdr) &&
292 nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
293 nlh->nlmsg_len <= remaining);
294}
295
296/**
297 * nlmsg_next - next netlink message in message stream
298 * @nlh: netlink message header
299 * @remaining: number of bytes remaining in message stream
300 *
301 * Returns the next netlink message in the message stream and
302 * decrements remaining by the size of the current message.
303 */
304static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
305{
306 int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
307
308 *remaining -= totlen;
309
310 return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
311}
312
313/**
314 * nlmsg_parse - parse attributes of a netlink message
315 * @nlh: netlink message header
316 * @hdrlen: length of family specific header
317 * @tb: destination array with maxtype+1 elements
318 * @maxtype: maximum attribute type to be expected
319 * @policy: validation policy
320 *
321 * See nla_parse()
322 */
323static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
324 struct nlattr *tb[], int maxtype,
325 struct nla_policy *policy)
326{
327 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
328 return -EINVAL;
329
330 return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
331 nlmsg_attrlen(nlh, hdrlen), policy);
332}
333
334/**
335 * nlmsg_find_attr - find a specific attribute in a netlink message
336 * @nlh: netlink message header
337 * @hdrlen: length of familiy specific header
338 * @attrtype: type of attribute to look for
339 *
340 * Returns the first attribute which matches the specified type.
341 */
342static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
343 int hdrlen, int attrtype)
344{
345 return nla_find(nlmsg_attrdata(nlh, hdrlen),
346 nlmsg_attrlen(nlh, hdrlen), attrtype);
347}
348
349/**
350 * nlmsg_validate - validate a netlink message including attributes
351 * @nlh: netlinket message header
352 * @hdrlen: length of familiy specific header
353 * @maxtype: maximum attribute type to be expected
354 * @policy: validation policy
355 */
356static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
357 struct nla_policy *policy)
358{
359 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
360 return -EINVAL;
361
362 return nla_validate(nlmsg_attrdata(nlh, hdrlen),
363 nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
364}
365
366/**
367 * nlmsg_for_each_attr - iterate over a stream of attributes
368 * @pos: loop counter, set to current attribute
369 * @nlh: netlink message header
370 * @hdrlen: length of familiy specific header
371 * @rem: initialized to len, holds bytes currently remaining in stream
372 */
373#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
374 nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
375 nlmsg_attrlen(nlh, hdrlen), rem)
376
377#if 0
378/* FIXME: Enable once all users have been converted */
379
380/**
381 * __nlmsg_put - Add a new netlink message to an skb
382 * @skb: socket buffer to store message in
383 * @pid: netlink process id
384 * @seq: sequence number of message
385 * @type: message type
386 * @payload: length of message payload
387 * @flags: message flags
388 *
389 * The caller is responsible to ensure that the skb provides enough
390 * tailroom for both the netlink header and payload.
391 */
392static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid,
393 u32 seq, int type, int payload,
394 int flags)
395{
396 struct nlmsghdr *nlh;
397
398 nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload));
399 nlh->nlmsg_type = type;
400 nlh->nlmsg_len = nlmsg_msg_size(payload);
401 nlh->nlmsg_flags = flags;
402 nlh->nlmsg_pid = pid;
403 nlh->nlmsg_seq = seq;
404
405 memset((unsigned char *) nlmsg_data(nlh) + payload, 0,
406 nlmsg_padlen(payload));
407
408 return nlh;
409}
410#endif
411
412/**
413 * nlmsg_put - Add a new netlink message to an skb
414 * @skb: socket buffer to store message in
415 * @pid: netlink process id
416 * @seq: sequence number of message
417 * @type: message type
418 * @payload: length of message payload
419 * @flags: message flags
420 *
421 * Returns NULL if the tailroom of the skb is insufficient to store
422 * the message header and payload.
423 */
424static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
425 int type, int payload, int flags)
426{
427 if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
428 return NULL;
429
430 return __nlmsg_put(skb, pid, seq, type, payload, flags);
431}
432
433/**
434 * nlmsg_put_answer - Add a new callback based netlink message to an skb
435 * @skb: socket buffer to store message in
436 * @cb: netlink callback
437 * @type: message type
438 * @payload: length of message payload
439 * @flags: message flags
440 *
441 * Returns NULL if the tailroom of the skb is insufficient to store
442 * the message header and payload.
443 */
444static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
445 struct netlink_callback *cb,
446 int type, int payload,
447 int flags)
448{
449 return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
450 type, payload, flags);
451}
452
453/**
454 * nlmsg_new - Allocate a new netlink message
455 * @size: maximum size of message
456 *
457 * Use NLMSG_GOODSIZE if size isn't know and you need a good default size.
458 */
459static inline struct sk_buff *nlmsg_new(int size)
460{
461 return alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
462}
463
464/**
465 * nlmsg_end - Finalize a netlink message
466 * @skb: socket buffer the message is stored in
467 * @nlh: netlink message header
468 *
469 * Corrects the netlink message header to include the appeneded
470 * attributes. Only necessary if attributes have been added to
471 * the message.
472 *
473 * Returns the total data length of the skb.
474 */
475static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
476{
477 nlh->nlmsg_len = skb->tail - (unsigned char *) nlh;
478
479 return skb->len;
480}
481
482/**
483 * nlmsg_cancel - Cancel construction of a netlink message
484 * @skb: socket buffer the message is stored in
485 * @nlh: netlink message header
486 *
487 * Removes the complete netlink message including all
488 * attributes from the socket buffer again. Returns -1.
489 */
490static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
491{
492 skb_trim(skb, (unsigned char *) nlh - skb->data);
493
494 return -1;
495}
496
497/**
498 * nlmsg_free - free a netlink message
499 * @skb: socket buffer of netlink message
500 */
501static inline void nlmsg_free(struct sk_buff *skb)
502{
503 kfree_skb(skb);
504}
505
506/**
507 * nlmsg_multicast - multicast a netlink message
508 * @sk: netlink socket to spread messages to
509 * @skb: netlink message as socket buffer
510 * @pid: own netlink pid to avoid sending to yourself
511 * @group: multicast group id
512 */
513static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
514 u32 pid, unsigned int group)
515{
516 int err;
517
518 NETLINK_CB(skb).dst_group = group;
519
520 err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL);
521 if (err > 0)
522 err = 0;
523
524 return err;
525}
526
527/**
528 * nlmsg_unicast - unicast a netlink message
529 * @sk: netlink socket to spread message to
530 * @skb: netlink message as socket buffer
531 * @pid: netlink pid of the destination socket
532 */
533static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid)
534{
535 int err;
536
537 err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
538 if (err > 0)
539 err = 0;
540
541 return err;
542}
543
544/**
545 * nlmsg_for_each_msg - iterate over a stream of messages
546 * @pos: loop counter, set to current message
547 * @head: head of message stream
548 * @len: length of message stream
549 * @rem: initialized to len, holds bytes currently remaining in stream
550 */
551#define nlmsg_for_each_msg(pos, head, len, rem) \
552 for (pos = head, rem = len; \
553 nlmsg_ok(pos, rem); \
554 pos = nlmsg_next(pos, &(rem)))
555
556/**************************************************************************
557 * Netlink Attributes
558 **************************************************************************/
559
560/**
561 * nla_attr_size - length of attribute not including padding
562 * @payload: length of payload
563 */
564static inline int nla_attr_size(int payload)
565{
566 return NLA_HDRLEN + payload;
567}
568
569/**
570 * nla_total_size - total length of attribute including padding
571 * @payload: length of payload
572 */
573static inline int nla_total_size(int payload)
574{
575 return NLA_ALIGN(nla_attr_size(payload));
576}
577
578/**
579 * nla_padlen - length of padding at the tail of attribute
580 * @payload: length of payload
581 */
582static inline int nla_padlen(int payload)
583{
584 return nla_total_size(payload) - nla_attr_size(payload);
585}
586
587/**
588 * nla_data - head of payload
589 * @nla: netlink attribute
590 */
591static inline void *nla_data(const struct nlattr *nla)
592{
593 return (char *) nla + NLA_HDRLEN;
594}
595
596/**
597 * nla_len - length of payload
598 * @nla: netlink attribute
599 */
600static inline int nla_len(const struct nlattr *nla)
601{
602 return nla->nla_len - NLA_HDRLEN;
603}
604
605/**
606 * nla_ok - check if the netlink attribute fits into the remaining bytes
607 * @nla: netlink attribute
608 * @remaining: number of bytes remaining in attribute stream
609 */
610static inline int nla_ok(const struct nlattr *nla, int remaining)
611{
612 return remaining >= sizeof(*nla) &&
613 nla->nla_len >= sizeof(*nla) &&
614 nla->nla_len <= remaining;
615}
616
617/**
618 * nla_next - next netlink attribte in attribute stream
619 * @nla: netlink attribute
620 * @remaining: number of bytes remaining in attribute stream
621 *
622 * Returns the next netlink attribute in the attribute stream and
623 * decrements remaining by the size of the current attribute.
624 */
625static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
626{
627 int totlen = NLA_ALIGN(nla->nla_len);
628
629 *remaining -= totlen;
630 return (struct nlattr *) ((char *) nla + totlen);
631}
632
633/**
634 * nla_parse_nested - parse nested attributes
635 * @tb: destination array with maxtype+1 elements
636 * @maxtype: maximum attribute type to be expected
637 * @nla: attribute containing the nested attributes
638 * @policy: validation policy
639 *
640 * See nla_parse()
641 */
642static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
643 struct nlattr *nla,
644 struct nla_policy *policy)
645{
646 return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
647}
648/**
649 * nla_put_u8 - Add a u16 netlink attribute to a socket buffer
650 * @skb: socket buffer to add attribute to
651 * @attrtype: attribute type
652 * @value: numeric value
653 */
654static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
655{
656 return nla_put(skb, attrtype, sizeof(u8), &value);
657}
658
659/**
660 * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
661 * @skb: socket buffer to add attribute to
662 * @attrtype: attribute type
663 * @value: numeric value
664 */
665static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
666{
667 return nla_put(skb, attrtype, sizeof(u16), &value);
668}
669
670/**
671 * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
672 * @skb: socket buffer to add attribute to
673 * @attrtype: attribute type
674 * @value: numeric value
675 */
676static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
677{
678 return nla_put(skb, attrtype, sizeof(u32), &value);
679}
680
681/**
682 * nla_put_64 - Add a u64 netlink attribute to a socket buffer
683 * @skb: socket buffer to add attribute to
684 * @attrtype: attribute type
685 * @value: numeric value
686 */
687static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
688{
689 return nla_put(skb, attrtype, sizeof(u64), &value);
690}
691
692/**
693 * nla_put_string - Add a string netlink attribute to a socket buffer
694 * @skb: socket buffer to add attribute to
695 * @attrtype: attribute type
696 * @str: NUL terminated string
697 */
698static inline int nla_put_string(struct sk_buff *skb, int attrtype,
699 const char *str)
700{
701 return nla_put(skb, attrtype, strlen(str) + 1, str);
702}
703
704/**
705 * nla_put_flag - Add a flag netlink attribute to a socket buffer
706 * @skb: socket buffer to add attribute to
707 * @attrtype: attribute type
708 */
709static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
710{
711 return nla_put(skb, attrtype, 0, NULL);
712}
713
714/**
715 * nla_put_msecs - Add a msecs netlink attribute to a socket buffer
716 * @skb: socket buffer to add attribute to
717 * @attrtype: attribute type
718 * @jiffies: number of msecs in jiffies
719 */
720static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
721 unsigned long jiffies)
722{
723 u64 tmp = jiffies_to_msecs(jiffies);
724 return nla_put(skb, attrtype, sizeof(u64), &tmp);
725}
726
727#define NLA_PUT(skb, attrtype, attrlen, data) \
728 do { \
729 if (nla_put(skb, attrtype, attrlen, data) < 0) \
730 goto nla_put_failure; \
731 } while(0)
732
733#define NLA_PUT_TYPE(skb, type, attrtype, value) \
734 do { \
735 type __tmp = value; \
736 NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
737 } while(0)
738
739#define NLA_PUT_U8(skb, attrtype, value) \
740 NLA_PUT_TYPE(skb, u8, attrtype, value)
741
742#define NLA_PUT_U16(skb, attrtype, value) \
743 NLA_PUT_TYPE(skb, u16, attrtype, value)
744
745#define NLA_PUT_U32(skb, attrtype, value) \
746 NLA_PUT_TYPE(skb, u32, attrtype, value)
747
748#define NLA_PUT_U64(skb, attrtype, value) \
749 NLA_PUT_TYPE(skb, u64, attrtype, value)
750
751#define NLA_PUT_STRING(skb, attrtype, value) \
752 NLA_PUT(skb, attrtype, strlen(value) + 1, value)
753
754#define NLA_PUT_FLAG(skb, attrtype, value) \
755 NLA_PUT(skb, attrtype, 0, NULL)
756
757#define NLA_PUT_MSECS(skb, attrtype, jiffies) \
758 NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies))
759
760/**
761 * nla_get_u32 - return payload of u32 attribute
762 * @nla: u32 netlink attribute
763 */
764static inline u32 nla_get_u32(struct nlattr *nla)
765{
766 return *(u32 *) nla_data(nla);
767}
768
769/**
770 * nla_get_u16 - return payload of u16 attribute
771 * @nla: u16 netlink attribute
772 */
773static inline u16 nla_get_u16(struct nlattr *nla)
774{
775 return *(u16 *) nla_data(nla);
776}
777
778/**
779 * nla_get_u8 - return payload of u8 attribute
780 * @nla: u8 netlink attribute
781 */
782static inline u8 nla_get_u8(struct nlattr *nla)
783{
784 return *(u8 *) nla_data(nla);
785}
786
787/**
788 * nla_get_u64 - return payload of u64 attribute
789 * @nla: u64 netlink attribute
790 */
791static inline u64 nla_get_u64(struct nlattr *nla)
792{
793 u64 tmp;
794
795 nla_memcpy(&tmp, nla, sizeof(tmp));
796
797 return tmp;
798}
799
800/**
801 * nla_get_flag - return payload of flag attribute
802 * @nla: flag netlink attribute
803 */
804static inline int nla_get_flag(struct nlattr *nla)
805{
806 return !!nla;
807}
808
809/**
810 * nla_get_msecs - return payload of msecs attribute
811 * @nla: msecs netlink attribute
812 *
813 * Returns the number of milliseconds in jiffies.
814 */
815static inline unsigned long nla_get_msecs(struct nlattr *nla)
816{
817 u64 msecs = nla_get_u64(nla);
818
819 return msecs_to_jiffies((unsigned long) msecs);
820}
821
822/**
823 * nla_nest_start - Start a new level of nested attributes
824 * @skb: socket buffer to add attributes to
825 * @attrtype: attribute type of container
826 *
827 * Returns the container attribute
828 */
829static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
830{
831 struct nlattr *start = (struct nlattr *) skb->tail;
832
833 if (nla_put(skb, attrtype, 0, NULL) < 0)
834 return NULL;
835
836 return start;
837}
838
839/**
840 * nla_nest_end - Finalize nesting of attributes
841 * @skb: socket buffer the attribtues are stored in
842 * @start: container attribute
843 *
844 * Corrects the container attribute header to include the all
845 * appeneded attributes.
846 *
847 * Returns the total data length of the skb.
848 */
849static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
850{
851 start->nla_len = skb->tail - (unsigned char *) start;
852 return skb->len;
853}
854
855/**
856 * nla_nest_cancel - Cancel nesting of attributes
857 * @skb: socket buffer the message is stored in
858 * @start: container attribute
859 *
860 * Removes the container attribute and including all nested
861 * attributes. Returns -1.
862 */
863static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
864{
865 if (start)
866 skb_trim(skb, (unsigned char *) start - skb->data);
867
868 return -1;
869}
870
871/**
872 * nla_for_each_attr - iterate over a stream of attributes
873 * @pos: loop counter, set to current attribute
874 * @head: head of attribute stream
875 * @len: length of attribute stream
876 * @rem: initialized to len, holds bytes currently remaining in stream
877 */
878#define nla_for_each_attr(pos, head, len, rem) \
879 for (pos = head, rem = len; \
880 nla_ok(pos, rem); \
881 pos = nla_next(pos, &(rem)))
882
883#endif
diff --git a/include/net/sock.h b/include/net/sock.h
index ff13c4cc287a..982b4ecd187b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1247,6 +1247,12 @@ static inline struct page *sk_stream_alloc_page(struct sock *sk)
1247 (skb != (struct sk_buff *)&(sk)->sk_write_queue); \ 1247 (skb != (struct sk_buff *)&(sk)->sk_write_queue); \
1248 skb = skb->next) 1248 skb = skb->next)
1249 1249
1250/*from STCP for fast SACK Process*/
1251#define sk_stream_for_retrans_queue_from(skb, sk) \
1252 for (; (skb != (sk)->sk_send_head) && \
1253 (skb != (struct sk_buff *)&(sk)->sk_write_queue); \
1254 skb = skb->next)
1255
1250/* 1256/*
1251 * Default write policy as shown to user space via poll/select/SIGIO 1257 * Default write policy as shown to user space via poll/select/SIGIO
1252 */ 1258 */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index c24339c4e310..0f9848011972 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -27,6 +27,7 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/cache.h> 28#include <linux/cache.h>
29#include <linux/percpu.h> 29#include <linux/percpu.h>
30#include <linux/skbuff.h>
30 31
31#include <net/inet_connection_sock.h> 32#include <net/inet_connection_sock.h>
32#include <net/inet_timewait_sock.h> 33#include <net/inet_timewait_sock.h>
@@ -88,10 +89,10 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
88 */ 89 */
89 90
90#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a 91#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a
91 * connection: ~180sec is RFC minumum */ 92 * connection: ~180sec is RFC minimum */
92 93
93#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a 94#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a
94 * connection: ~180sec is RFC minumum */ 95 * connection: ~180sec is RFC minimum */
95 96
96 97
97#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned 98#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned
@@ -179,7 +180,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
179/* Flags in tp->nonagle */ 180/* Flags in tp->nonagle */
180#define TCP_NAGLE_OFF 1 /* Nagle's algo is disabled */ 181#define TCP_NAGLE_OFF 1 /* Nagle's algo is disabled */
181#define TCP_NAGLE_CORK 2 /* Socket is corked */ 182#define TCP_NAGLE_CORK 2 /* Socket is corked */
182#define TCP_NAGLE_PUSH 4 /* Cork is overriden for already queued data */ 183#define TCP_NAGLE_PUSH 4 /* Cork is overridden for already queued data */
183 184
184extern struct inet_timewait_death_row tcp_death_row; 185extern struct inet_timewait_death_row tcp_death_row;
185 186
@@ -217,6 +218,7 @@ extern int sysctl_tcp_low_latency;
217extern int sysctl_tcp_nometrics_save; 218extern int sysctl_tcp_nometrics_save;
218extern int sysctl_tcp_moderate_rcvbuf; 219extern int sysctl_tcp_moderate_rcvbuf;
219extern int sysctl_tcp_tso_win_divisor; 220extern int sysctl_tcp_tso_win_divisor;
221extern int sysctl_tcp_abc;
220 222
221extern atomic_t tcp_memory_allocated; 223extern atomic_t tcp_memory_allocated;
222extern atomic_t tcp_sockets_allocated; 224extern atomic_t tcp_sockets_allocated;
@@ -550,13 +552,13 @@ extern u32 __tcp_select_window(struct sock *sk);
550 552
551/* TCP timestamps are only 32-bits, this causes a slight 553/* TCP timestamps are only 32-bits, this causes a slight
552 * complication on 64-bit systems since we store a snapshot 554 * complication on 64-bit systems since we store a snapshot
553 * of jiffies in the buffer control blocks below. We decidely 555 * of jiffies in the buffer control blocks below. We decidedly
554 * only use of the low 32-bits of jiffies and hide the ugly 556 * only use of the low 32-bits of jiffies and hide the ugly
555 * casts with the following macro. 557 * casts with the following macro.
556 */ 558 */
557#define tcp_time_stamp ((__u32)(jiffies)) 559#define tcp_time_stamp ((__u32)(jiffies))
558 560
559/* This is what the send packet queueing engine uses to pass 561/* This is what the send packet queuing engine uses to pass
560 * TCP per-packet control information to the transmission 562 * TCP per-packet control information to the transmission
561 * code. We also store the host-order sequence numbers in 563 * code. We also store the host-order sequence numbers in
562 * here too. This is 36 bytes on 32-bit architectures, 564 * here too. This is 36 bytes on 32-bit architectures,
@@ -596,7 +598,7 @@ struct tcp_skb_cb {
596#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */ 598#define TCPCB_EVER_RETRANS 0x80 /* Ever retransmitted frame */
597#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS) 599#define TCPCB_RETRANS (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
598 600
599#define TCPCB_URG 0x20 /* Urgent pointer advenced here */ 601#define TCPCB_URG 0x20 /* Urgent pointer advanced here */
600 602
601#define TCPCB_AT_TAIL (TCPCB_URG) 603#define TCPCB_AT_TAIL (TCPCB_URG)
602 604
@@ -764,6 +766,33 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk)
764 (tp->snd_cwnd >> 2))); 766 (tp->snd_cwnd >> 2)));
765} 767}
766 768
769/*
770 * Linear increase during slow start
771 */
772static inline void tcp_slow_start(struct tcp_sock *tp)
773{
774 if (sysctl_tcp_abc) {
775 /* RFC3465: Slow Start
776 * TCP sender SHOULD increase cwnd by the number of
777 * previously unacknowledged bytes ACKed by each incoming
778 * acknowledgment, provided the increase is not more than L
779 */
780 if (tp->bytes_acked < tp->mss_cache)
781 return;
782
783 /* We MAY increase by 2 if discovered delayed ack */
784 if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
785 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
786 tp->snd_cwnd++;
787 }
788 }
789 tp->bytes_acked = 0;
790
791 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
792 tp->snd_cwnd++;
793}
794
795
767static inline void tcp_sync_left_out(struct tcp_sock *tp) 796static inline void tcp_sync_left_out(struct tcp_sock *tp)
768{ 797{
769 if (tp->rx_opt.sack_ok && 798 if (tp->rx_opt.sack_ok &&
@@ -793,6 +822,7 @@ static inline void tcp_enter_cwr(struct sock *sk)
793 struct tcp_sock *tp = tcp_sk(sk); 822 struct tcp_sock *tp = tcp_sk(sk);
794 823
795 tp->prior_ssthresh = 0; 824 tp->prior_ssthresh = 0;
825 tp->bytes_acked = 0;
796 if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { 826 if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
797 __tcp_enter_cwr(sk); 827 __tcp_enter_cwr(sk);
798 tcp_set_ca_state(sk, TCP_CA_CWR); 828 tcp_set_ca_state(sk, TCP_CA_CWR);
@@ -809,6 +839,27 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
809 return 3; 839 return 3;
810} 840}
811 841
842/* RFC2861 Check whether we are limited by application or congestion window
843 * This is the inverse of cwnd check in tcp_tso_should_defer
844 */
845static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
846{
847 const struct tcp_sock *tp = tcp_sk(sk);
848 u32 left;
849
850 if (in_flight >= tp->snd_cwnd)
851 return 1;
852
853 if (!(sk->sk_route_caps & NETIF_F_TSO))
854 return 0;
855
856 left = tp->snd_cwnd - in_flight;
857 if (sysctl_tcp_tso_win_divisor)
858 return left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd;
859 else
860 return left <= tcp_max_burst(tp);
861}
862
812static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, 863static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss,
813 const struct sk_buff *skb) 864 const struct sk_buff *skb)
814{ 865{
@@ -852,7 +903,7 @@ static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
852 903
853static __inline__ int __tcp_checksum_complete(struct sk_buff *skb) 904static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
854{ 905{
855 return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); 906 return __skb_checksum_complete(skb);
856} 907}
857 908
858static __inline__ int tcp_checksum_complete(struct sk_buff *skb) 909static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
@@ -1156,6 +1207,15 @@ static inline void tcp_mib_init(void)
1156 TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1); 1207 TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);
1157} 1208}
1158 1209
1210/*from STCP */
1211static inline void clear_all_retrans_hints(struct tcp_sock *tp){
1212 tp->lost_skb_hint = NULL;
1213 tp->scoreboard_skb_hint = NULL;
1214 tp->retransmit_skb_hint = NULL;
1215 tp->forward_skb_hint = NULL;
1216 tp->fastpath_skb_hint = NULL;
1217}
1218
1159/* /proc */ 1219/* /proc */
1160enum tcp_seq_states { 1220enum tcp_seq_states {
1161 TCP_SEQ_STATE_LISTENING, 1221 TCP_SEQ_STATE_LISTENING,
diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
index 072f3a2edace..5ff1490c08db 100644
--- a/include/rdma/ib_user_verbs.h
+++ b/include/rdma/ib_user_verbs.h
@@ -43,7 +43,7 @@
43 * Increment this value if any changes that break userspace ABI 43 * Increment this value if any changes that break userspace ABI
44 * compatibility are made. 44 * compatibility are made.
45 */ 45 */
46#define IB_USER_VERBS_ABI_VERSION 3 46#define IB_USER_VERBS_ABI_VERSION 4
47 47
48enum { 48enum {
49 IB_USER_VERBS_CMD_GET_CONTEXT, 49 IB_USER_VERBS_CMD_GET_CONTEXT,
@@ -333,6 +333,11 @@ struct ib_uverbs_create_qp {
333struct ib_uverbs_create_qp_resp { 333struct ib_uverbs_create_qp_resp {
334 __u32 qp_handle; 334 __u32 qp_handle;
335 __u32 qpn; 335 __u32 qpn;
336 __u32 max_send_wr;
337 __u32 max_recv_wr;
338 __u32 max_send_sge;
339 __u32 max_recv_sge;
340 __u32 max_inline_data;
336}; 341};
337 342
338/* 343/*
@@ -552,9 +557,7 @@ struct ib_uverbs_modify_srq {
552 __u32 srq_handle; 557 __u32 srq_handle;
553 __u32 attr_mask; 558 __u32 attr_mask;
554 __u32 max_wr; 559 __u32 max_wr;
555 __u32 max_sge;
556 __u32 srq_limit; 560 __u32 srq_limit;
557 __u32 reserved;
558 __u64 driver_data[0]; 561 __u64 driver_data[0];
559}; 562};
560 563
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index f72d46d54e0a..a7f4c355a91f 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -881,7 +881,7 @@ struct ib_device {
881 struct ib_ucontext *context, 881 struct ib_ucontext *context,
882 struct ib_udata *udata); 882 struct ib_udata *udata);
883 int (*destroy_cq)(struct ib_cq *cq); 883 int (*destroy_cq)(struct ib_cq *cq);
884 int (*resize_cq)(struct ib_cq *cq, int *cqe); 884 int (*resize_cq)(struct ib_cq *cq, int cqe);
885 int (*poll_cq)(struct ib_cq *cq, int num_entries, 885 int (*poll_cq)(struct ib_cq *cq, int num_entries,
886 struct ib_wc *wc); 886 struct ib_wc *wc);
887 int (*peek_cq)(struct ib_cq *cq, int wc_cnt); 887 int (*peek_cq)(struct ib_cq *cq, int wc_cnt);
diff --git a/init/main.c b/init/main.c
index f142d4035341..27f97f9b4636 100644
--- a/init/main.c
+++ b/init/main.c
@@ -394,14 +394,16 @@ static void noinline rest_init(void)
394 kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND); 394 kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
395 numa_default_policy(); 395 numa_default_policy();
396 unlock_kernel(); 396 unlock_kernel();
397 preempt_enable_no_resched();
398 397
399 /* 398 /*
400 * The boot idle thread must execute schedule() 399 * The boot idle thread must execute schedule()
401 * at least one to get things moving: 400 * at least one to get things moving:
402 */ 401 */
402 preempt_enable_no_resched();
403 schedule(); 403 schedule();
404 preempt_disable();
404 405
406 /* Call into cpu_idle with preempt disabled */
405 cpu_idle(); 407 cpu_idle();
406} 408}
407 409
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 3619e939182e..d61ba88f34e5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -21,6 +21,24 @@ EXPORT_SYMBOL_GPL(cpucontrol);
21 21
22static struct notifier_block *cpu_chain; 22static struct notifier_block *cpu_chain;
23 23
24/*
25 * Used to check by callers if they need to acquire the cpucontrol
26 * or not to protect a cpu from being removed. Its sometimes required to
27 * call these functions both for normal operations, and in response to
28 * a cpu being added/removed. If the context of the call is in the same
29 * thread context as a CPU hotplug thread, we dont need to take the lock
30 * since its already protected
31 * check drivers/cpufreq/cpufreq.c for its usage - Ashok Raj
32 */
33
34int current_in_cpu_hotplug(void)
35{
36 return (current->flags & PF_HOTPLUG_CPU);
37}
38
39EXPORT_SYMBOL_GPL(current_in_cpu_hotplug);
40
41
24/* Need to know about CPUs going up/down? */ 42/* Need to know about CPUs going up/down? */
25int register_cpu_notifier(struct notifier_block *nb) 43int register_cpu_notifier(struct notifier_block *nb)
26{ 44{
@@ -94,6 +112,13 @@ int cpu_down(unsigned int cpu)
94 goto out; 112 goto out;
95 } 113 }
96 114
115 /*
116 * Leave a trace in current->flags indicating we are already in
117 * process of performing CPU hotplug. Callers can check if cpucontrol
118 * is already acquired by current thread, and if so not cause
119 * a dead lock by not acquiring the lock
120 */
121 current->flags |= PF_HOTPLUG_CPU;
97 err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, 122 err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
98 (void *)(long)cpu); 123 (void *)(long)cpu);
99 if (err == NOTIFY_BAD) { 124 if (err == NOTIFY_BAD) {
@@ -146,6 +171,7 @@ out_thread:
146out_allowed: 171out_allowed:
147 set_cpus_allowed(current, old_allowed); 172 set_cpus_allowed(current, old_allowed);
148out: 173out:
174 current->flags &= ~PF_HOTPLUG_CPU;
149 unlock_cpu_hotplug(); 175 unlock_cpu_hotplug();
150 return err; 176 return err;
151} 177}
@@ -163,6 +189,12 @@ int __devinit cpu_up(unsigned int cpu)
163 ret = -EINVAL; 189 ret = -EINVAL;
164 goto out; 190 goto out;
165 } 191 }
192
193 /*
194 * Leave a trace in current->flags indicating we are already in
195 * process of performing CPU hotplug.
196 */
197 current->flags |= PF_HOTPLUG_CPU;
166 ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); 198 ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
167 if (ret == NOTIFY_BAD) { 199 if (ret == NOTIFY_BAD) {
168 printk("%s: attempt to bring up CPU %u failed\n", 200 printk("%s: attempt to bring up CPU %u failed\n",
@@ -185,6 +217,7 @@ out_notify:
185 if (ret != 0) 217 if (ret != 0)
186 notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); 218 notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu);
187out: 219out:
220 current->flags &= ~PF_HOTPLUG_CPU;
188 up(&cpucontrol); 221 up(&cpucontrol);
189 return ret; 222 return ret;
190} 223}
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 18d7d693fbba..6ee2cad530e8 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -167,7 +167,7 @@ static int enter_state(suspend_state_t state)
167{ 167{
168 int error; 168 int error;
169 169
170 if (pm_ops->valid && !pm_ops->valid(state)) 170 if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
171 return -ENODEV; 171 return -ENODEV;
172 if (down_trylock(&pm_sem)) 172 if (down_trylock(&pm_sem))
173 return -EBUSY; 173 return -EBUSY;
diff --git a/kernel/power/power.h b/kernel/power/power.h
index d4fd96a135ab..6c042b5ee14b 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -65,8 +65,8 @@ extern suspend_pagedir_t *pagedir_save;
65extern asmlinkage int swsusp_arch_suspend(void); 65extern asmlinkage int swsusp_arch_suspend(void);
66extern asmlinkage int swsusp_arch_resume(void); 66extern asmlinkage int swsusp_arch_resume(void);
67 67
68extern int restore_highmem(void); 68extern void free_pagedir(struct pbe *pblist);
69extern struct pbe * alloc_pagedir(unsigned nr_pages); 69extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
70extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages); 70extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
71extern void swsusp_free(void); 71extern void swsusp_free(void);
72extern int enough_swap(unsigned nr_pages); 72extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 723f5179883e..4a6dbcefd378 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -88,8 +88,7 @@ static int save_highmem_zone(struct zone *zone)
88 return 0; 88 return 0;
89} 89}
90 90
91 91int save_highmem(void)
92static int save_highmem(void)
93{ 92{
94 struct zone *zone; 93 struct zone *zone;
95 int res = 0; 94 int res = 0;
@@ -120,11 +119,7 @@ int restore_highmem(void)
120 } 119 }
121 return 0; 120 return 0;
122} 121}
123#else 122#endif
124static int save_highmem(void) { return 0; }
125int restore_highmem(void) { return 0; }
126#endif /* CONFIG_HIGHMEM */
127
128 123
129static int pfn_is_nosave(unsigned long pfn) 124static int pfn_is_nosave(unsigned long pfn)
130{ 125{
@@ -216,7 +211,7 @@ static void copy_data_pages(struct pbe *pblist)
216 * free_pagedir - free pages allocated with alloc_pagedir() 211 * free_pagedir - free pages allocated with alloc_pagedir()
217 */ 212 */
218 213
219static void free_pagedir(struct pbe *pblist) 214void free_pagedir(struct pbe *pblist)
220{ 215{
221 struct pbe *pbe; 216 struct pbe *pbe;
222 217
@@ -269,9 +264,30 @@ void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
269 pr_debug("create_pbe_list(): initialized %d PBEs\n", num); 264 pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
270} 265}
271 266
272static void *alloc_image_page(void) 267/**
268 * @safe_needed - on resume, for storing the PBE list and the image,
269 * we can only use memory pages that do not conflict with the pages
270 * which had been used before suspend.
271 *
272 * The unsafe pages are marked with the PG_nosave_free flag
273 *
274 * Allocated but unusable (ie eaten) memory pages should be marked
275 * so that swsusp_free() can release them
276 */
277
278static inline void *alloc_image_page(gfp_t gfp_mask, int safe_needed)
273{ 279{
274 void *res = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD); 280 void *res;
281
282 if (safe_needed)
283 do {
284 res = (void *)get_zeroed_page(gfp_mask);
285 if (res && PageNosaveFree(virt_to_page(res)))
286 /* This is for swsusp_free() */
287 SetPageNosave(virt_to_page(res));
288 } while (res && PageNosaveFree(virt_to_page(res)));
289 else
290 res = (void *)get_zeroed_page(gfp_mask);
275 if (res) { 291 if (res) {
276 SetPageNosave(virt_to_page(res)); 292 SetPageNosave(virt_to_page(res));
277 SetPageNosaveFree(virt_to_page(res)); 293 SetPageNosaveFree(virt_to_page(res));
@@ -279,6 +295,11 @@ static void *alloc_image_page(void)
279 return res; 295 return res;
280} 296}
281 297
298unsigned long get_safe_page(gfp_t gfp_mask)
299{
300 return (unsigned long)alloc_image_page(gfp_mask, 1);
301}
302
282/** 303/**
283 * alloc_pagedir - Allocate the page directory. 304 * alloc_pagedir - Allocate the page directory.
284 * 305 *
@@ -292,7 +313,7 @@ static void *alloc_image_page(void)
292 * On each page we set up a list of struct_pbe elements. 313 * On each page we set up a list of struct_pbe elements.
293 */ 314 */
294 315
295struct pbe *alloc_pagedir(unsigned int nr_pages) 316struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed)
296{ 317{
297 unsigned int num; 318 unsigned int num;
298 struct pbe *pblist, *pbe; 319 struct pbe *pblist, *pbe;
@@ -301,12 +322,12 @@ struct pbe *alloc_pagedir(unsigned int nr_pages)
301 return NULL; 322 return NULL;
302 323
303 pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages); 324 pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
304 pblist = alloc_image_page(); 325 pblist = alloc_image_page(gfp_mask, safe_needed);
305 /* FIXME: rewrite this ugly loop */ 326 /* FIXME: rewrite this ugly loop */
306 for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages; 327 for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
307 pbe = pbe->next, num += PBES_PER_PAGE) { 328 pbe = pbe->next, num += PBES_PER_PAGE) {
308 pbe += PB_PAGE_SKIP; 329 pbe += PB_PAGE_SKIP;
309 pbe->next = alloc_image_page(); 330 pbe->next = alloc_image_page(gfp_mask, safe_needed);
310 } 331 }
311 if (!pbe) { /* get_zeroed_page() failed */ 332 if (!pbe) { /* get_zeroed_page() failed */
312 free_pagedir(pblist); 333 free_pagedir(pblist);
@@ -354,24 +375,32 @@ static int enough_free_mem(unsigned int nr_pages)
354 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE); 375 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
355} 376}
356 377
378int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed)
379{
380 struct pbe *p;
381
382 for_each_pbe (p, pblist) {
383 p->address = (unsigned long)alloc_image_page(gfp_mask, safe_needed);
384 if (!p->address)
385 return -ENOMEM;
386 }
387 return 0;
388}
357 389
358static struct pbe *swsusp_alloc(unsigned int nr_pages) 390static struct pbe *swsusp_alloc(unsigned int nr_pages)
359{ 391{
360 struct pbe *pblist, *p; 392 struct pbe *pblist;
361 393
362 if (!(pblist = alloc_pagedir(nr_pages))) { 394 if (!(pblist = alloc_pagedir(nr_pages, GFP_ATOMIC | __GFP_COLD, 0))) {
363 printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); 395 printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
364 return NULL; 396 return NULL;
365 } 397 }
366 create_pbe_list(pblist, nr_pages); 398 create_pbe_list(pblist, nr_pages);
367 399
368 for_each_pbe (p, pblist) { 400 if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) {
369 p->address = (unsigned long)alloc_image_page(); 401 printk(KERN_ERR "suspend: Allocating image pages failed.\n");
370 if (!p->address) { 402 swsusp_free();
371 printk(KERN_ERR "suspend: Allocating image pages failed.\n"); 403 return NULL;
372 swsusp_free();
373 return NULL;
374 }
375 } 404 }
376 405
377 return pblist; 406 return pblist;
@@ -382,11 +411,6 @@ asmlinkage int swsusp_save(void)
382 unsigned int nr_pages; 411 unsigned int nr_pages;
383 412
384 pr_debug("swsusp: critical section: \n"); 413 pr_debug("swsusp: critical section: \n");
385 if (save_highmem()) {
386 printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n");
387 restore_highmem();
388 return -ENOMEM;
389 }
390 414
391 drain_local_pages(); 415 drain_local_pages();
392 nr_pages = count_data_pages(); 416 nr_pages = count_data_pages();
@@ -406,11 +430,6 @@ asmlinkage int swsusp_save(void)
406 return -ENOMEM; 430 return -ENOMEM;
407 } 431 }
408 432
409 if (!enough_swap(nr_pages)) {
410 printk(KERN_ERR "swsusp: Not enough free swap\n");
411 return -ENOSPC;
412 }
413
414 pagedir_nosave = swsusp_alloc(nr_pages); 433 pagedir_nosave = swsusp_alloc(nr_pages);
415 if (!pagedir_nosave) 434 if (!pagedir_nosave)
416 return -ENOMEM; 435 return -ENOMEM;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index e1ab28b9b217..c05f46e7348f 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -73,6 +73,14 @@
73 73
74#include "power.h" 74#include "power.h"
75 75
76#ifdef CONFIG_HIGHMEM
77int save_highmem(void);
78int restore_highmem(void);
79#else
80static int save_highmem(void) { return 0; }
81static int restore_highmem(void) { return 0; }
82#endif
83
76#define CIPHER "aes" 84#define CIPHER "aes"
77#define MAXKEY 32 85#define MAXKEY 32
78#define MAXIV 32 86#define MAXIV 32
@@ -500,6 +508,26 @@ static int write_pagedir(void)
500} 508}
501 509
502/** 510/**
511 * enough_swap - Make sure we have enough swap to save the image.
512 *
513 * Returns TRUE or FALSE after checking the total amount of swap
514 * space avaiable.
515 *
516 * FIXME: si_swapinfo(&i) returns all swap devices information.
517 * We should only consider resume_device.
518 */
519
520static int enough_swap(unsigned int nr_pages)
521{
522 struct sysinfo i;
523
524 si_swapinfo(&i);
525 pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
526 return i.freeswap > (nr_pages + PAGES_FOR_IO +
527 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
528}
529
530/**
503 * write_suspend_image - Write entire image and metadata. 531 * write_suspend_image - Write entire image and metadata.
504 * 532 *
505 */ 533 */
@@ -507,6 +535,11 @@ static int write_suspend_image(void)
507{ 535{
508 int error; 536 int error;
509 537
538 if (!enough_swap(nr_copy_pages)) {
539 printk(KERN_ERR "swsusp: Not enough free swap\n");
540 return -ENOSPC;
541 }
542
510 init_header(); 543 init_header();
511 if ((error = data_write())) 544 if ((error = data_write()))
512 goto FreeData; 545 goto FreeData;
@@ -526,27 +559,6 @@ static int write_suspend_image(void)
526 goto Done; 559 goto Done;
527} 560}
528 561
529/**
530 * enough_swap - Make sure we have enough swap to save the image.
531 *
532 * Returns TRUE or FALSE after checking the total amount of swap
533 * space avaiable.
534 *
535 * FIXME: si_swapinfo(&i) returns all swap devices information.
536 * We should only consider resume_device.
537 */
538
539int enough_swap(unsigned int nr_pages)
540{
541 struct sysinfo i;
542
543 si_swapinfo(&i);
544 pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
545 return i.freeswap > (nr_pages + PAGES_FOR_IO +
546 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
547}
548
549
550/* It is important _NOT_ to umount filesystems at this point. We want 562/* It is important _NOT_ to umount filesystems at this point. We want
551 * them synced (in case something goes wrong) but we DO not want to mark 563 * them synced (in case something goes wrong) but we DO not want to mark
552 * filesystem clean: it is not. (And it does not matter, if we resume 564 * filesystem clean: it is not. (And it does not matter, if we resume
@@ -556,12 +568,15 @@ int swsusp_write(void)
556{ 568{
557 int error; 569 int error;
558 570
571 if ((error = swsusp_swap_check())) {
572 printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
573 return error;
574 }
559 lock_swapdevices(); 575 lock_swapdevices();
560 error = write_suspend_image(); 576 error = write_suspend_image();
561 /* This will unlock ignored swap devices since writing is finished */ 577 /* This will unlock ignored swap devices since writing is finished */
562 lock_swapdevices(); 578 lock_swapdevices();
563 return error; 579 return error;
564
565} 580}
566 581
567 582
@@ -569,6 +584,7 @@ int swsusp_write(void)
569int swsusp_suspend(void) 584int swsusp_suspend(void)
570{ 585{
571 int error; 586 int error;
587
572 if ((error = arch_prepare_suspend())) 588 if ((error = arch_prepare_suspend()))
573 return error; 589 return error;
574 local_irq_disable(); 590 local_irq_disable();
@@ -580,15 +596,12 @@ int swsusp_suspend(void)
580 */ 596 */
581 if ((error = device_power_down(PMSG_FREEZE))) { 597 if ((error = device_power_down(PMSG_FREEZE))) {
582 printk(KERN_ERR "Some devices failed to power down, aborting suspend\n"); 598 printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
583 local_irq_enable(); 599 goto Enable_irqs;
584 return error;
585 } 600 }
586 601
587 if ((error = swsusp_swap_check())) { 602 if ((error = save_highmem())) {
588 printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n"); 603 printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
589 device_power_up(); 604 goto Restore_highmem;
590 local_irq_enable();
591 return error;
592 } 605 }
593 606
594 save_processor_state(); 607 save_processor_state();
@@ -596,8 +609,10 @@ int swsusp_suspend(void)
596 printk(KERN_ERR "Error %d suspending\n", error); 609 printk(KERN_ERR "Error %d suspending\n", error);
597 /* Restore control flow magically appears here */ 610 /* Restore control flow magically appears here */
598 restore_processor_state(); 611 restore_processor_state();
612Restore_highmem:
599 restore_highmem(); 613 restore_highmem();
600 device_power_up(); 614 device_power_up();
615Enable_irqs:
601 local_irq_enable(); 616 local_irq_enable();
602 return error; 617 return error;
603} 618}
@@ -629,127 +644,43 @@ int swsusp_resume(void)
629} 644}
630 645
631/** 646/**
632 * On resume, for storing the PBE list and the image, 647 * mark_unsafe_pages - mark the pages that cannot be used for storing
633 * we can only use memory pages that do not conflict with the pages 648 * the image during resume, because they conflict with the pages that
634 * which had been used before suspend. 649 * had been used before suspend
635 *
636 * We don't know which pages are usable until we allocate them.
637 *
638 * Allocated but unusable (ie eaten) memory pages are marked so that
639 * swsusp_free() can release them
640 */
641
642unsigned long get_safe_page(gfp_t gfp_mask)
643{
644 unsigned long m;
645
646 do {
647 m = get_zeroed_page(gfp_mask);
648 if (m && PageNosaveFree(virt_to_page(m)))
649 /* This is for swsusp_free() */
650 SetPageNosave(virt_to_page(m));
651 } while (m && PageNosaveFree(virt_to_page(m)));
652 if (m) {
653 /* This is for swsusp_free() */
654 SetPageNosave(virt_to_page(m));
655 SetPageNosaveFree(virt_to_page(m));
656 }
657 return m;
658}
659
660/**
661 * check_pagedir - We ensure here that pages that the PBEs point to
662 * won't collide with pages where we're going to restore from the loaded
663 * pages later
664 */
665
666static int check_pagedir(struct pbe *pblist)
667{
668 struct pbe *p;
669
670 /* This is necessary, so that we can free allocated pages
671 * in case of failure
672 */
673 for_each_pbe (p, pblist)
674 p->address = 0UL;
675
676 for_each_pbe (p, pblist) {
677 p->address = get_safe_page(GFP_ATOMIC);
678 if (!p->address)
679 return -ENOMEM;
680 }
681 return 0;
682}
683
684/**
685 * swsusp_pagedir_relocate - It is possible, that some memory pages
686 * occupied by the list of PBEs collide with pages where we're going to
687 * restore from the loaded pages later. We relocate them here.
688 */ 650 */
689 651
690static struct pbe *swsusp_pagedir_relocate(struct pbe *pblist) 652static void mark_unsafe_pages(struct pbe *pblist)
691{ 653{
692 struct zone *zone; 654 struct zone *zone;
693 unsigned long zone_pfn; 655 unsigned long zone_pfn;
694 struct pbe *pbpage, *tail, *p; 656 struct pbe *p;
695 void *m;
696 int rel = 0;
697 657
698 if (!pblist) /* a sanity check */ 658 if (!pblist) /* a sanity check */
699 return NULL; 659 return;
700
701 pr_debug("swsusp: Relocating pagedir (%lu pages to check)\n",
702 swsusp_info.pagedir_pages);
703 660
704 /* Clear page flags */ 661 /* Clear page flags */
705
706 for_each_zone (zone) { 662 for_each_zone (zone) {
707 for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) 663 for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
708 if (pfn_valid(zone_pfn + zone->zone_start_pfn)) 664 if (pfn_valid(zone_pfn + zone->zone_start_pfn))
709 ClearPageNosaveFree(pfn_to_page(zone_pfn + 665 ClearPageNosaveFree(pfn_to_page(zone_pfn +
710 zone->zone_start_pfn)); 666 zone->zone_start_pfn));
711 } 667 }
712 668
713 /* Mark orig addresses */ 669 /* Mark orig addresses */
714
715 for_each_pbe (p, pblist) 670 for_each_pbe (p, pblist)
716 SetPageNosaveFree(virt_to_page(p->orig_address)); 671 SetPageNosaveFree(virt_to_page(p->orig_address));
717 672
718 tail = pblist + PB_PAGE_SKIP; 673}
719
720 /* Relocate colliding pages */
721
722 for_each_pb_page (pbpage, pblist) {
723 if (PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
724 m = (void *)get_safe_page(GFP_ATOMIC | __GFP_COLD);
725 if (!m)
726 return NULL;
727 memcpy(m, (void *)pbpage, PAGE_SIZE);
728 if (pbpage == pblist)
729 pblist = (struct pbe *)m;
730 else
731 tail->next = (struct pbe *)m;
732 pbpage = (struct pbe *)m;
733
734 /* We have to link the PBEs again */
735 for (p = pbpage; p < pbpage + PB_PAGE_SKIP; p++)
736 if (p->next) /* needed to save the end */
737 p->next = p + 1;
738
739 rel++;
740 }
741 tail = pbpage + PB_PAGE_SKIP;
742 }
743 674
744 /* This is for swsusp_free() */ 675static void copy_page_backup_list(struct pbe *dst, struct pbe *src)
745 for_each_pb_page (pbpage, pblist) { 676{
746 SetPageNosave(virt_to_page(pbpage)); 677 /* We assume both lists contain the same number of elements */
747 SetPageNosaveFree(virt_to_page(pbpage)); 678 while (src) {
679 dst->orig_address = src->orig_address;
680 dst->swap_address = src->swap_address;
681 dst = dst->next;
682 src = src->next;
748 } 683 }
749
750 printk("swsusp: Relocated %d pages\n", rel);
751
752 return pblist;
753} 684}
754 685
755/* 686/*
@@ -888,7 +819,7 @@ static int check_sig(void)
888 * Reset swap signature now. 819 * Reset swap signature now.
889 */ 820 */
890 error = bio_write_page(0, &swsusp_header); 821 error = bio_write_page(0, &swsusp_header);
891 } else { 822 } else {
892 return -EINVAL; 823 return -EINVAL;
893 } 824 }
894 if (!error) 825 if (!error)
@@ -990,20 +921,25 @@ static int read_suspend_image(void)
990 int error = 0; 921 int error = 0;
991 struct pbe *p; 922 struct pbe *p;
992 923
993 if (!(p = alloc_pagedir(nr_copy_pages))) 924 if (!(p = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 0)))
994 return -ENOMEM; 925 return -ENOMEM;
995 926
996 if ((error = read_pagedir(p))) 927 if ((error = read_pagedir(p)))
997 return error; 928 return error;
998
999 create_pbe_list(p, nr_copy_pages); 929 create_pbe_list(p, nr_copy_pages);
1000 930 mark_unsafe_pages(p);
1001 if (!(pagedir_nosave = swsusp_pagedir_relocate(p))) 931 pagedir_nosave = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1);
932 if (pagedir_nosave) {
933 create_pbe_list(pagedir_nosave, nr_copy_pages);
934 copy_page_backup_list(pagedir_nosave, p);
935 }
936 free_pagedir(p);
937 if (!pagedir_nosave)
1002 return -ENOMEM; 938 return -ENOMEM;
1003 939
1004 /* Allocate memory for the image and read the data from swap */ 940 /* Allocate memory for the image and read the data from swap */
1005 941
1006 error = check_pagedir(pagedir_nosave); 942 error = alloc_data_pages(pagedir_nosave, GFP_ATOMIC, 1);
1007 943
1008 if (!error) 944 if (!error)
1009 error = data_read(pagedir_nosave); 945 error = data_read(pagedir_nosave);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 5b8dd98a230e..b88d4186cd7a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -155,7 +155,7 @@ int ptrace_attach(struct task_struct *task)
155 retval = -EPERM; 155 retval = -EPERM;
156 if (task->pid <= 1) 156 if (task->pid <= 1)
157 goto bad; 157 goto bad;
158 if (task == current) 158 if (task->tgid == current->tgid)
159 goto bad; 159 goto bad;
160 /* the same process cannot be attached many times */ 160 /* the same process cannot be attached many times */
161 if (task->ptrace & PT_PTRACED) 161 if (task->ptrace & PT_PTRACED)
diff --git a/kernel/sched.c b/kernel/sched.c
index 3ce26954be12..b6506671b2be 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -206,6 +206,7 @@ struct runqueue {
206 */ 206 */
207 unsigned long nr_running; 207 unsigned long nr_running;
208#ifdef CONFIG_SMP 208#ifdef CONFIG_SMP
209 unsigned long prio_bias;
209 unsigned long cpu_load[3]; 210 unsigned long cpu_load[3];
210#endif 211#endif
211 unsigned long long nr_switches; 212 unsigned long long nr_switches;
@@ -659,13 +660,68 @@ static int effective_prio(task_t *p)
659 return prio; 660 return prio;
660} 661}
661 662
663#ifdef CONFIG_SMP
664static inline void inc_prio_bias(runqueue_t *rq, int prio)
665{
666 rq->prio_bias += MAX_PRIO - prio;
667}
668
669static inline void dec_prio_bias(runqueue_t *rq, int prio)
670{
671 rq->prio_bias -= MAX_PRIO - prio;
672}
673
674static inline void inc_nr_running(task_t *p, runqueue_t *rq)
675{
676 rq->nr_running++;
677 if (rt_task(p)) {
678 if (p != rq->migration_thread)
679 /*
680 * The migration thread does the actual balancing. Do
681 * not bias by its priority as the ultra high priority
682 * will skew balancing adversely.
683 */
684 inc_prio_bias(rq, p->prio);
685 } else
686 inc_prio_bias(rq, p->static_prio);
687}
688
689static inline void dec_nr_running(task_t *p, runqueue_t *rq)
690{
691 rq->nr_running--;
692 if (rt_task(p)) {
693 if (p != rq->migration_thread)
694 dec_prio_bias(rq, p->prio);
695 } else
696 dec_prio_bias(rq, p->static_prio);
697}
698#else
699static inline void inc_prio_bias(runqueue_t *rq, int prio)
700{
701}
702
703static inline void dec_prio_bias(runqueue_t *rq, int prio)
704{
705}
706
707static inline void inc_nr_running(task_t *p, runqueue_t *rq)
708{
709 rq->nr_running++;
710}
711
712static inline void dec_nr_running(task_t *p, runqueue_t *rq)
713{
714 rq->nr_running--;
715}
716#endif
717
662/* 718/*
663 * __activate_task - move a task to the runqueue. 719 * __activate_task - move a task to the runqueue.
664 */ 720 */
665static inline void __activate_task(task_t *p, runqueue_t *rq) 721static inline void __activate_task(task_t *p, runqueue_t *rq)
666{ 722{
667 enqueue_task(p, rq->active); 723 enqueue_task(p, rq->active);
668 rq->nr_running++; 724 inc_nr_running(p, rq);
669} 725}
670 726
671/* 727/*
@@ -674,7 +730,7 @@ static inline void __activate_task(task_t *p, runqueue_t *rq)
674static inline void __activate_idle_task(task_t *p, runqueue_t *rq) 730static inline void __activate_idle_task(task_t *p, runqueue_t *rq)
675{ 731{
676 enqueue_task_head(p, rq->active); 732 enqueue_task_head(p, rq->active);
677 rq->nr_running++; 733 inc_nr_running(p, rq);
678} 734}
679 735
680static int recalc_task_prio(task_t *p, unsigned long long now) 736static int recalc_task_prio(task_t *p, unsigned long long now)
@@ -759,7 +815,8 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
759 } 815 }
760#endif 816#endif
761 817
762 p->prio = recalc_task_prio(p, now); 818 if (!rt_task(p))
819 p->prio = recalc_task_prio(p, now);
763 820
764 /* 821 /*
765 * This checks to make sure it's not an uninterruptible task 822 * This checks to make sure it's not an uninterruptible task
@@ -793,7 +850,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
793 */ 850 */
794static void deactivate_task(struct task_struct *p, runqueue_t *rq) 851static void deactivate_task(struct task_struct *p, runqueue_t *rq)
795{ 852{
796 rq->nr_running--; 853 dec_nr_running(p, rq);
797 dequeue_task(p, p->array); 854 dequeue_task(p, p->array);
798 p->array = NULL; 855 p->array = NULL;
799} 856}
@@ -808,21 +865,28 @@ static void deactivate_task(struct task_struct *p, runqueue_t *rq)
808#ifdef CONFIG_SMP 865#ifdef CONFIG_SMP
809static void resched_task(task_t *p) 866static void resched_task(task_t *p)
810{ 867{
811 int need_resched, nrpolling; 868 int cpu;
812 869
813 assert_spin_locked(&task_rq(p)->lock); 870 assert_spin_locked(&task_rq(p)->lock);
814 871
815 /* minimise the chance of sending an interrupt to poll_idle() */ 872 if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED)))
816 nrpolling = test_tsk_thread_flag(p,TIF_POLLING_NRFLAG); 873 return;
817 need_resched = test_and_set_tsk_thread_flag(p,TIF_NEED_RESCHED); 874
818 nrpolling |= test_tsk_thread_flag(p,TIF_POLLING_NRFLAG); 875 set_tsk_thread_flag(p, TIF_NEED_RESCHED);
876
877 cpu = task_cpu(p);
878 if (cpu == smp_processor_id())
879 return;
819 880
820 if (!need_resched && !nrpolling && (task_cpu(p) != smp_processor_id())) 881 /* NEED_RESCHED must be visible before we test POLLING_NRFLAG */
821 smp_send_reschedule(task_cpu(p)); 882 smp_mb();
883 if (!test_tsk_thread_flag(p, TIF_POLLING_NRFLAG))
884 smp_send_reschedule(cpu);
822} 885}
823#else 886#else
824static inline void resched_task(task_t *p) 887static inline void resched_task(task_t *p)
825{ 888{
889 assert_spin_locked(&task_rq(p)->lock);
826 set_tsk_need_resched(p); 890 set_tsk_need_resched(p);
827} 891}
828#endif 892#endif
@@ -930,27 +994,61 @@ void kick_process(task_t *p)
930 * We want to under-estimate the load of migration sources, to 994 * We want to under-estimate the load of migration sources, to
931 * balance conservatively. 995 * balance conservatively.
932 */ 996 */
933static inline unsigned long source_load(int cpu, int type) 997static inline unsigned long __source_load(int cpu, int type, enum idle_type idle)
934{ 998{
935 runqueue_t *rq = cpu_rq(cpu); 999 runqueue_t *rq = cpu_rq(cpu);
936 unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; 1000 unsigned long running = rq->nr_running;
1001 unsigned long source_load, cpu_load = rq->cpu_load[type-1],
1002 load_now = running * SCHED_LOAD_SCALE;
1003
937 if (type == 0) 1004 if (type == 0)
938 return load_now; 1005 source_load = load_now;
1006 else
1007 source_load = min(cpu_load, load_now);
939 1008
940 return min(rq->cpu_load[type-1], load_now); 1009 if (running > 1 || (idle == NOT_IDLE && running))
1010 /*
1011 * If we are busy rebalancing the load is biased by
1012 * priority to create 'nice' support across cpus. When
1013 * idle rebalancing we should only bias the source_load if
1014 * there is more than one task running on that queue to
1015 * prevent idle rebalance from trying to pull tasks from a
1016 * queue with only one running task.
1017 */
1018 source_load = source_load * rq->prio_bias / running;
1019
1020 return source_load;
1021}
1022
1023static inline unsigned long source_load(int cpu, int type)
1024{
1025 return __source_load(cpu, type, NOT_IDLE);
941} 1026}
942 1027
943/* 1028/*
944 * Return a high guess at the load of a migration-target cpu 1029 * Return a high guess at the load of a migration-target cpu
945 */ 1030 */
946static inline unsigned long target_load(int cpu, int type) 1031static inline unsigned long __target_load(int cpu, int type, enum idle_type idle)
947{ 1032{
948 runqueue_t *rq = cpu_rq(cpu); 1033 runqueue_t *rq = cpu_rq(cpu);
949 unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; 1034 unsigned long running = rq->nr_running;
1035 unsigned long target_load, cpu_load = rq->cpu_load[type-1],
1036 load_now = running * SCHED_LOAD_SCALE;
1037
950 if (type == 0) 1038 if (type == 0)
951 return load_now; 1039 target_load = load_now;
1040 else
1041 target_load = max(cpu_load, load_now);
1042
1043 if (running > 1 || (idle == NOT_IDLE && running))
1044 target_load = target_load * rq->prio_bias / running;
952 1045
953 return max(rq->cpu_load[type-1], load_now); 1046 return target_load;
1047}
1048
1049static inline unsigned long target_load(int cpu, int type)
1050{
1051 return __target_load(cpu, type, NOT_IDLE);
954} 1052}
955 1053
956/* 1054/*
@@ -1411,7 +1509,7 @@ void fastcall wake_up_new_task(task_t *p, unsigned long clone_flags)
1411 list_add_tail(&p->run_list, &current->run_list); 1509 list_add_tail(&p->run_list, &current->run_list);
1412 p->array = current->array; 1510 p->array = current->array;
1413 p->array->nr_active++; 1511 p->array->nr_active++;
1414 rq->nr_running++; 1512 inc_nr_running(p, rq);
1415 } 1513 }
1416 set_need_resched(); 1514 set_need_resched();
1417 } else 1515 } else
@@ -1756,9 +1854,9 @@ void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p,
1756 runqueue_t *this_rq, prio_array_t *this_array, int this_cpu) 1854 runqueue_t *this_rq, prio_array_t *this_array, int this_cpu)
1757{ 1855{
1758 dequeue_task(p, src_array); 1856 dequeue_task(p, src_array);
1759 src_rq->nr_running--; 1857 dec_nr_running(p, src_rq);
1760 set_task_cpu(p, this_cpu); 1858 set_task_cpu(p, this_cpu);
1761 this_rq->nr_running++; 1859 inc_nr_running(p, this_rq);
1762 enqueue_task(p, this_array); 1860 enqueue_task(p, this_array);
1763 p->timestamp = (p->timestamp - src_rq->timestamp_last_tick) 1861 p->timestamp = (p->timestamp - src_rq->timestamp_last_tick)
1764 + this_rq->timestamp_last_tick; 1862 + this_rq->timestamp_last_tick;
@@ -1937,9 +2035,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
1937 2035
1938 /* Bias balancing toward cpus of our domain */ 2036 /* Bias balancing toward cpus of our domain */
1939 if (local_group) 2037 if (local_group)
1940 load = target_load(i, load_idx); 2038 load = __target_load(i, load_idx, idle);
1941 else 2039 else
1942 load = source_load(i, load_idx); 2040 load = __source_load(i, load_idx, idle);
1943 2041
1944 avg_load += load; 2042 avg_load += load;
1945 } 2043 }
@@ -2044,14 +2142,15 @@ out_balanced:
2044/* 2142/*
2045 * find_busiest_queue - find the busiest runqueue among the cpus in group. 2143 * find_busiest_queue - find the busiest runqueue among the cpus in group.
2046 */ 2144 */
2047static runqueue_t *find_busiest_queue(struct sched_group *group) 2145static runqueue_t *find_busiest_queue(struct sched_group *group,
2146 enum idle_type idle)
2048{ 2147{
2049 unsigned long load, max_load = 0; 2148 unsigned long load, max_load = 0;
2050 runqueue_t *busiest = NULL; 2149 runqueue_t *busiest = NULL;
2051 int i; 2150 int i;
2052 2151
2053 for_each_cpu_mask(i, group->cpumask) { 2152 for_each_cpu_mask(i, group->cpumask) {
2054 load = source_load(i, 0); 2153 load = __source_load(i, 0, idle);
2055 2154
2056 if (load > max_load) { 2155 if (load > max_load) {
2057 max_load = load; 2156 max_load = load;
@@ -2095,7 +2194,7 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
2095 goto out_balanced; 2194 goto out_balanced;
2096 } 2195 }
2097 2196
2098 busiest = find_busiest_queue(group); 2197 busiest = find_busiest_queue(group, idle);
2099 if (!busiest) { 2198 if (!busiest) {
2100 schedstat_inc(sd, lb_nobusyq[idle]); 2199 schedstat_inc(sd, lb_nobusyq[idle]);
2101 goto out_balanced; 2200 goto out_balanced;
@@ -2218,7 +2317,7 @@ static int load_balance_newidle(int this_cpu, runqueue_t *this_rq,
2218 goto out_balanced; 2317 goto out_balanced;
2219 } 2318 }
2220 2319
2221 busiest = find_busiest_queue(group); 2320 busiest = find_busiest_queue(group, NEWLY_IDLE);
2222 if (!busiest) { 2321 if (!busiest) {
2223 schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]); 2322 schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]);
2224 goto out_balanced; 2323 goto out_balanced;
@@ -3451,8 +3550,10 @@ void set_user_nice(task_t *p, long nice)
3451 goto out_unlock; 3550 goto out_unlock;
3452 } 3551 }
3453 array = p->array; 3552 array = p->array;
3454 if (array) 3553 if (array) {
3455 dequeue_task(p, array); 3554 dequeue_task(p, array);
3555 dec_prio_bias(rq, p->static_prio);
3556 }
3456 3557
3457 old_prio = p->prio; 3558 old_prio = p->prio;
3458 new_prio = NICE_TO_PRIO(nice); 3559 new_prio = NICE_TO_PRIO(nice);
@@ -3462,6 +3563,7 @@ void set_user_nice(task_t *p, long nice)
3462 3563
3463 if (array) { 3564 if (array) {
3464 enqueue_task(p, array); 3565 enqueue_task(p, array);
3566 inc_prio_bias(rq, p->static_prio);
3465 /* 3567 /*
3466 * If the task increased its priority or is running and 3568 * If the task increased its priority or is running and
3467 * lowered its priority, then reschedule its CPU: 3569 * lowered its priority, then reschedule its CPU:
diff --git a/kernel/signal.c b/kernel/signal.c
index 1bf3c39d6109..80789a59b4db 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1499,7 +1499,7 @@ void do_notify_parent(struct task_struct *tsk, int sig)
1499 1499
1500 psig = tsk->parent->sighand; 1500 psig = tsk->parent->sighand;
1501 spin_lock_irqsave(&psig->siglock, flags); 1501 spin_lock_irqsave(&psig->siglock, flags);
1502 if (sig == SIGCHLD && 1502 if (!tsk->ptrace && sig == SIGCHLD &&
1503 (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN || 1503 (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
1504 (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) { 1504 (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
1505 /* 1505 /*
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index a2dcceb9437d..c67189a25d52 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -73,9 +73,6 @@ void softlockup_tick(struct pt_regs *regs)
73static int watchdog(void * __bind_cpu) 73static int watchdog(void * __bind_cpu)
74{ 74{
75 struct sched_param param = { .sched_priority = 99 }; 75 struct sched_param param = { .sched_priority = 99 };
76 int this_cpu = (long) __bind_cpu;
77
78 printk("softlockup thread %d started up.\n", this_cpu);
79 76
80 sched_setscheduler(current, SCHED_FIFO, &param); 77 sched_setscheduler(current, SCHED_FIFO, &param);
81 current->flags |= PF_NOFREEZE; 78 current->flags |= PF_NOFREEZE;
diff --git a/kernel/sys.c b/kernel/sys.c
index c43b3e22bbda..bce933ebb29f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1497,6 +1497,8 @@ EXPORT_SYMBOL(in_egroup_p);
1497 1497
1498DECLARE_RWSEM(uts_sem); 1498DECLARE_RWSEM(uts_sem);
1499 1499
1500EXPORT_SYMBOL(uts_sem);
1501
1500asmlinkage long sys_newuname(struct new_utsname __user * name) 1502asmlinkage long sys_newuname(struct new_utsname __user * name)
1501{ 1503{
1502 int errno = 0; 1504 int errno = 0;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ff81b5c65511..987225bdd661 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1330,7 +1330,7 @@ void show_free_areas(void)
1330 } else 1330 } else
1331 printk("\n"); 1331 printk("\n");
1332 1332
1333 for_each_cpu(cpu) { 1333 for_each_online_cpu(cpu) {
1334 struct per_cpu_pageset *pageset; 1334 struct per_cpu_pageset *pageset;
1335 1335
1336 pageset = zone_pcp(zone, cpu); 1336 pageset = zone_pcp(zone, cpu);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index d219435d086c..1bcfef51ac58 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -350,6 +350,20 @@ fault:
350 return -EFAULT; 350 return -EFAULT;
351} 351}
352 352
353unsigned int __skb_checksum_complete(struct sk_buff *skb)
354{
355 unsigned int sum;
356
357 sum = (u16)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
358 if (likely(!sum)) {
359 if (unlikely(skb->ip_summed == CHECKSUM_HW))
360 netdev_rx_csum_fault(skb->dev);
361 skb->ip_summed = CHECKSUM_UNNECESSARY;
362 }
363 return sum;
364}
365EXPORT_SYMBOL(__skb_checksum_complete);
366
353/** 367/**
354 * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec. 368 * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec.
355 * @skb: skbuff 369 * @skb: skbuff
@@ -363,7 +377,7 @@ fault:
363 * -EFAULT - fault during copy. Beware, in this case iovec 377 * -EFAULT - fault during copy. Beware, in this case iovec
364 * can be modified! 378 * can be modified!
365 */ 379 */
366int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb, 380int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
367 int hlen, struct iovec *iov) 381 int hlen, struct iovec *iov)
368{ 382{
369 unsigned int csum; 383 unsigned int csum;
@@ -376,8 +390,7 @@ int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
376 iov++; 390 iov++;
377 391
378 if (iov->iov_len < chunk) { 392 if (iov->iov_len < chunk) {
379 if ((unsigned short)csum_fold(skb_checksum(skb, 0, chunk + hlen, 393 if (__skb_checksum_complete(skb))
380 skb->csum)))
381 goto csum_error; 394 goto csum_error;
382 if (skb_copy_datagram_iovec(skb, hlen, iov, chunk)) 395 if (skb_copy_datagram_iovec(skb, hlen, iov, chunk))
383 goto fault; 396 goto fault;
@@ -388,6 +401,8 @@ int skb_copy_and_csum_datagram_iovec(const struct sk_buff *skb,
388 goto fault; 401 goto fault;
389 if ((unsigned short)csum_fold(csum)) 402 if ((unsigned short)csum_fold(csum))
390 goto csum_error; 403 goto csum_error;
404 if (unlikely(skb->ip_summed == CHECKSUM_HW))
405 netdev_rx_csum_fault(skb->dev);
391 iov->iov_len -= chunk; 406 iov->iov_len -= chunk;
392 iov->iov_base += chunk; 407 iov->iov_base += chunk;
393 } 408 }
diff --git a/net/core/dev.c b/net/core/dev.c
index 8d1541595277..0b48e294aafe 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1108,6 +1108,18 @@ out:
1108 return ret; 1108 return ret;
1109} 1109}
1110 1110
1111/* Take action when hardware reception checksum errors are detected. */
1112#ifdef CONFIG_BUG
1113void netdev_rx_csum_fault(struct net_device *dev)
1114{
1115 if (net_ratelimit()) {
1116 printk(KERN_ERR "%s: hw csum failure.\n", dev->name);
1117 dump_stack();
1118 }
1119}
1120EXPORT_SYMBOL(netdev_rx_csum_fault);
1121#endif
1122
1111#ifdef CONFIG_HIGHMEM 1123#ifdef CONFIG_HIGHMEM
1112/* Actually, we should eliminate this check as soon as we know, that: 1124/* Actually, we should eliminate this check as soon as we know, that:
1113 * 1. IOMMU is present and allows to map all the memory. 1125 * 1. IOMMU is present and allows to map all the memory.
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 802fe11efad0..49424a42a2c0 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -101,16 +101,20 @@ void netpoll_queue(struct sk_buff *skb)
101static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, 101static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
102 unsigned short ulen, u32 saddr, u32 daddr) 102 unsigned short ulen, u32 saddr, u32 daddr)
103{ 103{
104 if (uh->check == 0) 104 unsigned int psum;
105
106 if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY)
105 return 0; 107 return 0;
106 108
107 if (skb->ip_summed == CHECKSUM_HW) 109 psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
108 return csum_tcpudp_magic( 110
109 saddr, daddr, ulen, IPPROTO_UDP, skb->csum); 111 if (skb->ip_summed == CHECKSUM_HW &&
112 !(u16)csum_fold(csum_add(psum, skb->csum)))
113 return 0;
110 114
111 skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); 115 skb->csum = psum;
112 116
113 return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); 117 return __skb_checksum_complete(skb);
114} 118}
115 119
116/* 120/*
@@ -489,7 +493,7 @@ int __netpoll_rx(struct sk_buff *skb)
489 493
490 if (ulen != len) 494 if (ulen != len)
491 goto out; 495 goto out;
492 if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0) 496 if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr))
493 goto out; 497 goto out;
494 if (np->local_ip && np->local_ip != ntohl(iph->daddr)) 498 if (np->local_ip && np->local_ip != ntohl(iph->daddr))
495 goto out; 499 goto out;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9bed7569ce3f..8700379685e0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -49,6 +49,7 @@
49#include <net/udp.h> 49#include <net/udp.h>
50#include <net/sock.h> 50#include <net/sock.h>
51#include <net/pkt_sched.h> 51#include <net/pkt_sched.h>
52#include <net/netlink.h>
52 53
53DECLARE_MUTEX(rtnl_sem); 54DECLARE_MUTEX(rtnl_sem);
54 55
@@ -462,11 +463,6 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
462 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_KERNEL); 463 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_KERNEL);
463} 464}
464 465
465static int rtnetlink_done(struct netlink_callback *cb)
466{
467 return 0;
468}
469
470/* Protected by RTNL sempahore. */ 466/* Protected by RTNL sempahore. */
471static struct rtattr **rta_buf; 467static struct rtattr **rta_buf;
472static int rtattr_max; 468static int rtattr_max;
@@ -524,8 +520,6 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
524 } 520 }
525 521
526 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 522 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
527 u32 rlen;
528
529 if (link->dumpit == NULL) 523 if (link->dumpit == NULL)
530 link = &(rtnetlink_links[PF_UNSPEC][type]); 524 link = &(rtnetlink_links[PF_UNSPEC][type]);
531 525
@@ -533,14 +527,11 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
533 goto err_inval; 527 goto err_inval;
534 528
535 if ((*errp = netlink_dump_start(rtnl, skb, nlh, 529 if ((*errp = netlink_dump_start(rtnl, skb, nlh,
536 link->dumpit, 530 link->dumpit, NULL)) != 0) {
537 rtnetlink_done)) != 0) {
538 return -1; 531 return -1;
539 } 532 }
540 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 533
541 if (rlen > skb->len) 534 netlink_queue_skip(nlh, skb);
542 rlen = skb->len;
543 skb_pull(skb, rlen);
544 return -1; 535 return -1;
545 } 536 }
546 537
@@ -579,75 +570,13 @@ err_inval:
579 return -1; 570 return -1;
580} 571}
581 572
582/*
583 * Process one packet of messages.
584 * Malformed skbs with wrong lengths of messages are discarded silently.
585 */
586
587static inline int rtnetlink_rcv_skb(struct sk_buff *skb)
588{
589 int err;
590 struct nlmsghdr * nlh;
591
592 while (skb->len >= NLMSG_SPACE(0)) {
593 u32 rlen;
594
595 nlh = (struct nlmsghdr *)skb->data;
596 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
597 return 0;
598 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
599 if (rlen > skb->len)
600 rlen = skb->len;
601 if (rtnetlink_rcv_msg(skb, nlh, &err)) {
602 /* Not error, but we must interrupt processing here:
603 * Note, that in this case we do not pull message
604 * from skb, it will be processed later.
605 */
606 if (err == 0)
607 return -1;
608 netlink_ack(skb, nlh, err);
609 } else if (nlh->nlmsg_flags&NLM_F_ACK)
610 netlink_ack(skb, nlh, 0);
611 skb_pull(skb, rlen);
612 }
613
614 return 0;
615}
616
617/*
618 * rtnetlink input queue processing routine:
619 * - process as much as there was in the queue upon entry.
620 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message,
621 * that will occur, when a dump started.
622 */
623
624static void rtnetlink_rcv(struct sock *sk, int len) 573static void rtnetlink_rcv(struct sock *sk, int len)
625{ 574{
626 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); 575 unsigned int qlen = 0;
627 576
628 do { 577 do {
629 struct sk_buff *skb;
630
631 rtnl_lock(); 578 rtnl_lock();
632 579 netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg);
633 if (qlen > skb_queue_len(&sk->sk_receive_queue))
634 qlen = skb_queue_len(&sk->sk_receive_queue);
635
636 for (; qlen; qlen--) {
637 skb = skb_dequeue(&sk->sk_receive_queue);
638 if (rtnetlink_rcv_skb(skb)) {
639 if (skb->len)
640 skb_queue_head(&sk->sk_receive_queue,
641 skb);
642 else {
643 kfree_skb(skb);
644 qlen--;
645 }
646 break;
647 }
648 kfree_skb(skb);
649 }
650
651 up(&rtnl_sem); 580 up(&rtnl_sem);
652 581
653 netdev_run_todo(); 582 netdev_run_todo();
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 95501e40100e..b7d13a4fff48 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -336,6 +336,9 @@ void __kfree_skb(struct sk_buff *skb)
336 } 336 }
337#ifdef CONFIG_NETFILTER 337#ifdef CONFIG_NETFILTER
338 nf_conntrack_put(skb->nfct); 338 nf_conntrack_put(skb->nfct);
339#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
340 nf_conntrack_put_reasm(skb->nfct_reasm);
341#endif
339#ifdef CONFIG_BRIDGE_NETFILTER 342#ifdef CONFIG_BRIDGE_NETFILTER
340 nf_bridge_put(skb->nf_bridge); 343 nf_bridge_put(skb->nf_bridge);
341#endif 344#endif
@@ -414,9 +417,17 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
414 C(nfct); 417 C(nfct);
415 nf_conntrack_get(skb->nfct); 418 nf_conntrack_get(skb->nfct);
416 C(nfctinfo); 419 C(nfctinfo);
420#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
421 C(nfct_reasm);
422 nf_conntrack_get_reasm(skb->nfct_reasm);
423#endif
417#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 424#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
418 C(ipvs_property); 425 C(ipvs_property);
419#endif 426#endif
427#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
428 C(nfct_reasm);
429 nf_conntrack_get_reasm(skb->nfct_reasm);
430#endif
420#ifdef CONFIG_BRIDGE_NETFILTER 431#ifdef CONFIG_BRIDGE_NETFILTER
421 C(nf_bridge); 432 C(nf_bridge);
422 nf_bridge_get(skb->nf_bridge); 433 nf_bridge_get(skb->nf_bridge);
@@ -474,6 +485,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
474 new->nfct = old->nfct; 485 new->nfct = old->nfct;
475 nf_conntrack_get(old->nfct); 486 nf_conntrack_get(old->nfct);
476 new->nfctinfo = old->nfctinfo; 487 new->nfctinfo = old->nfctinfo;
488#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
489 new->nfct_reasm = old->nfct_reasm;
490 nf_conntrack_get_reasm(old->nfct_reasm);
491#endif
477#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 492#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
478 new->ipvs_property = old->ipvs_property; 493 new->ipvs_property = old->ipvs_property;
479#endif 494#endif
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index 20cc580a07e0..ecc9bb196abc 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -11,15 +11,14 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/config.h> 14#include <linux/errno.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <asm/string.h> 18#include <linux/string.h>
19#include <asm/errno.h>
20
21#include <net/ieee80211.h> 19#include <net/ieee80211.h>
22 20
21
23MODULE_AUTHOR("Jouni Malinen"); 22MODULE_AUTHOR("Jouni Malinen");
24MODULE_DESCRIPTION("HostAP crypto"); 23MODULE_DESCRIPTION("HostAP crypto");
25MODULE_LICENSE("GPL"); 24MODULE_LICENSE("GPL");
@@ -29,32 +28,20 @@ struct ieee80211_crypto_alg {
29 struct ieee80211_crypto_ops *ops; 28 struct ieee80211_crypto_ops *ops;
30}; 29};
31 30
32struct ieee80211_crypto { 31static LIST_HEAD(ieee80211_crypto_algs);
33 struct list_head algs; 32static DEFINE_SPINLOCK(ieee80211_crypto_lock);
34 spinlock_t lock;
35};
36
37static struct ieee80211_crypto *hcrypt;
38 33
39void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) 34void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
40{ 35{
41 struct list_head *ptr, *n; 36 struct ieee80211_crypt_data *entry, *next;
42 struct ieee80211_crypt_data *entry;
43 unsigned long flags; 37 unsigned long flags;
44 38
45 spin_lock_irqsave(&ieee->lock, flags); 39 spin_lock_irqsave(&ieee->lock, flags);
46 40 list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
47 if (list_empty(&ieee->crypt_deinit_list))
48 goto unlock;
49
50 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
51 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
52 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
53
54 if (atomic_read(&entry->refcnt) != 0 && !force) 41 if (atomic_read(&entry->refcnt) != 0 && !force)
55 continue; 42 continue;
56 43
57 list_del(ptr); 44 list_del(&entry->list);
58 45
59 if (entry->ops) { 46 if (entry->ops) {
60 entry->ops->deinit(entry->priv); 47 entry->ops->deinit(entry->priv);
@@ -62,7 +49,6 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
62 } 49 }
63 kfree(entry); 50 kfree(entry);
64 } 51 }
65 unlock:
66 spin_unlock_irqrestore(&ieee->lock, flags); 52 spin_unlock_irqrestore(&ieee->lock, flags);
67} 53}
68 54
@@ -125,9 +111,6 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
125 unsigned long flags; 111 unsigned long flags;
126 struct ieee80211_crypto_alg *alg; 112 struct ieee80211_crypto_alg *alg;
127 113
128 if (hcrypt == NULL)
129 return -1;
130
131 alg = kmalloc(sizeof(*alg), GFP_KERNEL); 114 alg = kmalloc(sizeof(*alg), GFP_KERNEL);
132 if (alg == NULL) 115 if (alg == NULL)
133 return -ENOMEM; 116 return -ENOMEM;
@@ -135,9 +118,9 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
135 memset(alg, 0, sizeof(*alg)); 118 memset(alg, 0, sizeof(*alg));
136 alg->ops = ops; 119 alg->ops = ops;
137 120
138 spin_lock_irqsave(&hcrypt->lock, flags); 121 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
139 list_add(&alg->list, &hcrypt->algs); 122 list_add(&alg->list, &ieee80211_crypto_algs);
140 spin_unlock_irqrestore(&hcrypt->lock, flags); 123 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
141 124
142 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", 125 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
143 ops->name); 126 ops->name);
@@ -147,64 +130,49 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
147 130
148int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) 131int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
149{ 132{
133 struct ieee80211_crypto_alg *alg;
150 unsigned long flags; 134 unsigned long flags;
151 struct list_head *ptr;
152 struct ieee80211_crypto_alg *del_alg = NULL;
153
154 if (hcrypt == NULL)
155 return -1;
156
157 spin_lock_irqsave(&hcrypt->lock, flags);
158 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
159 struct ieee80211_crypto_alg *alg =
160 (struct ieee80211_crypto_alg *)ptr;
161 if (alg->ops == ops) {
162 list_del(&alg->list);
163 del_alg = alg;
164 break;
165 }
166 }
167 spin_unlock_irqrestore(&hcrypt->lock, flags);
168 135
169 if (del_alg) { 136 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
170 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " 137 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
171 "'%s'\n", ops->name); 138 if (alg->ops == ops)
172 kfree(del_alg); 139 goto found;
173 } 140 }
174 141 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
175 return del_alg ? 0 : -1; 142 return -EINVAL;
143
144 found:
145 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
146 "'%s'\n", ops->name);
147 list_del(&alg->list);
148 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
149 kfree(alg);
150 return 0;
176} 151}
177 152
178struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) 153struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
179{ 154{
155 struct ieee80211_crypto_alg *alg;
180 unsigned long flags; 156 unsigned long flags;
181 struct list_head *ptr; 157
182 struct ieee80211_crypto_alg *found_alg = NULL; 158 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
183 159 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
184 if (hcrypt == NULL) 160 if (strcmp(alg->ops->name, name) == 0)
185 return NULL; 161 goto found;
186
187 spin_lock_irqsave(&hcrypt->lock, flags);
188 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
189 struct ieee80211_crypto_alg *alg =
190 (struct ieee80211_crypto_alg *)ptr;
191 if (strcmp(alg->ops->name, name) == 0) {
192 found_alg = alg;
193 break;
194 }
195 } 162 }
196 spin_unlock_irqrestore(&hcrypt->lock, flags); 163 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
164 return NULL;
197 165
198 if (found_alg) 166 found:
199 return found_alg->ops; 167 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
200 else 168 return alg->ops;
201 return NULL;
202} 169}
203 170
204static void *ieee80211_crypt_null_init(int keyidx) 171static void *ieee80211_crypt_null_init(int keyidx)
205{ 172{
206 return (void *)1; 173 return (void *)1;
207} 174}
175
208static void ieee80211_crypt_null_deinit(void *priv) 176static void ieee80211_crypt_null_deinit(void *priv)
209{ 177{
210} 178}
@@ -213,56 +181,18 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
213 .name = "NULL", 181 .name = "NULL",
214 .init = ieee80211_crypt_null_init, 182 .init = ieee80211_crypt_null_init,
215 .deinit = ieee80211_crypt_null_deinit, 183 .deinit = ieee80211_crypt_null_deinit,
216 .encrypt_mpdu = NULL,
217 .decrypt_mpdu = NULL,
218 .encrypt_msdu = NULL,
219 .decrypt_msdu = NULL,
220 .set_key = NULL,
221 .get_key = NULL,
222 .extra_mpdu_prefix_len = 0,
223 .extra_mpdu_postfix_len = 0,
224 .owner = THIS_MODULE, 184 .owner = THIS_MODULE,
225}; 185};
226 186
227static int __init ieee80211_crypto_init(void) 187static int __init ieee80211_crypto_init(void)
228{ 188{
229 int ret = -ENOMEM; 189 return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
230
231 hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
232 if (!hcrypt)
233 goto out;
234
235 memset(hcrypt, 0, sizeof(*hcrypt));
236 INIT_LIST_HEAD(&hcrypt->algs);
237 spin_lock_init(&hcrypt->lock);
238
239 ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
240 if (ret < 0) {
241 kfree(hcrypt);
242 hcrypt = NULL;
243 }
244 out:
245 return ret;
246} 190}
247 191
248static void __exit ieee80211_crypto_deinit(void) 192static void __exit ieee80211_crypto_deinit(void)
249{ 193{
250 struct list_head *ptr, *n; 194 ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
251 195 BUG_ON(!list_empty(&ieee80211_crypto_algs));
252 if (hcrypt == NULL)
253 return;
254
255 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
256 ptr = n, n = ptr->next) {
257 struct ieee80211_crypto_alg *alg =
258 (struct ieee80211_crypto_alg *)ptr;
259 list_del(ptr);
260 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
261 "'%s' (deinit)\n", alg->ops->name);
262 kfree(alg);
263 }
264
265 kfree(hcrypt);
266} 196}
267 197
268EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); 198EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 6ad88218f573..03efaacbdb73 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -369,6 +369,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
369 /* Put this code here so that we avoid duplicating it in all 369 /* Put this code here so that we avoid duplicating it in all
370 * Rx paths. - Jean II */ 370 * Rx paths. - Jean II */
371#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ 371#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
372#ifdef CONFIG_NET_RADIO
372 /* If spy monitoring on */ 373 /* If spy monitoring on */
373 if (ieee->spy_data.spy_number > 0) { 374 if (ieee->spy_data.spy_number > 0) {
374 struct iw_quality wstats; 375 struct iw_quality wstats;
@@ -395,6 +396,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
395 /* Update spy records */ 396 /* Update spy records */
396 wireless_spy_update(ieee->dev, hdr->addr2, &wstats); 397 wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
397 } 398 }
399#endif /* CONFIG_NET_RADIO */
398#endif /* IW_WIRELESS_SPY */ 400#endif /* IW_WIRELESS_SPY */
399 401
400#ifdef NOT_YET 402#ifdef NOT_YET
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 1ce7af9bec35..181755f2aa8b 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -161,9 +161,11 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
161 (ieee->perfect_rssi - ieee->worst_rssi) - 161 (ieee->perfect_rssi - ieee->worst_rssi) -
162 (ieee->perfect_rssi - network->stats.rssi) * 162 (ieee->perfect_rssi - network->stats.rssi) *
163 (15 * (ieee->perfect_rssi - ieee->worst_rssi) + 163 (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
164 62 * (ieee->perfect_rssi - network->stats.rssi))) / 164 62 * (ieee->perfect_rssi -
165 ((ieee->perfect_rssi - ieee->worst_rssi) * 165 network->stats.rssi))) /
166 (ieee->perfect_rssi - ieee->worst_rssi)); 166 ((ieee->perfect_rssi -
167 ieee->worst_rssi) * (ieee->perfect_rssi -
168 ieee->worst_rssi));
167 if (iwe.u.qual.qual > 100) 169 if (iwe.u.qual.qual > 100)
168 iwe.u.qual.qual = 100; 170 iwe.u.qual.qual = 100;
169 else if (iwe.u.qual.qual < 1) 171 else if (iwe.u.qual.qual < 1)
@@ -520,7 +522,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
520 crypt = &ieee->crypt[idx]; 522 crypt = &ieee->crypt[idx];
521 group_key = 1; 523 group_key = 1;
522 } else { 524 } else {
523 if (idx != 0) 525 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
526 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
524 return -EINVAL; 527 return -EINVAL;
525 if (ieee->iw_mode == IW_MODE_INFRA) 528 if (ieee->iw_mode == IW_MODE_INFRA)
526 crypt = &ieee->crypt[idx]; 529 crypt = &ieee->crypt[idx];
@@ -688,7 +691,8 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
688 } else 691 } else
689 idx = ieee->tx_keyidx; 692 idx = ieee->tx_keyidx;
690 693
691 if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) 694 if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
695 ext->alg != IW_ENCODE_ALG_WEP)
692 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) 696 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
693 return -EINVAL; 697 return -EINVAL;
694 698
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 175e093ec564..e3eceecd0496 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -934,11 +934,11 @@ int icmp_rcv(struct sk_buff *skb)
934 case CHECKSUM_HW: 934 case CHECKSUM_HW:
935 if (!(u16)csum_fold(skb->csum)) 935 if (!(u16)csum_fold(skb->csum))
936 break; 936 break;
937 LIMIT_NETDEBUG(KERN_DEBUG "icmp v4 hw csum failure\n"); 937 /* fall through */
938 case CHECKSUM_NONE: 938 case CHECKSUM_NONE:
939 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) 939 skb->csum = 0;
940 if (__skb_checksum_complete(skb))
940 goto error; 941 goto error;
941 default:;
942 } 942 }
943 943
944 if (!pskb_pull(skb, sizeof(struct icmphdr))) 944 if (!pskb_pull(skb, sizeof(struct icmphdr)))
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index c6247fc84060..c04607b49212 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -872,11 +872,18 @@ int igmp_rcv(struct sk_buff *skb)
872 return 0; 872 return 0;
873 } 873 }
874 874
875 if (!pskb_may_pull(skb, sizeof(struct igmphdr)) || 875 if (!pskb_may_pull(skb, sizeof(struct igmphdr)))
876 (u16)csum_fold(skb_checksum(skb, 0, len, 0))) { 876 goto drop;
877 in_dev_put(in_dev); 877
878 kfree_skb(skb); 878 switch (skb->ip_summed) {
879 return 0; 879 case CHECKSUM_HW:
880 if (!(u16)csum_fold(skb->csum))
881 break;
882 /* fall through */
883 case CHECKSUM_NONE:
884 skb->csum = 0;
885 if (__skb_checksum_complete(skb))
886 goto drop;
880 } 887 }
881 888
882 ih = skb->h.igmph; 889 ih = skb->h.igmph;
@@ -906,6 +913,8 @@ int igmp_rcv(struct sk_buff *skb)
906 default: 913 default:
907 NETDEBUG(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type); 914 NETDEBUG(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type);
908 } 915 }
916
917drop:
909 in_dev_put(in_dev); 918 in_dev_put(in_dev);
910 kfree_skb(skb); 919 kfree_skb(skb);
911 return 0; 920 return 0;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 71f3c7350c6e..39061ed53cfd 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -724,12 +724,6 @@ done:
724 return skb->len; 724 return skb->len;
725} 725}
726 726
727static int inet_diag_dump_done(struct netlink_callback *cb)
728{
729 return 0;
730}
731
732
733static __inline__ int 727static __inline__ int
734inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 728inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
735{ 729{
@@ -760,8 +754,7 @@ inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
760 goto err_inval; 754 goto err_inval;
761 } 755 }
762 return netlink_dump_start(idiagnl, skb, nlh, 756 return netlink_dump_start(idiagnl, skb, nlh,
763 inet_diag_dump, 757 inet_diag_dump, NULL);
764 inet_diag_dump_done);
765 } else { 758 } else {
766 return inet_diag_get_exact(skb, nlh); 759 return inet_diag_get_exact(skb, nlh);
767 } 760 }
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 896ce3f8f53a..4e9c74b54b15 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -577,15 +577,16 @@ static int ipgre_rcv(struct sk_buff *skb)
577 goto drop_nolock; 577 goto drop_nolock;
578 578
579 if (flags&GRE_CSUM) { 579 if (flags&GRE_CSUM) {
580 if (skb->ip_summed == CHECKSUM_HW) { 580 switch (skb->ip_summed) {
581 case CHECKSUM_HW:
581 csum = (u16)csum_fold(skb->csum); 582 csum = (u16)csum_fold(skb->csum);
582 if (csum) 583 if (!csum)
583 skb->ip_summed = CHECKSUM_NONE; 584 break;
584 } 585 /* fall through */
585 if (skb->ip_summed == CHECKSUM_NONE) { 586 case CHECKSUM_NONE:
586 skb->csum = skb_checksum(skb, 0, skb->len, 0); 587 skb->csum = 0;
588 csum = __skb_checksum_complete(skb);
587 skb->ip_summed = CHECKSUM_HW; 589 skb->ip_summed = CHECKSUM_HW;
588 csum = (u16)csum_fold(skb->csum);
589 } 590 }
590 offset += 4; 591 offset += 4;
591 } 592 }
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 7d917e4ce1d9..9d3c8b5f327e 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -5,6 +5,20 @@
5menu "IP: Netfilter Configuration" 5menu "IP: Netfilter Configuration"
6 depends on INET && NETFILTER 6 depends on INET && NETFILTER
7 7
8config NF_CONNTRACK_IPV4
9 tristate "IPv4 support for new connection tracking (EXPERIMENTAL)"
10 depends on EXPERIMENTAL && NF_CONNTRACK
11 ---help---
12 Connection tracking keeps a record of what packets have passed
13 through your machine, in order to figure out how they are related
14 into connections.
15
16 This is IPv4 support on Layer 3 independent connection tracking.
17 Layer 3 independent connection tracking is experimental scheme
18 which generalize ip_conntrack to support other layer 3 protocols.
19
20 To compile it as a module, choose M here. If unsure, say N.
21
8# connection tracking, helpers and protocols 22# connection tracking, helpers and protocols
9config IP_NF_CONNTRACK 23config IP_NF_CONNTRACK
10 tristate "Connection tracking (required for masq/NAT)" 24 tristate "Connection tracking (required for masq/NAT)"
@@ -209,8 +223,8 @@ config IP_NF_MATCH_PKTTYPE
209 tristate "Packet type match support" 223 tristate "Packet type match support"
210 depends on IP_NF_IPTABLES 224 depends on IP_NF_IPTABLES
211 help 225 help
212 Packet type matching allows you to match a packet by 226 Packet type matching allows you to match a packet by
213 its "class", eg. BROADCAST, MULTICAST, ... 227 its "class", eg. BROADCAST, MULTICAST, ...
214 228
215 Typical usage: 229 Typical usage:
216 iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG 230 iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
@@ -317,7 +331,8 @@ config IP_NF_MATCH_TCPMSS
317 331
318config IP_NF_MATCH_HELPER 332config IP_NF_MATCH_HELPER
319 tristate "Helper match support" 333 tristate "Helper match support"
320 depends on IP_NF_CONNTRACK && IP_NF_IPTABLES 334 depends on IP_NF_IPTABLES
335 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
321 help 336 help
322 Helper matching allows you to match packets in dynamic connections 337 Helper matching allows you to match packets in dynamic connections
323 tracked by a conntrack-helper, ie. ip_conntrack_ftp 338 tracked by a conntrack-helper, ie. ip_conntrack_ftp
@@ -326,7 +341,8 @@ config IP_NF_MATCH_HELPER
326 341
327config IP_NF_MATCH_STATE 342config IP_NF_MATCH_STATE
328 tristate "Connection state match support" 343 tristate "Connection state match support"
329 depends on IP_NF_CONNTRACK && IP_NF_IPTABLES 344 depends on IP_NF_IPTABLES
345 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
330 help 346 help
331 Connection state matching allows you to match packets based on their 347 Connection state matching allows you to match packets based on their
332 relationship to a tracked connection (ie. previous packets). This 348 relationship to a tracked connection (ie. previous packets). This
@@ -336,7 +352,8 @@ config IP_NF_MATCH_STATE
336 352
337config IP_NF_MATCH_CONNTRACK 353config IP_NF_MATCH_CONNTRACK
338 tristate "Connection tracking match support" 354 tristate "Connection tracking match support"
339 depends on IP_NF_CONNTRACK && IP_NF_IPTABLES 355 depends on IP_NF_IPTABLES
356 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
340 help 357 help
341 This is a general conntrack match module, a superset of the state match. 358 This is a general conntrack match module, a superset of the state match.
342 359
@@ -422,7 +439,8 @@ config IP_NF_MATCH_COMMENT
422 439
423config IP_NF_MATCH_CONNMARK 440config IP_NF_MATCH_CONNMARK
424 tristate 'Connection mark match support' 441 tristate 'Connection mark match support'
425 depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES 442 depends on IP_NF_IPTABLES
443 depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
426 help 444 help
427 This option adds a `connmark' match, which allows you to match the 445 This option adds a `connmark' match, which allows you to match the
428 connection mark value previously set for the session by `CONNMARK'. 446 connection mark value previously set for the session by `CONNMARK'.
@@ -433,7 +451,8 @@ config IP_NF_MATCH_CONNMARK
433 451
434config IP_NF_MATCH_CONNBYTES 452config IP_NF_MATCH_CONNBYTES
435 tristate 'Connection byte/packet counter match support' 453 tristate 'Connection byte/packet counter match support'
436 depends on IP_NF_CT_ACCT && IP_NF_IPTABLES 454 depends on IP_NF_IPTABLES
455 depends on IP_NF_CT_ACCT || (NF_CT_ACCT && NF_CONNTRACK_IPV4)
437 help 456 help
438 This option adds a `connbytes' match, which allows you to match the 457 This option adds a `connbytes' match, which allows you to match the
439 number of bytes and/or packets for each direction within a connection. 458 number of bytes and/or packets for each direction within a connection.
@@ -747,7 +766,8 @@ config IP_NF_TARGET_TTL
747 766
748config IP_NF_TARGET_CONNMARK 767config IP_NF_TARGET_CONNMARK
749 tristate 'CONNMARK target support' 768 tristate 'CONNMARK target support'
750 depends on IP_NF_CONNTRACK_MARK && IP_NF_MANGLE 769 depends on IP_NF_MANGLE
770 depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
751 help 771 help
752 This option adds a `CONNMARK' target, which allows one to manipulate 772 This option adds a `CONNMARK' target, which allows one to manipulate
753 the connection mark value. Similar to the MARK target, but 773 the connection mark value. Similar to the MARK target, but
@@ -759,7 +779,8 @@ config IP_NF_TARGET_CONNMARK
759 779
760config IP_NF_TARGET_CLUSTERIP 780config IP_NF_TARGET_CLUSTERIP
761 tristate "CLUSTERIP target support (EXPERIMENTAL)" 781 tristate "CLUSTERIP target support (EXPERIMENTAL)"
762 depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES && EXPERIMENTAL 782 depends on IP_NF_IPTABLES && EXPERIMENTAL
783 depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
763 help 784 help
764 The CLUSTERIP target allows you to build load-balancing clusters of 785 The CLUSTERIP target allows you to build load-balancing clusters of
765 network servers without having a dedicated load-balancing 786 network servers without having a dedicated load-balancing
@@ -782,7 +803,7 @@ config IP_NF_RAW
782config IP_NF_TARGET_NOTRACK 803config IP_NF_TARGET_NOTRACK
783 tristate 'NOTRACK target support' 804 tristate 'NOTRACK target support'
784 depends on IP_NF_RAW 805 depends on IP_NF_RAW
785 depends on IP_NF_CONNTRACK 806 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
786 help 807 help
787 The NOTRACK target allows a select rule to specify 808 The NOTRACK target allows a select rule to specify
788 which packets *not* to enter the conntrack/NAT 809 which packets *not* to enter the conntrack/NAT
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index dab4b58dd31e..058c48e258fc 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -103,3 +103,9 @@ obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
103obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o 103obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
104 104
105obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o 105obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
106
107# objects for l3 independent conntrack
108nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
109
110# l3 independent conntrack
111obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 82a65043a8ef..d2a4fec22862 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -28,11 +28,8 @@
28#include <linux/netlink.h> 28#include <linux/netlink.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/notifier.h> 30#include <linux/notifier.h>
31#include <linux/rtnetlink.h>
32 31
33#include <linux/netfilter.h> 32#include <linux/netfilter.h>
34#include <linux/netfilter_ipv4.h>
35#include <linux/netfilter_ipv4/ip_tables.h>
36#include <linux/netfilter_ipv4/ip_conntrack.h> 33#include <linux/netfilter_ipv4/ip_conntrack.h>
37#include <linux/netfilter_ipv4/ip_conntrack_core.h> 34#include <linux/netfilter_ipv4/ip_conntrack_core.h>
38#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 35#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -58,14 +55,17 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb,
58 const struct ip_conntrack_tuple *tuple) 55 const struct ip_conntrack_tuple *tuple)
59{ 56{
60 struct ip_conntrack_protocol *proto; 57 struct ip_conntrack_protocol *proto;
58 int ret = 0;
61 59
62 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 60 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
63 61
64 proto = ip_conntrack_proto_find_get(tuple->dst.protonum); 62 proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
65 if (proto && proto->tuple_to_nfattr) 63 if (likely(proto && proto->tuple_to_nfattr)) {
66 return proto->tuple_to_nfattr(skb, tuple); 64 ret = proto->tuple_to_nfattr(skb, tuple);
65 ip_conntrack_proto_put(proto);
66 }
67 67
68 return 0; 68 return ret;
69 69
70nfattr_failure: 70nfattr_failure:
71 return -1; 71 return -1;
@@ -175,7 +175,7 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
175{ 175{
176 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; 176 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
177 struct nfattr *nest_count = NFA_NEST(skb, type); 177 struct nfattr *nest_count = NFA_NEST(skb, type);
178 u_int64_t tmp; 178 u_int32_t tmp;
179 179
180 tmp = htonl(ct->counters[dir].packets); 180 tmp = htonl(ct->counters[dir].packets);
181 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); 181 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
@@ -479,9 +479,7 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
479 479
480 DEBUGP("entered %s\n", __FUNCTION__); 480 DEBUGP("entered %s\n", __FUNCTION__);
481 481
482 482 nfattr_parse_nested(tb, CTA_IP_MAX, attr);
483 if (nfattr_parse_nested(tb, CTA_IP_MAX, attr) < 0)
484 goto nfattr_failure;
485 483
486 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) 484 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
487 return -EINVAL; 485 return -EINVAL;
@@ -497,9 +495,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
497 DEBUGP("leaving\n"); 495 DEBUGP("leaving\n");
498 496
499 return 0; 497 return 0;
500
501nfattr_failure:
502 return -1;
503} 498}
504 499
505static const int cta_min_proto[CTA_PROTO_MAX] = { 500static const int cta_min_proto[CTA_PROTO_MAX] = {
@@ -521,8 +516,7 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
521 516
522 DEBUGP("entered %s\n", __FUNCTION__); 517 DEBUGP("entered %s\n", __FUNCTION__);
523 518
524 if (nfattr_parse_nested(tb, CTA_PROTO_MAX, attr) < 0) 519 nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
525 goto nfattr_failure;
526 520
527 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) 521 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
528 return -EINVAL; 522 return -EINVAL;
@@ -539,9 +533,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
539 } 533 }
540 534
541 return ret; 535 return ret;
542
543nfattr_failure:
544 return -1;
545} 536}
546 537
547static inline int 538static inline int
@@ -555,8 +546,7 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
555 546
556 memset(tuple, 0, sizeof(*tuple)); 547 memset(tuple, 0, sizeof(*tuple));
557 548
558 if (nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]) < 0) 549 nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
559 goto nfattr_failure;
560 550
561 if (!tb[CTA_TUPLE_IP-1]) 551 if (!tb[CTA_TUPLE_IP-1])
562 return -EINVAL; 552 return -EINVAL;
@@ -583,9 +573,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
583 DEBUGP("leaving\n"); 573 DEBUGP("leaving\n");
584 574
585 return 0; 575 return 0;
586
587nfattr_failure:
588 return -1;
589} 576}
590 577
591#ifdef CONFIG_IP_NF_NAT_NEEDED 578#ifdef CONFIG_IP_NF_NAT_NEEDED
@@ -603,11 +590,10 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
603 590
604 DEBUGP("entered %s\n", __FUNCTION__); 591 DEBUGP("entered %s\n", __FUNCTION__);
605 592
606 if (nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr) < 0) 593 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
607 goto nfattr_failure;
608 594
609 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) 595 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
610 goto nfattr_failure; 596 return -EINVAL;
611 597
612 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 598 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
613 if (!npt) 599 if (!npt)
@@ -626,9 +612,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
626 612
627 DEBUGP("leaving\n"); 613 DEBUGP("leaving\n");
628 return 0; 614 return 0;
629
630nfattr_failure:
631 return -1;
632} 615}
633 616
634static inline int 617static inline int
@@ -642,8 +625,7 @@ ctnetlink_parse_nat(struct nfattr *cda[],
642 625
643 memset(range, 0, sizeof(*range)); 626 memset(range, 0, sizeof(*range));
644 627
645 if (nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]) < 0) 628 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
646 goto nfattr_failure;
647 629
648 if (tb[CTA_NAT_MINIP-1]) 630 if (tb[CTA_NAT_MINIP-1])
649 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]); 631 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
@@ -665,9 +647,6 @@ ctnetlink_parse_nat(struct nfattr *cda[],
665 647
666 DEBUGP("leaving\n"); 648 DEBUGP("leaving\n");
667 return 0; 649 return 0;
668
669nfattr_failure:
670 return -1;
671} 650}
672#endif 651#endif
673 652
@@ -678,8 +657,7 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
678 657
679 DEBUGP("entered %s\n", __FUNCTION__); 658 DEBUGP("entered %s\n", __FUNCTION__);
680 659
681 if (nfattr_parse_nested(tb, CTA_HELP_MAX, attr) < 0) 660 nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
682 goto nfattr_failure;
683 661
684 if (!tb[CTA_HELP_NAME-1]) 662 if (!tb[CTA_HELP_NAME-1])
685 return -EINVAL; 663 return -EINVAL;
@@ -687,9 +665,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
687 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]); 665 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
688 666
689 return 0; 667 return 0;
690
691nfattr_failure:
692 return -1;
693} 668}
694 669
695static int 670static int
@@ -804,7 +779,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
804 ct = tuplehash_to_ctrack(h); 779 ct = tuplehash_to_ctrack(h);
805 780
806 err = -ENOMEM; 781 err = -ENOMEM;
807 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 782 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
808 if (!skb2) { 783 if (!skb2) {
809 ip_conntrack_put(ct); 784 ip_conntrack_put(ct);
810 return -ENOMEM; 785 return -ENOMEM;
@@ -827,7 +802,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
827free: 802free:
828 kfree_skb(skb2); 803 kfree_skb(skb2);
829out: 804out:
830 return -1; 805 return err;
831} 806}
832 807
833static inline int 808static inline int
@@ -957,8 +932,7 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
957 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; 932 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
958 int err = 0; 933 int err = 0;
959 934
960 if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0) 935 nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
961 goto nfattr_failure;
962 936
963 proto = ip_conntrack_proto_find_get(npt); 937 proto = ip_conntrack_proto_find_get(npt);
964 if (!proto) 938 if (!proto)
@@ -969,9 +943,6 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
969 ip_conntrack_proto_put(proto); 943 ip_conntrack_proto_put(proto);
970 944
971 return err; 945 return err;
972
973nfattr_failure:
974 return -ENOMEM;
975} 946}
976 947
977static int 948static int
@@ -1005,6 +976,11 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
1005 return err; 976 return err;
1006 } 977 }
1007 978
979#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
980 if (cda[CTA_MARK-1])
981 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
982#endif
983
1008 DEBUGP("all done\n"); 984 DEBUGP("all done\n");
1009 return 0; 985 return 0;
1010} 986}
@@ -1048,6 +1024,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
1048 if (ct->helper) 1024 if (ct->helper)
1049 ip_conntrack_helper_put(ct->helper); 1025 ip_conntrack_helper_put(ct->helper);
1050 1026
1027#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1028 if (cda[CTA_MARK-1])
1029 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
1030#endif
1031
1051 DEBUGP("conntrack with id %u inserted\n", ct->id); 1032 DEBUGP("conntrack with id %u inserted\n", ct->id);
1052 return 0; 1033 return 0;
1053 1034
@@ -1312,6 +1293,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1312 if (!exp) 1293 if (!exp)
1313 return -ENOENT; 1294 return -ENOENT;
1314 1295
1296 if (cda[CTA_EXPECT_ID-1]) {
1297 u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1298 if (exp->id != ntohl(id)) {
1299 ip_conntrack_expect_put(exp);
1300 return -ENOENT;
1301 }
1302 }
1303
1315 err = -ENOMEM; 1304 err = -ENOMEM;
1316 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1305 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1317 if (!skb2) 1306 if (!skb2)
@@ -1387,7 +1376,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1387 ip_conntrack_expect_put(exp); 1376 ip_conntrack_expect_put(exp);
1388 } 1377 }
1389 } 1378 }
1390 write_unlock(&ip_conntrack_lock); 1379 write_unlock_bh(&ip_conntrack_lock);
1391 } else { 1380 } else {
1392 /* This basically means we have to flush everything*/ 1381 /* This basically means we have to flush everything*/
1393 write_lock_bh(&ip_conntrack_lock); 1382 write_lock_bh(&ip_conntrack_lock);
@@ -1554,6 +1543,8 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1554 .cb = ctnl_exp_cb, 1543 .cb = ctnl_exp_cb,
1555}; 1544};
1556 1545
1546MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1547
1557static int __init ctnetlink_init(void) 1548static int __init ctnetlink_init(void)
1558{ 1549{
1559 int ret; 1550 int ret;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 98f0015dd255..e4d6b268e8c4 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -13,6 +13,7 @@
13#include <linux/in.h> 13#include <linux/in.h>
14#include <linux/icmp.h> 14#include <linux/icmp.h>
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16#include <linux/skbuff.h>
16#include <net/ip.h> 17#include <net/ip.h>
17#include <net/checksum.h> 18#include <net/checksum.h>
18#include <linux/netfilter.h> 19#include <linux/netfilter.h>
@@ -151,13 +152,13 @@ icmp_error_message(struct sk_buff *skb,
151 /* Not enough header? */ 152 /* Not enough header? */
152 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in); 153 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
153 if (inside == NULL) 154 if (inside == NULL)
154 return NF_ACCEPT; 155 return -NF_ACCEPT;
155 156
156 /* Ignore ICMP's containing fragments (shouldn't happen) */ 157 /* Ignore ICMP's containing fragments (shouldn't happen) */
157 if (inside->ip.frag_off & htons(IP_OFFSET)) { 158 if (inside->ip.frag_off & htons(IP_OFFSET)) {
158 DEBUGP("icmp_error_track: fragment of proto %u\n", 159 DEBUGP("icmp_error_track: fragment of proto %u\n",
159 inside->ip.protocol); 160 inside->ip.protocol);
160 return NF_ACCEPT; 161 return -NF_ACCEPT;
161 } 162 }
162 163
163 innerproto = ip_conntrack_proto_find_get(inside->ip.protocol); 164 innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
@@ -166,7 +167,7 @@ icmp_error_message(struct sk_buff *skb,
166 if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) { 167 if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
167 DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol); 168 DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
168 ip_conntrack_proto_put(innerproto); 169 ip_conntrack_proto_put(innerproto);
169 return NF_ACCEPT; 170 return -NF_ACCEPT;
170 } 171 }
171 172
172 /* Ordinarily, we'd expect the inverted tupleproto, but it's 173 /* Ordinarily, we'd expect the inverted tupleproto, but it's
@@ -174,7 +175,7 @@ icmp_error_message(struct sk_buff *skb,
174 if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) { 175 if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
175 DEBUGP("icmp_error_track: Can't invert tuple\n"); 176 DEBUGP("icmp_error_track: Can't invert tuple\n");
176 ip_conntrack_proto_put(innerproto); 177 ip_conntrack_proto_put(innerproto);
177 return NF_ACCEPT; 178 return -NF_ACCEPT;
178 } 179 }
179 ip_conntrack_proto_put(innerproto); 180 ip_conntrack_proto_put(innerproto);
180 181
@@ -190,7 +191,7 @@ icmp_error_message(struct sk_buff *skb,
190 191
191 if (!h) { 192 if (!h) {
192 DEBUGP("icmp_error_track: no match\n"); 193 DEBUGP("icmp_error_track: no match\n");
193 return NF_ACCEPT; 194 return -NF_ACCEPT;
194 } 195 }
195 /* Reverse direction from that found */ 196 /* Reverse direction from that found */
196 if (DIRECTION(h) != IP_CT_DIR_REPLY) 197 if (DIRECTION(h) != IP_CT_DIR_REPLY)
@@ -230,19 +231,15 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
230 case CHECKSUM_HW: 231 case CHECKSUM_HW:
231 if (!(u16)csum_fold(skb->csum)) 232 if (!(u16)csum_fold(skb->csum))
232 break; 233 break;
233 if (LOG_INVALID(IPPROTO_ICMP)) 234 /* fall through */
234 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
235 "ip_ct_icmp: bad HW ICMP checksum ");
236 return -NF_ACCEPT;
237 case CHECKSUM_NONE: 235 case CHECKSUM_NONE:
238 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { 236 skb->csum = 0;
237 if (__skb_checksum_complete(skb)) {
239 if (LOG_INVALID(IPPROTO_ICMP)) 238 if (LOG_INVALID(IPPROTO_ICMP))
240 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 239 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
241 "ip_ct_icmp: bad ICMP checksum "); 240 "ip_ct_icmp: bad ICMP checksum ");
242 return -NF_ACCEPT; 241 return -NF_ACCEPT;
243 } 242 }
244 default:
245 break;
246 } 243 }
247 244
248checksum_skipped: 245checksum_skipped:
@@ -296,7 +293,8 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
296 struct ip_conntrack_tuple *tuple) 293 struct ip_conntrack_tuple *tuple)
297{ 294{
298 if (!tb[CTA_PROTO_ICMP_TYPE-1] 295 if (!tb[CTA_PROTO_ICMP_TYPE-1]
299 || !tb[CTA_PROTO_ICMP_CODE-1]) 296 || !tb[CTA_PROTO_ICMP_CODE-1]
297 || !tb[CTA_PROTO_ICMP_ID-1])
300 return -1; 298 return -1;
301 299
302 tuple->dst.u.icmp.type = 300 tuple->dst.u.icmp.type =
@@ -304,7 +302,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
304 tuple->dst.u.icmp.code = 302 tuple->dst.u.icmp.code =
305 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]); 303 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
306 tuple->src.u.icmp.id = 304 tuple->src.u.icmp.id =
307 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); 305 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
308 306
309 return 0; 307 return 0;
310} 308}
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index d6701cafbcc2..468c6003b4c7 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -362,8 +362,12 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1]; 362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
363 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX]; 363 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
364 364
365 if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0) 365 /* updates could not contain anything about the private
366 goto nfattr_failure; 366 * protocol info, in that case skip the parsing */
367 if (!attr)
368 return 0;
369
370 nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
367 371
368 if (!tb[CTA_PROTOINFO_TCP_STATE-1]) 372 if (!tb[CTA_PROTOINFO_TCP_STATE-1])
369 return -EINVAL; 373 return -EINVAL;
@@ -374,9 +378,6 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
374 write_unlock_bh(&tcp_lock); 378 write_unlock_bh(&tcp_lock);
375 379
376 return 0; 380 return 0;
377
378nfattr_failure:
379 return -1;
380} 381}
381#endif 382#endif
382 383
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index ee6ab74ad3a9..e546203f5662 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
73 struct ip_conntrack_tuple t; 73 struct ip_conntrack_tuple t;
74 struct ip_ct_pptp_master *ct_pptp_info; 74 struct ip_ct_pptp_master *ct_pptp_info;
75 struct ip_nat_pptp *nat_pptp_info; 75 struct ip_nat_pptp *nat_pptp_info;
76 struct ip_nat_range range;
76 77
77 ct_pptp_info = &master->help.ct_pptp_info; 78 ct_pptp_info = &master->help.ct_pptp_info;
78 nat_pptp_info = &master->nat.help.nat_pptp_info; 79 nat_pptp_info = &master->nat.help.nat_pptp_info;
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
110 DEBUGP("not found!\n"); 111 DEBUGP("not found!\n");
111 } 112 }
112 113
113 ip_nat_follow_master(ct, exp); 114 /* This must be a fresh one. */
115 BUG_ON(ct->status & IPS_NAT_DONE_MASK);
116
117 /* Change src to where master sends to */
118 range.flags = IP_NAT_RANGE_MAP_IPS;
119 range.min_ip = range.max_ip
120 = ct->master->tuplehash[!exp->dir].tuple.dst.ip;
121 if (exp->dir == IP_CT_DIR_ORIGINAL) {
122 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
123 range.min = range.max = exp->saved_proto;
124 }
125 /* hook doesn't matter, but it has to do source manip */
126 ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
127
128 /* For DST manip, map port here to where it's expected. */
129 range.flags = IP_NAT_RANGE_MAP_IPS;
130 range.min_ip = range.max_ip
131 = ct->master->tuplehash[!exp->dir].tuple.src.ip;
132 if (exp->dir == IP_CT_DIR_REPLY) {
133 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
134 range.min = range.max = exp->saved_proto;
135 }
136 /* hook doesn't matter, but it has to do destination manip */
137 ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
114} 138}
115 139
116/* outbound packets == from PNS to PAC */ 140/* outbound packets == from PNS to PAC */
@@ -213,7 +237,7 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
213 237
214 /* alter expectation for PNS->PAC direction */ 238 /* alter expectation for PNS->PAC direction */
215 invert_tuplepr(&inv_t, &expect_orig->tuple); 239 invert_tuplepr(&inv_t, &expect_orig->tuple);
216 expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id); 240 expect_orig->saved_proto.gre.key = htons(ct_pptp_info->pns_call_id);
217 expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id); 241 expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
218 expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id); 242 expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
219 expect_orig->dir = IP_CT_DIR_ORIGINAL; 243 expect_orig->dir = IP_CT_DIR_ORIGINAL;
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 9bcb398fbc1f..45c52d8f4d99 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -29,7 +29,7 @@
29 29
30#include <linux/netfilter_ipv4/ip_tables.h> 30#include <linux/netfilter_ipv4/ip_tables.h>
31#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h> 31#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
32#include <linux/netfilter_ipv4/ip_conntrack.h> 32#include <net/netfilter/nf_conntrack_compat.h>
33 33
34#define CLUSTERIP_VERSION "0.8" 34#define CLUSTERIP_VERSION "0.8"
35 35
@@ -316,14 +316,14 @@ target(struct sk_buff **pskb,
316{ 316{
317 const struct ipt_clusterip_tgt_info *cipinfo = targinfo; 317 const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
318 enum ip_conntrack_info ctinfo; 318 enum ip_conntrack_info ctinfo;
319 struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo); 319 u_int32_t *mark, hash;
320 u_int32_t hash;
321 320
322 /* don't need to clusterip_config_get() here, since refcount 321 /* don't need to clusterip_config_get() here, since refcount
323 * is only decremented by destroy() - and ip_tables guarantees 322 * is only decremented by destroy() - and ip_tables guarantees
324 * that the ->target() function isn't called after ->destroy() */ 323 * that the ->target() function isn't called after ->destroy() */
325 324
326 if (!ct) { 325 mark = nf_ct_get_mark((*pskb), &ctinfo);
326 if (mark == NULL) {
327 printk(KERN_ERR "CLUSTERIP: no conntrack!\n"); 327 printk(KERN_ERR "CLUSTERIP: no conntrack!\n");
328 /* FIXME: need to drop invalid ones, since replies 328 /* FIXME: need to drop invalid ones, since replies
329 * to outgoing connections of other nodes will be 329 * to outgoing connections of other nodes will be
@@ -346,7 +346,7 @@ target(struct sk_buff **pskb,
346 346
347 switch (ctinfo) { 347 switch (ctinfo) {
348 case IP_CT_NEW: 348 case IP_CT_NEW:
349 ct->mark = hash; 349 *mark = hash;
350 break; 350 break;
351 case IP_CT_RELATED: 351 case IP_CT_RELATED:
352 case IP_CT_RELATED+IP_CT_IS_REPLY: 352 case IP_CT_RELATED+IP_CT_IS_REPLY:
@@ -363,7 +363,7 @@ target(struct sk_buff **pskb,
363#ifdef DEBUG_CLUSTERP 363#ifdef DEBUG_CLUSTERP
364 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 364 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
365#endif 365#endif
366 DEBUGP("hash=%u ct_hash=%u ", hash, ct->mark); 366 DEBUGP("hash=%u ct_hash=%u ", hash, *mark);
367 if (!clusterip_responsible(cipinfo->config, hash)) { 367 if (!clusterip_responsible(cipinfo->config, hash)) {
368 DEBUGP("not responsible\n"); 368 DEBUGP("not responsible\n");
369 return NF_DROP; 369 return NF_DROP;
diff --git a/net/ipv4/netfilter/ipt_CONNMARK.c b/net/ipv4/netfilter/ipt_CONNMARK.c
index 05d66ab59424..8acac5a40a92 100644
--- a/net/ipv4/netfilter/ipt_CONNMARK.c
+++ b/net/ipv4/netfilter/ipt_CONNMARK.c
@@ -29,7 +29,7 @@ MODULE_LICENSE("GPL");
29 29
30#include <linux/netfilter_ipv4/ip_tables.h> 30#include <linux/netfilter_ipv4/ip_tables.h>
31#include <linux/netfilter_ipv4/ipt_CONNMARK.h> 31#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
32#include <linux/netfilter_ipv4/ip_conntrack.h> 32#include <net/netfilter/nf_conntrack_compat.h>
33 33
34static unsigned int 34static unsigned int
35target(struct sk_buff **pskb, 35target(struct sk_buff **pskb,
@@ -43,24 +43,24 @@ target(struct sk_buff **pskb,
43 u_int32_t diff; 43 u_int32_t diff;
44 u_int32_t nfmark; 44 u_int32_t nfmark;
45 u_int32_t newmark; 45 u_int32_t newmark;
46 u_int32_t ctinfo;
47 u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo);
46 48
47 enum ip_conntrack_info ctinfo; 49 if (ctmark) {
48 struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
49 if (ct) {
50 switch(markinfo->mode) { 50 switch(markinfo->mode) {
51 case IPT_CONNMARK_SET: 51 case IPT_CONNMARK_SET:
52 newmark = (ct->mark & ~markinfo->mask) | markinfo->mark; 52 newmark = (*ctmark & ~markinfo->mask) | markinfo->mark;
53 if (newmark != ct->mark) 53 if (newmark != *ctmark)
54 ct->mark = newmark; 54 *ctmark = newmark;
55 break; 55 break;
56 case IPT_CONNMARK_SAVE: 56 case IPT_CONNMARK_SAVE:
57 newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); 57 newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
58 if (ct->mark != newmark) 58 if (*ctmark != newmark)
59 ct->mark = newmark; 59 *ctmark = newmark;
60 break; 60 break;
61 case IPT_CONNMARK_RESTORE: 61 case IPT_CONNMARK_RESTORE:
62 nfmark = (*pskb)->nfmark; 62 nfmark = (*pskb)->nfmark;
63 diff = (ct->mark ^ nfmark) & markinfo->mask; 63 diff = (*ctmark ^ nfmark) & markinfo->mask;
64 if (diff != 0) 64 if (diff != 0)
65 (*pskb)->nfmark = nfmark ^ diff; 65 (*pskb)->nfmark = nfmark ^ diff;
66 break; 66 break;
diff --git a/net/ipv4/netfilter/ipt_NOTRACK.c b/net/ipv4/netfilter/ipt_NOTRACK.c
index a4bb9b3bc292..e3c69d072c6e 100644
--- a/net/ipv4/netfilter/ipt_NOTRACK.c
+++ b/net/ipv4/netfilter/ipt_NOTRACK.c
@@ -5,7 +5,7 @@
5#include <linux/skbuff.h> 5#include <linux/skbuff.h>
6 6
7#include <linux/netfilter_ipv4/ip_tables.h> 7#include <linux/netfilter_ipv4/ip_tables.h>
8#include <linux/netfilter_ipv4/ip_conntrack.h> 8#include <net/netfilter/nf_conntrack_compat.h>
9 9
10static unsigned int 10static unsigned int
11target(struct sk_buff **pskb, 11target(struct sk_buff **pskb,
@@ -23,7 +23,7 @@ target(struct sk_buff **pskb,
23 If there is a real ct entry correspondig to this packet, 23 If there is a real ct entry correspondig to this packet,
24 it'll hang aroun till timing out. We don't deal with it 24 it'll hang aroun till timing out. We don't deal with it
25 for performance reasons. JK */ 25 for performance reasons. JK */
26 (*pskb)->nfct = &ip_conntrack_untracked.ct_general; 26 nf_ct_untrack(*pskb);
27 (*pskb)->nfctinfo = IP_CT_NEW; 27 (*pskb)->nfctinfo = IP_CT_NEW;
28 nf_conntrack_get((*pskb)->nfct); 28 nf_conntrack_get((*pskb)->nfct);
29 29
diff --git a/net/ipv4/netfilter/ipt_connbytes.c b/net/ipv4/netfilter/ipt_connbytes.c
index df4a42c6da22..d68a048b7176 100644
--- a/net/ipv4/netfilter/ipt_connbytes.c
+++ b/net/ipv4/netfilter/ipt_connbytes.c
@@ -10,7 +10,7 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/netfilter_ipv4/ip_conntrack.h> 13#include <net/netfilter/nf_conntrack_compat.h>
14#include <linux/netfilter_ipv4/ip_tables.h> 14#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_connbytes.h> 15#include <linux/netfilter_ipv4/ipt_connbytes.h>
16 16
@@ -46,60 +46,59 @@ match(const struct sk_buff *skb,
46 int *hotdrop) 46 int *hotdrop)
47{ 47{
48 const struct ipt_connbytes_info *sinfo = matchinfo; 48 const struct ipt_connbytes_info *sinfo = matchinfo;
49 enum ip_conntrack_info ctinfo;
50 struct ip_conntrack *ct;
51 u_int64_t what = 0; /* initialize to make gcc happy */ 49 u_int64_t what = 0; /* initialize to make gcc happy */
50 const struct ip_conntrack_counter *counters;
52 51
53 if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo))) 52 if (!(counters = nf_ct_get_counters(skb)))
54 return 0; /* no match */ 53 return 0; /* no match */
55 54
56 switch (sinfo->what) { 55 switch (sinfo->what) {
57 case IPT_CONNBYTES_PKTS: 56 case IPT_CONNBYTES_PKTS:
58 switch (sinfo->direction) { 57 switch (sinfo->direction) {
59 case IPT_CONNBYTES_DIR_ORIGINAL: 58 case IPT_CONNBYTES_DIR_ORIGINAL:
60 what = ct->counters[IP_CT_DIR_ORIGINAL].packets; 59 what = counters[IP_CT_DIR_ORIGINAL].packets;
61 break; 60 break;
62 case IPT_CONNBYTES_DIR_REPLY: 61 case IPT_CONNBYTES_DIR_REPLY:
63 what = ct->counters[IP_CT_DIR_REPLY].packets; 62 what = counters[IP_CT_DIR_REPLY].packets;
64 break; 63 break;
65 case IPT_CONNBYTES_DIR_BOTH: 64 case IPT_CONNBYTES_DIR_BOTH:
66 what = ct->counters[IP_CT_DIR_ORIGINAL].packets; 65 what = counters[IP_CT_DIR_ORIGINAL].packets;
67 what += ct->counters[IP_CT_DIR_REPLY].packets; 66 what += counters[IP_CT_DIR_REPLY].packets;
68 break; 67 break;
69 } 68 }
70 break; 69 break;
71 case IPT_CONNBYTES_BYTES: 70 case IPT_CONNBYTES_BYTES:
72 switch (sinfo->direction) { 71 switch (sinfo->direction) {
73 case IPT_CONNBYTES_DIR_ORIGINAL: 72 case IPT_CONNBYTES_DIR_ORIGINAL:
74 what = ct->counters[IP_CT_DIR_ORIGINAL].bytes; 73 what = counters[IP_CT_DIR_ORIGINAL].bytes;
75 break; 74 break;
76 case IPT_CONNBYTES_DIR_REPLY: 75 case IPT_CONNBYTES_DIR_REPLY:
77 what = ct->counters[IP_CT_DIR_REPLY].bytes; 76 what = counters[IP_CT_DIR_REPLY].bytes;
78 break; 77 break;
79 case IPT_CONNBYTES_DIR_BOTH: 78 case IPT_CONNBYTES_DIR_BOTH:
80 what = ct->counters[IP_CT_DIR_ORIGINAL].bytes; 79 what = counters[IP_CT_DIR_ORIGINAL].bytes;
81 what += ct->counters[IP_CT_DIR_REPLY].bytes; 80 what += counters[IP_CT_DIR_REPLY].bytes;
82 break; 81 break;
83 } 82 }
84 break; 83 break;
85 case IPT_CONNBYTES_AVGPKT: 84 case IPT_CONNBYTES_AVGPKT:
86 switch (sinfo->direction) { 85 switch (sinfo->direction) {
87 case IPT_CONNBYTES_DIR_ORIGINAL: 86 case IPT_CONNBYTES_DIR_ORIGINAL:
88 what = div64_64(ct->counters[IP_CT_DIR_ORIGINAL].bytes, 87 what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes,
89 ct->counters[IP_CT_DIR_ORIGINAL].packets); 88 counters[IP_CT_DIR_ORIGINAL].packets);
90 break; 89 break;
91 case IPT_CONNBYTES_DIR_REPLY: 90 case IPT_CONNBYTES_DIR_REPLY:
92 what = div64_64(ct->counters[IP_CT_DIR_REPLY].bytes, 91 what = div64_64(counters[IP_CT_DIR_REPLY].bytes,
93 ct->counters[IP_CT_DIR_REPLY].packets); 92 counters[IP_CT_DIR_REPLY].packets);
94 break; 93 break;
95 case IPT_CONNBYTES_DIR_BOTH: 94 case IPT_CONNBYTES_DIR_BOTH:
96 { 95 {
97 u_int64_t bytes; 96 u_int64_t bytes;
98 u_int64_t pkts; 97 u_int64_t pkts;
99 bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes + 98 bytes = counters[IP_CT_DIR_ORIGINAL].bytes +
100 ct->counters[IP_CT_DIR_REPLY].bytes; 99 counters[IP_CT_DIR_REPLY].bytes;
101 pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets+ 100 pkts = counters[IP_CT_DIR_ORIGINAL].packets+
102 ct->counters[IP_CT_DIR_REPLY].packets; 101 counters[IP_CT_DIR_REPLY].packets;
103 102
104 /* FIXME_THEORETICAL: what to do if sum 103 /* FIXME_THEORETICAL: what to do if sum
105 * overflows ? */ 104 * overflows ? */
diff --git a/net/ipv4/netfilter/ipt_connmark.c b/net/ipv4/netfilter/ipt_connmark.c
index bf8de47ce004..5306ef293b92 100644
--- a/net/ipv4/netfilter/ipt_connmark.c
+++ b/net/ipv4/netfilter/ipt_connmark.c
@@ -28,7 +28,7 @@ MODULE_LICENSE("GPL");
28 28
29#include <linux/netfilter_ipv4/ip_tables.h> 29#include <linux/netfilter_ipv4/ip_tables.h>
30#include <linux/netfilter_ipv4/ipt_connmark.h> 30#include <linux/netfilter_ipv4/ipt_connmark.h>
31#include <linux/netfilter_ipv4/ip_conntrack.h> 31#include <net/netfilter/nf_conntrack_compat.h>
32 32
33static int 33static int
34match(const struct sk_buff *skb, 34match(const struct sk_buff *skb,
@@ -39,12 +39,12 @@ match(const struct sk_buff *skb,
39 int *hotdrop) 39 int *hotdrop)
40{ 40{
41 const struct ipt_connmark_info *info = matchinfo; 41 const struct ipt_connmark_info *info = matchinfo;
42 enum ip_conntrack_info ctinfo; 42 u_int32_t ctinfo;
43 struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 43 const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo);
44 if (!ct) 44 if (!ctmark)
45 return 0; 45 return 0;
46 46
47 return ((ct->mark & info->mask) == info->mark) ^ info->invert; 47 return (((*ctmark) & info->mask) == info->mark) ^ info->invert;
48} 48}
49 49
50static int 50static int
diff --git a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c
index c1d22801b7cf..c8d18705469b 100644
--- a/net/ipv4/netfilter/ipt_conntrack.c
+++ b/net/ipv4/netfilter/ipt_conntrack.c
@@ -10,7 +10,14 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13
14#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
13#include <linux/netfilter_ipv4/ip_conntrack.h> 15#include <linux/netfilter_ipv4/ip_conntrack.h>
16#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
17#else
18#include <net/netfilter/nf_conntrack.h>
19#endif
20
14#include <linux/netfilter_ipv4/ip_tables.h> 21#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_conntrack.h> 22#include <linux/netfilter_ipv4/ipt_conntrack.h>
16 23
@@ -18,6 +25,8 @@ MODULE_LICENSE("GPL");
18MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 25MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
19MODULE_DESCRIPTION("iptables connection tracking match module"); 26MODULE_DESCRIPTION("iptables connection tracking match module");
20 27
28#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
29
21static int 30static int
22match(const struct sk_buff *skb, 31match(const struct sk_buff *skb,
23 const struct net_device *in, 32 const struct net_device *in,
@@ -102,6 +111,93 @@ match(const struct sk_buff *skb,
102 return 1; 111 return 1;
103} 112}
104 113
114#else /* CONFIG_IP_NF_CONNTRACK */
115static int
116match(const struct sk_buff *skb,
117 const struct net_device *in,
118 const struct net_device *out,
119 const void *matchinfo,
120 int offset,
121 int *hotdrop)
122{
123 const struct ipt_conntrack_info *sinfo = matchinfo;
124 struct nf_conn *ct;
125 enum ip_conntrack_info ctinfo;
126 unsigned int statebit;
127
128 ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
129
130#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
131
132 if (ct == &nf_conntrack_untracked)
133 statebit = IPT_CONNTRACK_STATE_UNTRACKED;
134 else if (ct)
135 statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
136 else
137 statebit = IPT_CONNTRACK_STATE_INVALID;
138
139 if(sinfo->flags & IPT_CONNTRACK_STATE) {
140 if (ct) {
141 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip !=
142 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip)
143 statebit |= IPT_CONNTRACK_STATE_SNAT;
144
145 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip !=
146 ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip)
147 statebit |= IPT_CONNTRACK_STATE_DNAT;
148 }
149
150 if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE))
151 return 0;
152 }
153
154 if(sinfo->flags & IPT_CONNTRACK_PROTO) {
155 if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO))
156 return 0;
157 }
158
159 if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
160 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC))
161 return 0;
162 }
163
164 if(sinfo->flags & IPT_CONNTRACK_ORIGDST) {
165 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST))
166 return 0;
167 }
168
169 if(sinfo->flags & IPT_CONNTRACK_REPLSRC) {
170 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC))
171 return 0;
172 }
173
174 if(sinfo->flags & IPT_CONNTRACK_REPLDST) {
175 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST))
176 return 0;
177 }
178
179 if(sinfo->flags & IPT_CONNTRACK_STATUS) {
180 if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS))
181 return 0;
182 }
183
184 if(sinfo->flags & IPT_CONNTRACK_EXPIRES) {
185 unsigned long expires;
186
187 if(!ct)
188 return 0;
189
190 expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0;
191
192 if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES))
193 return 0;
194 }
195
196 return 1;
197}
198
199#endif /* CONFIG_NF_IP_CONNTRACK */
200
105static int check(const char *tablename, 201static int check(const char *tablename,
106 const struct ipt_ip *ip, 202 const struct ipt_ip *ip,
107 void *matchinfo, 203 void *matchinfo,
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
index 3e7dd014de43..bf14e1c7798a 100644
--- a/net/ipv4/netfilter/ipt_helper.c
+++ b/net/ipv4/netfilter/ipt_helper.c
@@ -13,9 +13,15 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/netfilter.h> 15#include <linux/netfilter.h>
16#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
16#include <linux/netfilter_ipv4/ip_conntrack.h> 17#include <linux/netfilter_ipv4/ip_conntrack.h>
17#include <linux/netfilter_ipv4/ip_conntrack_core.h> 18#include <linux/netfilter_ipv4/ip_conntrack_core.h>
18#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 19#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
20#else
21#include <net/netfilter/nf_conntrack.h>
22#include <net/netfilter/nf_conntrack_core.h>
23#include <net/netfilter/nf_conntrack_helper.h>
24#endif
19#include <linux/netfilter_ipv4/ip_tables.h> 25#include <linux/netfilter_ipv4/ip_tables.h>
20#include <linux/netfilter_ipv4/ipt_helper.h> 26#include <linux/netfilter_ipv4/ipt_helper.h>
21 27
@@ -29,6 +35,7 @@ MODULE_DESCRIPTION("iptables helper match module");
29#define DEBUGP(format, args...) 35#define DEBUGP(format, args...)
30#endif 36#endif
31 37
38#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
32static int 39static int
33match(const struct sk_buff *skb, 40match(const struct sk_buff *skb,
34 const struct net_device *in, 41 const struct net_device *in,
@@ -73,6 +80,53 @@ out_unlock:
73 return ret; 80 return ret;
74} 81}
75 82
83#else /* CONFIG_IP_NF_CONNTRACK */
84
85static int
86match(const struct sk_buff *skb,
87 const struct net_device *in,
88 const struct net_device *out,
89 const void *matchinfo,
90 int offset,
91 int *hotdrop)
92{
93 const struct ipt_helper_info *info = matchinfo;
94 struct nf_conn *ct;
95 enum ip_conntrack_info ctinfo;
96 int ret = info->invert;
97
98 ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
99 if (!ct) {
100 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
101 return ret;
102 }
103
104 if (!ct->master) {
105 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
106 return ret;
107 }
108
109 read_lock_bh(&nf_conntrack_lock);
110 if (!ct->master->helper) {
111 DEBUGP("ipt_helper: master ct %p has no helper\n",
112 exp->expectant);
113 goto out_unlock;
114 }
115
116 DEBUGP("master's name = %s , info->name = %s\n",
117 ct->master->helper->name, info->name);
118
119 if (info->name[0] == '\0')
120 ret ^= 1;
121 else
122 ret ^= !strncmp(ct->master->helper->name, info->name,
123 strlen(ct->master->helper->name));
124out_unlock:
125 read_unlock_bh(&nf_conntrack_lock);
126 return ret;
127}
128#endif
129
76static int check(const char *tablename, 130static int check(const char *tablename,
77 const struct ipt_ip *ip, 131 const struct ipt_ip *ip,
78 void *matchinfo, 132 void *matchinfo,
diff --git a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c
index b1511b97ea5f..4d7f16b70cec 100644
--- a/net/ipv4/netfilter/ipt_state.c
+++ b/net/ipv4/netfilter/ipt_state.c
@@ -10,7 +10,7 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/netfilter_ipv4/ip_conntrack.h> 13#include <net/netfilter/nf_conntrack_compat.h>
14#include <linux/netfilter_ipv4/ip_tables.h> 14#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_state.h> 15#include <linux/netfilter_ipv4/ipt_state.h>
16 16
@@ -30,9 +30,9 @@ match(const struct sk_buff *skb,
30 enum ip_conntrack_info ctinfo; 30 enum ip_conntrack_info ctinfo;
31 unsigned int statebit; 31 unsigned int statebit;
32 32
33 if (skb->nfct == &ip_conntrack_untracked.ct_general) 33 if (nf_ct_is_untracked(skb))
34 statebit = IPT_STATE_UNTRACKED; 34 statebit = IPT_STATE_UNTRACKED;
35 else if (!ip_conntrack_get(skb, &ctinfo)) 35 else if (!nf_ct_get_ctinfo(skb, &ctinfo))
36 statebit = IPT_STATE_INVALID; 36 statebit = IPT_STATE_INVALID;
37 else 37 else
38 statebit = IPT_STATE_BIT(ctinfo); 38 statebit = IPT_STATE_BIT(ctinfo);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
new file mode 100644
index 000000000000..8202c1c0afad
--- /dev/null
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -0,0 +1,571 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - move L3 protocol dependent part to this file.
10 * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
11 * - add get_features() to support various size of conntrack
12 * structures.
13 *
14 * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
15 */
16
17#include <linux/config.h>
18#include <linux/types.h>
19#include <linux/ip.h>
20#include <linux/netfilter.h>
21#include <linux/module.h>
22#include <linux/skbuff.h>
23#include <linux/icmp.h>
24#include <linux/sysctl.h>
25#include <net/ip.h>
26
27#include <linux/netfilter_ipv4.h>
28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_helper.h>
30#include <net/netfilter/nf_conntrack_protocol.h>
31#include <net/netfilter/nf_conntrack_l3proto.h>
32#include <net/netfilter/nf_conntrack_core.h>
33#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
34
35#if 0
36#define DEBUGP printk
37#else
38#define DEBUGP(format, args...)
39#endif
40
41DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
42
43static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
44 struct nf_conntrack_tuple *tuple)
45{
46 u_int32_t _addrs[2], *ap;
47 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
48 sizeof(u_int32_t) * 2, _addrs);
49 if (ap == NULL)
50 return 0;
51
52 tuple->src.u3.ip = ap[0];
53 tuple->dst.u3.ip = ap[1];
54
55 return 1;
56}
57
58static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
59 const struct nf_conntrack_tuple *orig)
60{
61 tuple->src.u3.ip = orig->dst.u3.ip;
62 tuple->dst.u3.ip = orig->src.u3.ip;
63
64 return 1;
65}
66
67static int ipv4_print_tuple(struct seq_file *s,
68 const struct nf_conntrack_tuple *tuple)
69{
70 return seq_printf(s, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
71 NIPQUAD(tuple->src.u3.ip),
72 NIPQUAD(tuple->dst.u3.ip));
73}
74
75static int ipv4_print_conntrack(struct seq_file *s,
76 const struct nf_conn *conntrack)
77{
78 return 0;
79}
80
81/* Returns new sk_buff, or NULL */
82static struct sk_buff *
83nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
84{
85 skb_orphan(skb);
86
87 local_bh_disable();
88 skb = ip_defrag(skb, user);
89 local_bh_enable();
90
91 if (skb)
92 ip_send_check(skb->nh.iph);
93
94 return skb;
95}
96
97static int
98ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
99 u_int8_t *protonum)
100{
101 /* Never happen */
102 if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
103 if (net_ratelimit()) {
104 printk(KERN_ERR "ipv4_prepare: Frag of proto %u (hook=%u)\n",
105 (*pskb)->nh.iph->protocol, hooknum);
106 }
107 return -NF_DROP;
108 }
109
110 *dataoff = (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4;
111 *protonum = (*pskb)->nh.iph->protocol;
112
113 return NF_ACCEPT;
114}
115
116int nat_module_is_loaded = 0;
117static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
118{
119 if (nat_module_is_loaded)
120 return NF_CT_F_NAT;
121
122 return NF_CT_F_BASIC;
123}
124
125static unsigned int ipv4_confirm(unsigned int hooknum,
126 struct sk_buff **pskb,
127 const struct net_device *in,
128 const struct net_device *out,
129 int (*okfn)(struct sk_buff *))
130{
131 /* We've seen it coming out the other side: confirm it */
132 return nf_conntrack_confirm(pskb);
133}
134
135static unsigned int ipv4_conntrack_help(unsigned int hooknum,
136 struct sk_buff **pskb,
137 const struct net_device *in,
138 const struct net_device *out,
139 int (*okfn)(struct sk_buff *))
140{
141 struct nf_conn *ct;
142 enum ip_conntrack_info ctinfo;
143
144 /* This is where we call the helper: as the packet goes out. */
145 ct = nf_ct_get(*pskb, &ctinfo);
146 if (ct && ct->helper) {
147 unsigned int ret;
148 ret = ct->helper->help(pskb,
149 (*pskb)->nh.raw - (*pskb)->data
150 + (*pskb)->nh.iph->ihl*4,
151 ct, ctinfo);
152 if (ret != NF_ACCEPT)
153 return ret;
154 }
155 return NF_ACCEPT;
156}
157
158static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
159 struct sk_buff **pskb,
160 const struct net_device *in,
161 const struct net_device *out,
162 int (*okfn)(struct sk_buff *))
163{
164#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
165 /* Previously seen (loopback)? Ignore. Do this before
166 fragment check. */
167 if ((*pskb)->nfct)
168 return NF_ACCEPT;
169#endif
170
171 /* Gather fragments. */
172 if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
173 *pskb = nf_ct_ipv4_gather_frags(*pskb,
174 hooknum == NF_IP_PRE_ROUTING ?
175 IP_DEFRAG_CONNTRACK_IN :
176 IP_DEFRAG_CONNTRACK_OUT);
177 if (!*pskb)
178 return NF_STOLEN;
179 }
180 return NF_ACCEPT;
181}
182
183static unsigned int ipv4_refrag(unsigned int hooknum,
184 struct sk_buff **pskb,
185 const struct net_device *in,
186 const struct net_device *out,
187 int (*okfn)(struct sk_buff *))
188{
189 struct rtable *rt = (struct rtable *)(*pskb)->dst;
190
191 /* We've seen it coming out the other side: confirm */
192 if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
193 return NF_DROP;
194
195 /* Local packets are never produced too large for their
196 interface. We degfragment them at LOCAL_OUT, however,
197 so we have to refragment them here. */
198 if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
199 !skb_shinfo(*pskb)->tso_size) {
200 /* No hook can be after us, so this should be OK. */
201 ip_fragment(*pskb, okfn);
202 return NF_STOLEN;
203 }
204 return NF_ACCEPT;
205}
206
207static unsigned int ipv4_conntrack_in(unsigned int hooknum,
208 struct sk_buff **pskb,
209 const struct net_device *in,
210 const struct net_device *out,
211 int (*okfn)(struct sk_buff *))
212{
213 return nf_conntrack_in(PF_INET, hooknum, pskb);
214}
215
216static unsigned int ipv4_conntrack_local(unsigned int hooknum,
217 struct sk_buff **pskb,
218 const struct net_device *in,
219 const struct net_device *out,
220 int (*okfn)(struct sk_buff *))
221{
222 /* root is playing with raw sockets. */
223 if ((*pskb)->len < sizeof(struct iphdr)
224 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
225 if (net_ratelimit())
226 printk("ipt_hook: happy cracking.\n");
227 return NF_ACCEPT;
228 }
229 return nf_conntrack_in(PF_INET, hooknum, pskb);
230}
231
232/* Connection tracking may drop packets, but never alters them, so
233 make it the first hook. */
234static struct nf_hook_ops ipv4_conntrack_defrag_ops = {
235 .hook = ipv4_conntrack_defrag,
236 .owner = THIS_MODULE,
237 .pf = PF_INET,
238 .hooknum = NF_IP_PRE_ROUTING,
239 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
240};
241
242static struct nf_hook_ops ipv4_conntrack_in_ops = {
243 .hook = ipv4_conntrack_in,
244 .owner = THIS_MODULE,
245 .pf = PF_INET,
246 .hooknum = NF_IP_PRE_ROUTING,
247 .priority = NF_IP_PRI_CONNTRACK,
248};
249
250static struct nf_hook_ops ipv4_conntrack_defrag_local_out_ops = {
251 .hook = ipv4_conntrack_defrag,
252 .owner = THIS_MODULE,
253 .pf = PF_INET,
254 .hooknum = NF_IP_LOCAL_OUT,
255 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
256};
257
258static struct nf_hook_ops ipv4_conntrack_local_out_ops = {
259 .hook = ipv4_conntrack_local,
260 .owner = THIS_MODULE,
261 .pf = PF_INET,
262 .hooknum = NF_IP_LOCAL_OUT,
263 .priority = NF_IP_PRI_CONNTRACK,
264};
265
266/* helpers */
267static struct nf_hook_ops ipv4_conntrack_helper_out_ops = {
268 .hook = ipv4_conntrack_help,
269 .owner = THIS_MODULE,
270 .pf = PF_INET,
271 .hooknum = NF_IP_POST_ROUTING,
272 .priority = NF_IP_PRI_CONNTRACK_HELPER,
273};
274
275static struct nf_hook_ops ipv4_conntrack_helper_in_ops = {
276 .hook = ipv4_conntrack_help,
277 .owner = THIS_MODULE,
278 .pf = PF_INET,
279 .hooknum = NF_IP_LOCAL_IN,
280 .priority = NF_IP_PRI_CONNTRACK_HELPER,
281};
282
283
284/* Refragmenter; last chance. */
285static struct nf_hook_ops ipv4_conntrack_out_ops = {
286 .hook = ipv4_refrag,
287 .owner = THIS_MODULE,
288 .pf = PF_INET,
289 .hooknum = NF_IP_POST_ROUTING,
290 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
291};
292
293static struct nf_hook_ops ipv4_conntrack_local_in_ops = {
294 .hook = ipv4_confirm,
295 .owner = THIS_MODULE,
296 .pf = PF_INET,
297 .hooknum = NF_IP_LOCAL_IN,
298 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
299};
300
301#ifdef CONFIG_SYSCTL
302/* From nf_conntrack_proto_icmp.c */
303extern unsigned long nf_ct_icmp_timeout;
304static struct ctl_table_header *nf_ct_ipv4_sysctl_header;
305
306static ctl_table nf_ct_sysctl_table[] = {
307 {
308 .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT,
309 .procname = "nf_conntrack_icmp_timeout",
310 .data = &nf_ct_icmp_timeout,
311 .maxlen = sizeof(unsigned int),
312 .mode = 0644,
313 .proc_handler = &proc_dointvec_jiffies,
314 },
315 { .ctl_name = 0 }
316};
317
318static ctl_table nf_ct_netfilter_table[] = {
319 {
320 .ctl_name = NET_NETFILTER,
321 .procname = "netfilter",
322 .mode = 0555,
323 .child = nf_ct_sysctl_table,
324 },
325 { .ctl_name = 0 }
326};
327
328static ctl_table nf_ct_net_table[] = {
329 {
330 .ctl_name = CTL_NET,
331 .procname = "net",
332 .mode = 0555,
333 .child = nf_ct_netfilter_table,
334 },
335 { .ctl_name = 0 }
336};
337#endif
338
339/* Fast function for those who don't want to parse /proc (and I don't
340 blame them). */
341/* Reversing the socket's dst/src point of view gives us the reply
342 mapping. */
343static int
344getorigdst(struct sock *sk, int optval, void __user *user, int *len)
345{
346 struct inet_sock *inet = inet_sk(sk);
347 struct nf_conntrack_tuple_hash *h;
348 struct nf_conntrack_tuple tuple;
349
350 NF_CT_TUPLE_U_BLANK(&tuple);
351 tuple.src.u3.ip = inet->rcv_saddr;
352 tuple.src.u.tcp.port = inet->sport;
353 tuple.dst.u3.ip = inet->daddr;
354 tuple.dst.u.tcp.port = inet->dport;
355 tuple.src.l3num = PF_INET;
356 tuple.dst.protonum = IPPROTO_TCP;
357
358 /* We only do TCP at the moment: is there a better way? */
359 if (strcmp(sk->sk_prot->name, "TCP")) {
360 DEBUGP("SO_ORIGINAL_DST: Not a TCP socket\n");
361 return -ENOPROTOOPT;
362 }
363
364 if ((unsigned int) *len < sizeof(struct sockaddr_in)) {
365 DEBUGP("SO_ORIGINAL_DST: len %u not %u\n",
366 *len, sizeof(struct sockaddr_in));
367 return -EINVAL;
368 }
369
370 h = nf_conntrack_find_get(&tuple, NULL);
371 if (h) {
372 struct sockaddr_in sin;
373 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
374
375 sin.sin_family = AF_INET;
376 sin.sin_port = ct->tuplehash[IP_CT_DIR_ORIGINAL]
377 .tuple.dst.u.tcp.port;
378 sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
379 .tuple.dst.u3.ip;
380
381 DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
382 NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
383 nf_ct_put(ct);
384 if (copy_to_user(user, &sin, sizeof(sin)) != 0)
385 return -EFAULT;
386 else
387 return 0;
388 }
389 DEBUGP("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
390 NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
391 NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
392 return -ENOENT;
393}
394
395static struct nf_sockopt_ops so_getorigdst = {
396 .pf = PF_INET,
397 .get_optmin = SO_ORIGINAL_DST,
398 .get_optmax = SO_ORIGINAL_DST+1,
399 .get = &getorigdst,
400};
401
402struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
403 .l3proto = PF_INET,
404 .name = "ipv4",
405 .pkt_to_tuple = ipv4_pkt_to_tuple,
406 .invert_tuple = ipv4_invert_tuple,
407 .print_tuple = ipv4_print_tuple,
408 .print_conntrack = ipv4_print_conntrack,
409 .prepare = ipv4_prepare,
410 .get_features = ipv4_get_features,
411 .me = THIS_MODULE,
412};
413
414extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4;
415extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
416extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp;
417static int init_or_cleanup(int init)
418{
419 int ret = 0;
420
421 if (!init) goto cleanup;
422
423 ret = nf_register_sockopt(&so_getorigdst);
424 if (ret < 0) {
425 printk(KERN_ERR "Unable to register netfilter socket option\n");
426 goto cleanup_nothing;
427 }
428
429 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4);
430 if (ret < 0) {
431 printk("nf_conntrack_ipv4: can't register tcp.\n");
432 goto cleanup_sockopt;
433 }
434
435 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp4);
436 if (ret < 0) {
437 printk("nf_conntrack_ipv4: can't register udp.\n");
438 goto cleanup_tcp;
439 }
440
441 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmp);
442 if (ret < 0) {
443 printk("nf_conntrack_ipv4: can't register icmp.\n");
444 goto cleanup_udp;
445 }
446
447 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
448 if (ret < 0) {
449 printk("nf_conntrack_ipv4: can't register ipv4\n");
450 goto cleanup_icmp;
451 }
452
453 ret = nf_register_hook(&ipv4_conntrack_defrag_ops);
454 if (ret < 0) {
455 printk("nf_conntrack_ipv4: can't register pre-routing defrag hook.\n");
456 goto cleanup_ipv4;
457 }
458 ret = nf_register_hook(&ipv4_conntrack_defrag_local_out_ops);
459 if (ret < 0) {
460 printk("nf_conntrack_ipv4: can't register local_out defrag hook.\n");
461 goto cleanup_defragops;
462 }
463
464 ret = nf_register_hook(&ipv4_conntrack_in_ops);
465 if (ret < 0) {
466 printk("nf_conntrack_ipv4: can't register pre-routing hook.\n");
467 goto cleanup_defraglocalops;
468 }
469
470 ret = nf_register_hook(&ipv4_conntrack_local_out_ops);
471 if (ret < 0) {
472 printk("nf_conntrack_ipv4: can't register local out hook.\n");
473 goto cleanup_inops;
474 }
475
476 ret = nf_register_hook(&ipv4_conntrack_helper_in_ops);
477 if (ret < 0) {
478 printk("nf_conntrack_ipv4: can't register local helper hook.\n");
479 goto cleanup_inandlocalops;
480 }
481
482 ret = nf_register_hook(&ipv4_conntrack_helper_out_ops);
483 if (ret < 0) {
484 printk("nf_conntrack_ipv4: can't register postrouting helper hook.\n");
485 goto cleanup_helperinops;
486 }
487
488 ret = nf_register_hook(&ipv4_conntrack_out_ops);
489 if (ret < 0) {
490 printk("nf_conntrack_ipv4: can't register post-routing hook.\n");
491 goto cleanup_helperoutops;
492 }
493
494 ret = nf_register_hook(&ipv4_conntrack_local_in_ops);
495 if (ret < 0) {
496 printk("nf_conntrack_ipv4: can't register local in hook.\n");
497 goto cleanup_inoutandlocalops;
498 }
499
500#ifdef CONFIG_SYSCTL
501 nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
502 if (nf_ct_ipv4_sysctl_header == NULL) {
503 printk("nf_conntrack: can't register to sysctl.\n");
504 ret = -ENOMEM;
505 goto cleanup_localinops;
506 }
507#endif
508
509 /* For use by REJECT target */
510 ip_ct_attach = __nf_conntrack_attach;
511
512 return ret;
513
514 cleanup:
515 synchronize_net();
516 ip_ct_attach = NULL;
517#ifdef CONFIG_SYSCTL
518 unregister_sysctl_table(nf_ct_ipv4_sysctl_header);
519 cleanup_localinops:
520#endif
521 nf_unregister_hook(&ipv4_conntrack_local_in_ops);
522 cleanup_inoutandlocalops:
523 nf_unregister_hook(&ipv4_conntrack_out_ops);
524 cleanup_helperoutops:
525 nf_unregister_hook(&ipv4_conntrack_helper_out_ops);
526 cleanup_helperinops:
527 nf_unregister_hook(&ipv4_conntrack_helper_in_ops);
528 cleanup_inandlocalops:
529 nf_unregister_hook(&ipv4_conntrack_local_out_ops);
530 cleanup_inops:
531 nf_unregister_hook(&ipv4_conntrack_in_ops);
532 cleanup_defraglocalops:
533 nf_unregister_hook(&ipv4_conntrack_defrag_local_out_ops);
534 cleanup_defragops:
535 nf_unregister_hook(&ipv4_conntrack_defrag_ops);
536 cleanup_ipv4:
537 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
538 cleanup_icmp:
539 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp);
540 cleanup_udp:
541 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4);
542 cleanup_tcp:
543 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4);
544 cleanup_sockopt:
545 nf_unregister_sockopt(&so_getorigdst);
546 cleanup_nothing:
547 return ret;
548}
549
550MODULE_LICENSE("GPL");
551
552static int __init init(void)
553{
554 need_nf_conntrack();
555 return init_or_cleanup(1);
556}
557
558static void __exit fini(void)
559{
560 init_or_cleanup(0);
561}
562
563module_init(init);
564module_exit(fini);
565
566void need_ip_conntrack(void)
567{
568}
569
570EXPORT_SYMBOL(need_ip_conntrack);
571EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
new file mode 100644
index 000000000000..7ddb5c08f7b8
--- /dev/null
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -0,0 +1,301 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - enable working with Layer 3 protocol independent connection tracking.
10 *
11 * Derived from net/ipv4/netfilter/ip_conntrack_proto_icmp.c
12 */
13
14#include <linux/types.h>
15#include <linux/sched.h>
16#include <linux/timer.h>
17#include <linux/netfilter.h>
18#include <linux/in.h>
19#include <linux/icmp.h>
20#include <linux/seq_file.h>
21#include <net/ip.h>
22#include <net/checksum.h>
23#include <linux/netfilter_ipv4.h>
24#include <net/netfilter/nf_conntrack_tuple.h>
25#include <net/netfilter/nf_conntrack_protocol.h>
26#include <net/netfilter/nf_conntrack_core.h>
27
28unsigned long nf_ct_icmp_timeout = 30*HZ;
29
30#if 0
31#define DEBUGP printk
32#else
33#define DEBUGP(format, args...)
34#endif
35
36static int icmp_pkt_to_tuple(const struct sk_buff *skb,
37 unsigned int dataoff,
38 struct nf_conntrack_tuple *tuple)
39{
40 struct icmphdr _hdr, *hp;
41
42 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
43 if (hp == NULL)
44 return 0;
45
46 tuple->dst.u.icmp.type = hp->type;
47 tuple->src.u.icmp.id = hp->un.echo.id;
48 tuple->dst.u.icmp.code = hp->code;
49
50 return 1;
51}
52
53static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
54 const struct nf_conntrack_tuple *orig)
55{
56 /* Add 1; spaces filled with 0. */
57 static u_int8_t invmap[]
58 = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
59 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
60 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
61 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
62 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
63 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
64 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
65 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
66
67 if (orig->dst.u.icmp.type >= sizeof(invmap)
68 || !invmap[orig->dst.u.icmp.type])
69 return 0;
70
71 tuple->src.u.icmp.id = orig->src.u.icmp.id;
72 tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
73 tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
74 return 1;
75}
76
77/* Print out the per-protocol part of the tuple. */
78static int icmp_print_tuple(struct seq_file *s,
79 const struct nf_conntrack_tuple *tuple)
80{
81 return seq_printf(s, "type=%u code=%u id=%u ",
82 tuple->dst.u.icmp.type,
83 tuple->dst.u.icmp.code,
84 ntohs(tuple->src.u.icmp.id));
85}
86
87/* Print out the private part of the conntrack. */
88static int icmp_print_conntrack(struct seq_file *s,
89 const struct nf_conn *conntrack)
90{
91 return 0;
92}
93
94/* Returns verdict for packet, or -1 for invalid. */
95static int icmp_packet(struct nf_conn *ct,
96 const struct sk_buff *skb,
97 unsigned int dataoff,
98 enum ip_conntrack_info ctinfo,
99 int pf,
100 unsigned int hooknum)
101{
102 /* Try to delete connection immediately after all replies:
103 won't actually vanish as we still have skb, and del_timer
104 means this will only run once even if count hits zero twice
105 (theoretically possible with SMP) */
106 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
107 if (atomic_dec_and_test(&ct->proto.icmp.count)
108 && del_timer(&ct->timeout))
109 ct->timeout.function((unsigned long)ct);
110 } else {
111 atomic_inc(&ct->proto.icmp.count);
112 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
113 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
114 }
115
116 return NF_ACCEPT;
117}
118
119/* Called when a new connection for this protocol found. */
120static int icmp_new(struct nf_conn *conntrack,
121 const struct sk_buff *skb, unsigned int dataoff)
122{
123 static u_int8_t valid_new[]
124 = { [ICMP_ECHO] = 1,
125 [ICMP_TIMESTAMP] = 1,
126 [ICMP_INFO_REQUEST] = 1,
127 [ICMP_ADDRESS] = 1 };
128
129 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
130 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
131 /* Can't create a new ICMP `conn' with this. */
132 DEBUGP("icmp: can't create new conn with type %u\n",
133 conntrack->tuplehash[0].tuple.dst.u.icmp.type);
134 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
135 return 0;
136 }
137 atomic_set(&conntrack->proto.icmp.count, 0);
138 return 1;
139}
140
141extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
142/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
143static int
144icmp_error_message(struct sk_buff *skb,
145 enum ip_conntrack_info *ctinfo,
146 unsigned int hooknum)
147{
148 struct nf_conntrack_tuple innertuple, origtuple;
149 struct {
150 struct icmphdr icmp;
151 struct iphdr ip;
152 } _in, *inside;
153 struct nf_conntrack_protocol *innerproto;
154 struct nf_conntrack_tuple_hash *h;
155 int dataoff;
156
157 NF_CT_ASSERT(skb->nfct == NULL);
158
159 /* Not enough header? */
160 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
161 if (inside == NULL)
162 return -NF_ACCEPT;
163
164 /* Ignore ICMP's containing fragments (shouldn't happen) */
165 if (inside->ip.frag_off & htons(IP_OFFSET)) {
166 DEBUGP("icmp_error_message: fragment of proto %u\n",
167 inside->ip.protocol);
168 return -NF_ACCEPT;
169 }
170
171 innerproto = nf_ct_find_proto(PF_INET, inside->ip.protocol);
172 dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp);
173 /* Are they talking about one of our connections? */
174 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
175 inside->ip.protocol, &origtuple,
176 &nf_conntrack_l3proto_ipv4, innerproto)) {
177 DEBUGP("icmp_error_message: ! get_tuple p=%u",
178 inside->ip.protocol);
179 return -NF_ACCEPT;
180 }
181
182 /* Ordinarily, we'd expect the inverted tupleproto, but it's
183 been preserved inside the ICMP. */
184 if (!nf_ct_invert_tuple(&innertuple, &origtuple,
185 &nf_conntrack_l3proto_ipv4, innerproto)) {
186 DEBUGP("icmp_error_message: no match\n");
187 return -NF_ACCEPT;
188 }
189
190 *ctinfo = IP_CT_RELATED;
191
192 h = nf_conntrack_find_get(&innertuple, NULL);
193 if (!h) {
194 /* Locally generated ICMPs will match inverted if they
195 haven't been SNAT'ed yet */
196 /* FIXME: NAT code has to handle half-done double NAT --RR */
197 if (hooknum == NF_IP_LOCAL_OUT)
198 h = nf_conntrack_find_get(&origtuple, NULL);
199
200 if (!h) {
201 DEBUGP("icmp_error_message: no match\n");
202 return -NF_ACCEPT;
203 }
204
205 /* Reverse direction from that found */
206 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
207 *ctinfo += IP_CT_IS_REPLY;
208 } else {
209 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
210 *ctinfo += IP_CT_IS_REPLY;
211 }
212
213 /* Update skb to refer to this connection */
214 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
215 skb->nfctinfo = *ctinfo;
216 return -NF_ACCEPT;
217}
218
219/* Small and modified version of icmp_rcv */
220static int
221icmp_error(struct sk_buff *skb, unsigned int dataoff,
222 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
223{
224 struct icmphdr _ih, *icmph;
225
226 /* Not enough header? */
227 icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih);
228 if (icmph == NULL) {
229 if (LOG_INVALID(IPPROTO_ICMP))
230 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
231 "nf_ct_icmp: short packet ");
232 return -NF_ACCEPT;
233 }
234
235 /* See ip_conntrack_proto_tcp.c */
236 if (hooknum != NF_IP_PRE_ROUTING)
237 goto checksum_skipped;
238
239 switch (skb->ip_summed) {
240 case CHECKSUM_HW:
241 if (!(u16)csum_fold(skb->csum))
242 break;
243 if (LOG_INVALID(IPPROTO_ICMP))
244 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
245 "nf_ct_icmp: bad HW ICMP checksum ");
246 return -NF_ACCEPT;
247 case CHECKSUM_NONE:
248 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) {
249 if (LOG_INVALID(IPPROTO_ICMP))
250 nf_log_packet(PF_INET, 0, skb, NULL, NULL,
251 NULL,
252 "nf_ct_icmp: bad ICMP checksum ");
253 return -NF_ACCEPT;
254 }
255 default:
256 break;
257 }
258
259checksum_skipped:
260 /*
261 * 18 is the highest 'known' ICMP type. Anything else is a mystery
262 *
263 * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
264 * discarded.
265 */
266 if (icmph->type > NR_ICMP_TYPES) {
267 if (LOG_INVALID(IPPROTO_ICMP))
268 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
269 "nf_ct_icmp: invalid ICMP type ");
270 return -NF_ACCEPT;
271 }
272
273 /* Need to track icmp error message? */
274 if (icmph->type != ICMP_DEST_UNREACH
275 && icmph->type != ICMP_SOURCE_QUENCH
276 && icmph->type != ICMP_TIME_EXCEEDED
277 && icmph->type != ICMP_PARAMETERPROB
278 && icmph->type != ICMP_REDIRECT)
279 return NF_ACCEPT;
280
281 return icmp_error_message(skb, ctinfo, hooknum);
282}
283
284struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
285{
286 .list = { NULL, NULL },
287 .l3proto = PF_INET,
288 .proto = IPPROTO_ICMP,
289 .name = "icmp",
290 .pkt_to_tuple = icmp_pkt_to_tuple,
291 .invert_tuple = icmp_invert_tuple,
292 .print_tuple = icmp_print_tuple,
293 .print_conntrack = icmp_print_conntrack,
294 .packet = icmp_packet,
295 .new = icmp_new,
296 .error = icmp_error,
297 .destroy = NULL,
298 .me = NULL
299};
300
301EXPORT_SYMBOL(nf_conntrack_protocol_icmp);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 652685623519..01444a02b48b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -645,6 +645,14 @@ ctl_table ipv4_table[] = {
645 .proc_handler = &proc_tcp_congestion_control, 645 .proc_handler = &proc_tcp_congestion_control,
646 .strategy = &sysctl_tcp_congestion_control, 646 .strategy = &sysctl_tcp_congestion_control,
647 }, 647 },
648 {
649 .ctl_name = NET_TCP_ABC,
650 .procname = "tcp_abc",
651 .data = &sysctl_tcp_abc,
652 .maxlen = sizeof(int),
653 .mode = 0644,
654 .proc_handler = &proc_dointvec,
655 },
648 656
649 { .ctl_name = 0 } 657 { .ctl_name = 0 }
650}; 658};
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 72b7c22e1ea5..9ac7a4f46bd8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1640,7 +1640,7 @@ int tcp_disconnect(struct sock *sk, int flags)
1640 } else if (tcp_need_reset(old_state) || 1640 } else if (tcp_need_reset(old_state) ||
1641 (tp->snd_nxt != tp->write_seq && 1641 (tp->snd_nxt != tp->write_seq &&
1642 (1 << old_state) & (TCPF_CLOSING | TCPF_LAST_ACK))) { 1642 (1 << old_state) & (TCPF_CLOSING | TCPF_LAST_ACK))) {
1643 /* The last check adjusts for discrepance of Linux wrt. RFC 1643 /* The last check adjusts for discrepancy of Linux wrt. RFC
1644 * states 1644 * states
1645 */ 1645 */
1646 tcp_send_active_reset(sk, gfp_any()); 1646 tcp_send_active_reset(sk, gfp_any());
@@ -1669,6 +1669,7 @@ int tcp_disconnect(struct sock *sk, int flags)
1669 tp->packets_out = 0; 1669 tp->packets_out = 0;
1670 tp->snd_ssthresh = 0x7fffffff; 1670 tp->snd_ssthresh = 0x7fffffff;
1671 tp->snd_cwnd_cnt = 0; 1671 tp->snd_cwnd_cnt = 0;
1672 tp->bytes_acked = 0;
1672 tcp_set_ca_state(sk, TCP_CA_Open); 1673 tcp_set_ca_state(sk, TCP_CA_Open);
1673 tcp_clear_retrans(tp); 1674 tcp_clear_retrans(tp);
1674 inet_csk_delack_init(sk); 1675 inet_csk_delack_init(sk);
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index ae35e0609047..1d0cd86621b1 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -217,17 +217,15 @@ static void bictcp_cong_avoid(struct sock *sk, u32 ack,
217 217
218 bictcp_low_utilization(sk, data_acked); 218 bictcp_low_utilization(sk, data_acked);
219 219
220 if (in_flight < tp->snd_cwnd) 220 if (!tcp_is_cwnd_limited(sk, in_flight))
221 return; 221 return;
222 222
223 if (tp->snd_cwnd <= tp->snd_ssthresh) { 223 if (tp->snd_cwnd <= tp->snd_ssthresh)
224 /* In "safe" area, increase. */ 224 tcp_slow_start(tp);
225 if (tp->snd_cwnd < tp->snd_cwnd_clamp) 225 else {
226 tp->snd_cwnd++;
227 } else {
228 bictcp_update(ca, tp->snd_cwnd); 226 bictcp_update(ca, tp->snd_cwnd);
229 227
230 /* In dangerous area, increase slowly. 228 /* In dangerous area, increase slowly.
231 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd 229 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
232 */ 230 */
233 if (tp->snd_cwnd_cnt >= ca->cnt) { 231 if (tp->snd_cwnd_cnt >= ca->cnt) {
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index bbf2d6624e89..c7cc62c8dc12 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -186,24 +186,32 @@ void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight,
186{ 186{
187 struct tcp_sock *tp = tcp_sk(sk); 187 struct tcp_sock *tp = tcp_sk(sk);
188 188
189 if (in_flight < tp->snd_cwnd) 189 if (!tcp_is_cwnd_limited(sk, in_flight))
190 return; 190 return;
191 191
192 if (tp->snd_cwnd <= tp->snd_ssthresh) { 192 /* In "safe" area, increase. */
193 /* In "safe" area, increase. */ 193 if (tp->snd_cwnd <= tp->snd_ssthresh)
194 if (tp->snd_cwnd < tp->snd_cwnd_clamp) 194 tcp_slow_start(tp);
195 tp->snd_cwnd++; 195
196 } else { 196 /* In dangerous area, increase slowly. */
197 /* In dangerous area, increase slowly. 197 else if (sysctl_tcp_abc) {
198 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd 198 /* RFC3465: Apppriate Byte Count
199 */ 199 * increase once for each full cwnd acked
200 if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { 200 */
201 if (tp->snd_cwnd < tp->snd_cwnd_clamp) 201 if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) {
202 tp->snd_cwnd++; 202 tp->bytes_acked -= tp->snd_cwnd*tp->mss_cache;
203 tp->snd_cwnd_cnt = 0; 203 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
204 } else 204 tp->snd_cwnd++;
205 tp->snd_cwnd_cnt++; 205 }
206 } 206 } else {
207 /* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd */
208 if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
209 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
210 tp->snd_cwnd++;
211 tp->snd_cwnd_cnt = 0;
212 } else
213 tp->snd_cwnd_cnt++;
214 }
207} 215}
208EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid); 216EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
209 217
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
index 6acc04bde080..82b3c189bd7d 100644
--- a/net/ipv4/tcp_highspeed.c
+++ b/net/ipv4/tcp_highspeed.c
@@ -111,18 +111,17 @@ static void hstcp_init(struct sock *sk)
111} 111}
112 112
113static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt, 113static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
114 u32 in_flight, int good) 114 u32 in_flight, u32 pkts_acked)
115{ 115{
116 struct tcp_sock *tp = tcp_sk(sk); 116 struct tcp_sock *tp = tcp_sk(sk);
117 struct hstcp *ca = inet_csk_ca(sk); 117 struct hstcp *ca = inet_csk_ca(sk);
118 118
119 if (in_flight < tp->snd_cwnd) 119 if (!tcp_is_cwnd_limited(sk, in_flight))
120 return; 120 return;
121 121
122 if (tp->snd_cwnd <= tp->snd_ssthresh) { 122 if (tp->snd_cwnd <= tp->snd_ssthresh)
123 if (tp->snd_cwnd < tp->snd_cwnd_clamp) 123 tcp_slow_start(tp);
124 tp->snd_cwnd++; 124 else {
125 } else {
126 /* Update AIMD parameters */ 125 /* Update AIMD parameters */
127 if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) { 126 if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
128 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && 127 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index e47b37984e95..3284cfb993e6 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -207,14 +207,13 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
207 struct tcp_sock *tp = tcp_sk(sk); 207 struct tcp_sock *tp = tcp_sk(sk);
208 struct htcp *ca = inet_csk_ca(sk); 208 struct htcp *ca = inet_csk_ca(sk);
209 209
210 if (in_flight < tp->snd_cwnd) 210 if (!tcp_is_cwnd_limited(sk, in_flight))
211 return; 211 return;
212 212
213 if (tp->snd_cwnd <= tp->snd_ssthresh) { 213 if (tp->snd_cwnd <= tp->snd_ssthresh)
214 /* In "safe" area, increase. */ 214 tcp_slow_start(tp);
215 if (tp->snd_cwnd < tp->snd_cwnd_clamp) 215 else {
216 tp->snd_cwnd++; 216
217 } else {
218 measure_rtt(sk); 217 measure_rtt(sk);
219 218
220 /* keep track of number of round-trip times since last backoff event */ 219 /* keep track of number of round-trip times since last backoff event */
@@ -224,7 +223,7 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
224 htcp_alpha_update(ca); 223 htcp_alpha_update(ca);
225 } 224 }
226 225
227 /* In dangerous area, increase slowly. 226 /* In dangerous area, increase slowly.
228 * In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd 227 * In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd
229 */ 228 */
230 if ((tp->snd_cwnd_cnt++ * ca->alpha)>>7 >= tp->snd_cwnd) { 229 if ((tp->snd_cwnd_cnt++ * ca->alpha)>>7 >= tp->snd_cwnd) {
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
index 77add63623df..40dbb3877510 100644
--- a/net/ipv4/tcp_hybla.c
+++ b/net/ipv4/tcp_hybla.c
@@ -100,12 +100,12 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
100 ca->minrtt = tp->srtt; 100 ca->minrtt = tp->srtt;
101 } 101 }
102 102
103 if (!tcp_is_cwnd_limited(sk, in_flight))
104 return;
105
103 if (!ca->hybla_en) 106 if (!ca->hybla_en)
104 return tcp_reno_cong_avoid(sk, ack, rtt, in_flight, flag); 107 return tcp_reno_cong_avoid(sk, ack, rtt, in_flight, flag);
105 108
106 if (in_flight < tp->snd_cwnd)
107 return;
108
109 if (ca->rho == 0) 109 if (ca->rho == 0)
110 hybla_recalc_param(sk); 110 hybla_recalc_param(sk);
111 111
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3e98b57578dc..40a26b7157b4 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -42,7 +42,7 @@
42 * Andi Kleen : Moved open_request checking here 42 * Andi Kleen : Moved open_request checking here
43 * and process RSTs for open_requests. 43 * and process RSTs for open_requests.
44 * Andi Kleen : Better prune_queue, and other fixes. 44 * Andi Kleen : Better prune_queue, and other fixes.
45 * Andrey Savochkin: Fix RTT measurements in the presnce of 45 * Andrey Savochkin: Fix RTT measurements in the presence of
46 * timestamps. 46 * timestamps.
47 * Andrey Savochkin: Check sequence numbers correctly when 47 * Andrey Savochkin: Check sequence numbers correctly when
48 * removing SACKs due to in sequence incoming 48 * removing SACKs due to in sequence incoming
@@ -89,6 +89,7 @@ int sysctl_tcp_frto;
89int sysctl_tcp_nometrics_save; 89int sysctl_tcp_nometrics_save;
90 90
91int sysctl_tcp_moderate_rcvbuf = 1; 91int sysctl_tcp_moderate_rcvbuf = 1;
92int sysctl_tcp_abc = 1;
92 93
93#define FLAG_DATA 0x01 /* Incoming frame contained data. */ 94#define FLAG_DATA 0x01 /* Incoming frame contained data. */
94#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ 95#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
@@ -223,7 +224,7 @@ static void tcp_fixup_sndbuf(struct sock *sk)
223 * of receiver window. Check #2. 224 * of receiver window. Check #2.
224 * 225 *
225 * The scheme does not work when sender sends good segments opening 226 * The scheme does not work when sender sends good segments opening
226 * window and then starts to feed us spagetti. But it should work 227 * window and then starts to feed us spaghetti. But it should work
227 * in common situations. Otherwise, we have to rely on queue collapsing. 228 * in common situations. Otherwise, we have to rely on queue collapsing.
228 */ 229 */
229 230
@@ -233,7 +234,7 @@ static int __tcp_grow_window(const struct sock *sk, struct tcp_sock *tp,
233{ 234{
234 /* Optimize this! */ 235 /* Optimize this! */
235 int truesize = tcp_win_from_space(skb->truesize)/2; 236 int truesize = tcp_win_from_space(skb->truesize)/2;
236 int window = tcp_full_space(sk)/2; 237 int window = tcp_win_from_space(sysctl_tcp_rmem[2])/2;
237 238
238 while (tp->rcv_ssthresh <= window) { 239 while (tp->rcv_ssthresh <= window) {
239 if (truesize <= skb->len) 240 if (truesize <= skb->len)
@@ -277,7 +278,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk)
277 int rcvmem = tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff); 278 int rcvmem = tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff);
278 279
279 /* Try to select rcvbuf so that 4 mss-sized segments 280 /* Try to select rcvbuf so that 4 mss-sized segments
280 * will fit to window and correspoding skbs will fit to our rcvbuf. 281 * will fit to window and corresponding skbs will fit to our rcvbuf.
281 * (was 3; 4 is minimum to allow fast retransmit to work.) 282 * (was 3; 4 is minimum to allow fast retransmit to work.)
282 */ 283 */
283 while (tcp_win_from_space(rcvmem) < tp->advmss) 284 while (tcp_win_from_space(rcvmem) < tp->advmss)
@@ -286,7 +287,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk)
286 sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]); 287 sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]);
287} 288}
288 289
289/* 4. Try to fixup all. It is made iimediately after connection enters 290/* 4. Try to fixup all. It is made immediately after connection enters
290 * established state. 291 * established state.
291 */ 292 */
292static void tcp_init_buffer_space(struct sock *sk) 293static void tcp_init_buffer_space(struct sock *sk)
@@ -326,37 +327,18 @@ static void tcp_init_buffer_space(struct sock *sk)
326static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp) 327static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
327{ 328{
328 struct inet_connection_sock *icsk = inet_csk(sk); 329 struct inet_connection_sock *icsk = inet_csk(sk);
329 struct sk_buff *skb;
330 unsigned int app_win = tp->rcv_nxt - tp->copied_seq;
331 int ofo_win = 0;
332 330
333 icsk->icsk_ack.quick = 0; 331 icsk->icsk_ack.quick = 0;
334 332
335 skb_queue_walk(&tp->out_of_order_queue, skb) { 333 if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
336 ofo_win += skb->len; 334 !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
337 } 335 !tcp_memory_pressure &&
338 336 atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
339 /* If overcommit is due to out of order segments, 337 sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
340 * do not clamp window. Try to expand rcvbuf instead. 338 sysctl_tcp_rmem[2]);
341 */
342 if (ofo_win) {
343 if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
344 !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
345 !tcp_memory_pressure &&
346 atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0])
347 sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
348 sysctl_tcp_rmem[2]);
349 } 339 }
350 if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) { 340 if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
351 app_win += ofo_win;
352 if (atomic_read(&sk->sk_rmem_alloc) >= 2 * sk->sk_rcvbuf)
353 app_win >>= 1;
354 if (app_win > icsk->icsk_ack.rcv_mss)
355 app_win -= icsk->icsk_ack.rcv_mss;
356 app_win = max(app_win, 2U*tp->advmss);
357
358 tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss); 341 tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
359 }
360} 342}
361 343
362/* Receiver "autotuning" code. 344/* Receiver "autotuning" code.
@@ -385,8 +367,8 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
385 * are stalled on filesystem I/O. 367 * are stalled on filesystem I/O.
386 * 368 *
387 * Also, since we are only going for a minimum in the 369 * Also, since we are only going for a minimum in the
388 * non-timestamp case, we do not smoothe things out 370 * non-timestamp case, we do not smoother things out
389 * else with timestamps disabled convergance takes too 371 * else with timestamps disabled convergence takes too
390 * long. 372 * long.
391 */ 373 */
392 if (!win_dep) { 374 if (!win_dep) {
@@ -395,7 +377,7 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
395 } else if (m < new_sample) 377 } else if (m < new_sample)
396 new_sample = m << 3; 378 new_sample = m << 3;
397 } else { 379 } else {
398 /* No previous mesaure. */ 380 /* No previous measure. */
399 new_sample = m << 3; 381 new_sample = m << 3;
400 } 382 }
401 383
@@ -524,7 +506,7 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_sock *tp, struct sk_
524 if (icsk->icsk_ack.ato > icsk->icsk_rto) 506 if (icsk->icsk_ack.ato > icsk->icsk_rto)
525 icsk->icsk_ack.ato = icsk->icsk_rto; 507 icsk->icsk_ack.ato = icsk->icsk_rto;
526 } else if (m > icsk->icsk_rto) { 508 } else if (m > icsk->icsk_rto) {
527 /* Too long gap. Apparently sender falled to 509 /* Too long gap. Apparently sender failed to
528 * restart window, so that we send ACKs quickly. 510 * restart window, so that we send ACKs quickly.
529 */ 511 */
530 tcp_incr_quickack(sk); 512 tcp_incr_quickack(sk);
@@ -548,10 +530,9 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_sock *tp, struct sk_
548 * To save cycles in the RFC 1323 implementation it was better to break 530 * To save cycles in the RFC 1323 implementation it was better to break
549 * it up into three procedures. -- erics 531 * it up into three procedures. -- erics
550 */ 532 */
551static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt, u32 *usrtt) 533static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt)
552{ 534{
553 struct tcp_sock *tp = tcp_sk(sk); 535 struct tcp_sock *tp = tcp_sk(sk);
554 const struct inet_connection_sock *icsk = inet_csk(sk);
555 long m = mrtt; /* RTT */ 536 long m = mrtt; /* RTT */
556 537
557 /* The following amusing code comes from Jacobson's 538 /* The following amusing code comes from Jacobson's
@@ -565,7 +546,7 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt, u32 *usrtt)
565 * 546 *
566 * Funny. This algorithm seems to be very broken. 547 * Funny. This algorithm seems to be very broken.
567 * These formulae increase RTO, when it should be decreased, increase 548 * These formulae increase RTO, when it should be decreased, increase
568 * too slowly, when it should be incresed fastly, decrease too fastly 549 * too slowly, when it should be increased fastly, decrease too fastly
569 * etc. I guess in BSD RTO takes ONE value, so that it is absolutely 550 * etc. I guess in BSD RTO takes ONE value, so that it is absolutely
570 * does not matter how to _calculate_ it. Seems, it was trap 551 * does not matter how to _calculate_ it. Seems, it was trap
571 * that VJ failed to avoid. 8) 552 * that VJ failed to avoid. 8)
@@ -610,9 +591,6 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt, u32 *usrtt)
610 tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); 591 tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
611 tp->rtt_seq = tp->snd_nxt; 592 tp->rtt_seq = tp->snd_nxt;
612 } 593 }
613
614 if (icsk->icsk_ca_ops->rtt_sample)
615 icsk->icsk_ca_ops->rtt_sample(sk, *usrtt);
616} 594}
617 595
618/* Calculate rto without backoff. This is the second half of Van Jacobson's 596/* Calculate rto without backoff. This is the second half of Van Jacobson's
@@ -629,14 +607,14 @@ static inline void tcp_set_rto(struct sock *sk)
629 * at least by solaris and freebsd. "Erratic ACKs" has _nothing_ 607 * at least by solaris and freebsd. "Erratic ACKs" has _nothing_
630 * to do with delayed acks, because at cwnd>2 true delack timeout 608 * to do with delayed acks, because at cwnd>2 true delack timeout
631 * is invisible. Actually, Linux-2.4 also generates erratic 609 * is invisible. Actually, Linux-2.4 also generates erratic
632 * ACKs in some curcumstances. 610 * ACKs in some circumstances.
633 */ 611 */
634 inet_csk(sk)->icsk_rto = (tp->srtt >> 3) + tp->rttvar; 612 inet_csk(sk)->icsk_rto = (tp->srtt >> 3) + tp->rttvar;
635 613
636 /* 2. Fixups made earlier cannot be right. 614 /* 2. Fixups made earlier cannot be right.
637 * If we do not estimate RTO correctly without them, 615 * If we do not estimate RTO correctly without them,
638 * all the algo is pure shit and should be replaced 616 * all the algo is pure shit and should be replaced
639 * with correct one. It is exaclty, which we pretend to do. 617 * with correct one. It is exactly, which we pretend to do.
640 */ 618 */
641} 619}
642 620
@@ -794,7 +772,7 @@ static void tcp_init_metrics(struct sock *sk)
794 * to make it more realistic. 772 * to make it more realistic.
795 * 773 *
796 * A bit of theory. RTT is time passed after "normal" sized packet 774 * A bit of theory. RTT is time passed after "normal" sized packet
797 * is sent until it is ACKed. In normal curcumstances sending small 775 * is sent until it is ACKed. In normal circumstances sending small
798 * packets force peer to delay ACKs and calculation is correct too. 776 * packets force peer to delay ACKs and calculation is correct too.
799 * The algorithm is adaptive and, provided we follow specs, it 777 * The algorithm is adaptive and, provided we follow specs, it
800 * NEVER underestimate RTT. BUT! If peer tries to make some clever 778 * NEVER underestimate RTT. BUT! If peer tries to make some clever
@@ -919,18 +897,32 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
919 int prior_fackets; 897 int prior_fackets;
920 u32 lost_retrans = 0; 898 u32 lost_retrans = 0;
921 int flag = 0; 899 int flag = 0;
900 int dup_sack = 0;
922 int i; 901 int i;
923 902
924 if (!tp->sacked_out) 903 if (!tp->sacked_out)
925 tp->fackets_out = 0; 904 tp->fackets_out = 0;
926 prior_fackets = tp->fackets_out; 905 prior_fackets = tp->fackets_out;
927 906
928 for (i=0; i<num_sacks; i++, sp++) { 907 /* SACK fastpath:
929 struct sk_buff *skb; 908 * if the only SACK change is the increase of the end_seq of
930 __u32 start_seq = ntohl(sp->start_seq); 909 * the first block then only apply that SACK block
931 __u32 end_seq = ntohl(sp->end_seq); 910 * and use retrans queue hinting otherwise slowpath */
932 int fack_count = 0; 911 flag = 1;
933 int dup_sack = 0; 912 for (i = 0; i< num_sacks; i++) {
913 __u32 start_seq = ntohl(sp[i].start_seq);
914 __u32 end_seq = ntohl(sp[i].end_seq);
915
916 if (i == 0){
917 if (tp->recv_sack_cache[i].start_seq != start_seq)
918 flag = 0;
919 } else {
920 if ((tp->recv_sack_cache[i].start_seq != start_seq) ||
921 (tp->recv_sack_cache[i].end_seq != end_seq))
922 flag = 0;
923 }
924 tp->recv_sack_cache[i].start_seq = start_seq;
925 tp->recv_sack_cache[i].end_seq = end_seq;
934 926
935 /* Check for D-SACK. */ 927 /* Check for D-SACK. */
936 if (i == 0) { 928 if (i == 0) {
@@ -962,15 +954,58 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
962 if (before(ack, prior_snd_una - tp->max_window)) 954 if (before(ack, prior_snd_una - tp->max_window))
963 return 0; 955 return 0;
964 } 956 }
957 }
958
959 if (flag)
960 num_sacks = 1;
961 else {
962 int j;
963 tp->fastpath_skb_hint = NULL;
964
965 /* order SACK blocks to allow in order walk of the retrans queue */
966 for (i = num_sacks-1; i > 0; i--) {
967 for (j = 0; j < i; j++){
968 if (after(ntohl(sp[j].start_seq),
969 ntohl(sp[j+1].start_seq))){
970 sp[j].start_seq = htonl(tp->recv_sack_cache[j+1].start_seq);
971 sp[j].end_seq = htonl(tp->recv_sack_cache[j+1].end_seq);
972 sp[j+1].start_seq = htonl(tp->recv_sack_cache[j].start_seq);
973 sp[j+1].end_seq = htonl(tp->recv_sack_cache[j].end_seq);
974 }
975
976 }
977 }
978 }
979
980 /* clear flag as used for different purpose in following code */
981 flag = 0;
982
983 for (i=0; i<num_sacks; i++, sp++) {
984 struct sk_buff *skb;
985 __u32 start_seq = ntohl(sp->start_seq);
986 __u32 end_seq = ntohl(sp->end_seq);
987 int fack_count;
988
989 /* Use SACK fastpath hint if valid */
990 if (tp->fastpath_skb_hint) {
991 skb = tp->fastpath_skb_hint;
992 fack_count = tp->fastpath_cnt_hint;
993 } else {
994 skb = sk->sk_write_queue.next;
995 fack_count = 0;
996 }
965 997
966 /* Event "B" in the comment above. */ 998 /* Event "B" in the comment above. */
967 if (after(end_seq, tp->high_seq)) 999 if (after(end_seq, tp->high_seq))
968 flag |= FLAG_DATA_LOST; 1000 flag |= FLAG_DATA_LOST;
969 1001
970 sk_stream_for_retrans_queue(skb, sk) { 1002 sk_stream_for_retrans_queue_from(skb, sk) {
971 int in_sack, pcount; 1003 int in_sack, pcount;
972 u8 sacked; 1004 u8 sacked;
973 1005
1006 tp->fastpath_skb_hint = skb;
1007 tp->fastpath_cnt_hint = fack_count;
1008
974 /* The retransmission queue is always in order, so 1009 /* The retransmission queue is always in order, so
975 * we can short-circuit the walk early. 1010 * we can short-circuit the walk early.
976 */ 1011 */
@@ -1045,6 +1080,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1045 TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); 1080 TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
1046 tp->lost_out -= tcp_skb_pcount(skb); 1081 tp->lost_out -= tcp_skb_pcount(skb);
1047 tp->retrans_out -= tcp_skb_pcount(skb); 1082 tp->retrans_out -= tcp_skb_pcount(skb);
1083
1084 /* clear lost hint */
1085 tp->retransmit_skb_hint = NULL;
1048 } 1086 }
1049 } else { 1087 } else {
1050 /* New sack for not retransmitted frame, 1088 /* New sack for not retransmitted frame,
@@ -1057,6 +1095,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1057 if (sacked & TCPCB_LOST) { 1095 if (sacked & TCPCB_LOST) {
1058 TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; 1096 TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
1059 tp->lost_out -= tcp_skb_pcount(skb); 1097 tp->lost_out -= tcp_skb_pcount(skb);
1098
1099 /* clear lost hint */
1100 tp->retransmit_skb_hint = NULL;
1060 } 1101 }
1061 } 1102 }
1062 1103
@@ -1080,6 +1121,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1080 (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS)) { 1121 (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS)) {
1081 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; 1122 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
1082 tp->retrans_out -= tcp_skb_pcount(skb); 1123 tp->retrans_out -= tcp_skb_pcount(skb);
1124 tp->retransmit_skb_hint = NULL;
1083 } 1125 }
1084 } 1126 }
1085 } 1127 }
@@ -1107,6 +1149,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1107 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; 1149 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
1108 tp->retrans_out -= tcp_skb_pcount(skb); 1150 tp->retrans_out -= tcp_skb_pcount(skb);
1109 1151
1152 /* clear lost hint */
1153 tp->retransmit_skb_hint = NULL;
1154
1110 if (!(TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_SACKED_ACKED))) { 1155 if (!(TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_SACKED_ACKED))) {
1111 tp->lost_out += tcp_skb_pcount(skb); 1156 tp->lost_out += tcp_skb_pcount(skb);
1112 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 1157 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
@@ -1214,6 +1259,8 @@ static void tcp_enter_frto_loss(struct sock *sk)
1214 tcp_set_ca_state(sk, TCP_CA_Loss); 1259 tcp_set_ca_state(sk, TCP_CA_Loss);
1215 tp->high_seq = tp->frto_highmark; 1260 tp->high_seq = tp->frto_highmark;
1216 TCP_ECN_queue_cwr(tp); 1261 TCP_ECN_queue_cwr(tp);
1262
1263 clear_all_retrans_hints(tp);
1217} 1264}
1218 1265
1219void tcp_clear_retrans(struct tcp_sock *tp) 1266void tcp_clear_retrans(struct tcp_sock *tp)
@@ -1251,6 +1298,7 @@ void tcp_enter_loss(struct sock *sk, int how)
1251 tp->snd_cwnd_cnt = 0; 1298 tp->snd_cwnd_cnt = 0;
1252 tp->snd_cwnd_stamp = tcp_time_stamp; 1299 tp->snd_cwnd_stamp = tcp_time_stamp;
1253 1300
1301 tp->bytes_acked = 0;
1254 tcp_clear_retrans(tp); 1302 tcp_clear_retrans(tp);
1255 1303
1256 /* Push undo marker, if it was plain RTO and nothing 1304 /* Push undo marker, if it was plain RTO and nothing
@@ -1279,6 +1327,8 @@ void tcp_enter_loss(struct sock *sk, int how)
1279 tcp_set_ca_state(sk, TCP_CA_Loss); 1327 tcp_set_ca_state(sk, TCP_CA_Loss);
1280 tp->high_seq = tp->snd_nxt; 1328 tp->high_seq = tp->snd_nxt;
1281 TCP_ECN_queue_cwr(tp); 1329 TCP_ECN_queue_cwr(tp);
1330
1331 clear_all_retrans_hints(tp);
1282} 1332}
1283 1333
1284static int tcp_check_sack_reneging(struct sock *sk) 1334static int tcp_check_sack_reneging(struct sock *sk)
@@ -1503,17 +1553,37 @@ static void tcp_mark_head_lost(struct sock *sk, struct tcp_sock *tp,
1503 int packets, u32 high_seq) 1553 int packets, u32 high_seq)
1504{ 1554{
1505 struct sk_buff *skb; 1555 struct sk_buff *skb;
1506 int cnt = packets; 1556 int cnt;
1507 1557
1508 BUG_TRAP(cnt <= tp->packets_out); 1558 BUG_TRAP(packets <= tp->packets_out);
1559 if (tp->lost_skb_hint) {
1560 skb = tp->lost_skb_hint;
1561 cnt = tp->lost_cnt_hint;
1562 } else {
1563 skb = sk->sk_write_queue.next;
1564 cnt = 0;
1565 }
1509 1566
1510 sk_stream_for_retrans_queue(skb, sk) { 1567 sk_stream_for_retrans_queue_from(skb, sk) {
1511 cnt -= tcp_skb_pcount(skb); 1568 /* TODO: do this better */
1512 if (cnt < 0 || after(TCP_SKB_CB(skb)->end_seq, high_seq)) 1569 /* this is not the most efficient way to do this... */
1570 tp->lost_skb_hint = skb;
1571 tp->lost_cnt_hint = cnt;
1572 cnt += tcp_skb_pcount(skb);
1573 if (cnt > packets || after(TCP_SKB_CB(skb)->end_seq, high_seq))
1513 break; 1574 break;
1514 if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { 1575 if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
1515 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 1576 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1516 tp->lost_out += tcp_skb_pcount(skb); 1577 tp->lost_out += tcp_skb_pcount(skb);
1578
1579 /* clear xmit_retransmit_queue hints
1580 * if this is beyond hint */
1581 if(tp->retransmit_skb_hint != NULL &&
1582 before(TCP_SKB_CB(skb)->seq,
1583 TCP_SKB_CB(tp->retransmit_skb_hint)->seq)) {
1584
1585 tp->retransmit_skb_hint = NULL;
1586 }
1517 } 1587 }
1518 } 1588 }
1519 tcp_sync_left_out(tp); 1589 tcp_sync_left_out(tp);
@@ -1540,13 +1610,28 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp)
1540 if (tcp_head_timedout(sk, tp)) { 1610 if (tcp_head_timedout(sk, tp)) {
1541 struct sk_buff *skb; 1611 struct sk_buff *skb;
1542 1612
1543 sk_stream_for_retrans_queue(skb, sk) { 1613 skb = tp->scoreboard_skb_hint ? tp->scoreboard_skb_hint
1544 if (tcp_skb_timedout(sk, skb) && 1614 : sk->sk_write_queue.next;
1545 !(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { 1615
1616 sk_stream_for_retrans_queue_from(skb, sk) {
1617 if (!tcp_skb_timedout(sk, skb))
1618 break;
1619
1620 if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
1546 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 1621 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1547 tp->lost_out += tcp_skb_pcount(skb); 1622 tp->lost_out += tcp_skb_pcount(skb);
1623
1624 /* clear xmit_retrans hint */
1625 if (tp->retransmit_skb_hint &&
1626 before(TCP_SKB_CB(skb)->seq,
1627 TCP_SKB_CB(tp->retransmit_skb_hint)->seq))
1628
1629 tp->retransmit_skb_hint = NULL;
1548 } 1630 }
1549 } 1631 }
1632
1633 tp->scoreboard_skb_hint = skb;
1634
1550 tcp_sync_left_out(tp); 1635 tcp_sync_left_out(tp);
1551 } 1636 }
1552} 1637}
@@ -1626,6 +1711,10 @@ static void tcp_undo_cwr(struct sock *sk, const int undo)
1626 } 1711 }
1627 tcp_moderate_cwnd(tp); 1712 tcp_moderate_cwnd(tp);
1628 tp->snd_cwnd_stamp = tcp_time_stamp; 1713 tp->snd_cwnd_stamp = tcp_time_stamp;
1714
1715 /* There is something screwy going on with the retrans hints after
1716 an undo */
1717 clear_all_retrans_hints(tp);
1629} 1718}
1630 1719
1631static inline int tcp_may_undo(struct tcp_sock *tp) 1720static inline int tcp_may_undo(struct tcp_sock *tp)
@@ -1709,6 +1798,9 @@ static int tcp_try_undo_loss(struct sock *sk, struct tcp_sock *tp)
1709 sk_stream_for_retrans_queue(skb, sk) { 1798 sk_stream_for_retrans_queue(skb, sk) {
1710 TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; 1799 TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
1711 } 1800 }
1801
1802 clear_all_retrans_hints(tp);
1803
1712 DBGUNDO(sk, tp, "partial loss"); 1804 DBGUNDO(sk, tp, "partial loss");
1713 tp->lost_out = 0; 1805 tp->lost_out = 0;
1714 tp->left_out = tp->sacked_out; 1806 tp->left_out = tp->sacked_out;
@@ -1908,6 +2000,7 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
1908 TCP_ECN_queue_cwr(tp); 2000 TCP_ECN_queue_cwr(tp);
1909 } 2001 }
1910 2002
2003 tp->bytes_acked = 0;
1911 tp->snd_cwnd_cnt = 0; 2004 tp->snd_cwnd_cnt = 0;
1912 tcp_set_ca_state(sk, TCP_CA_Recovery); 2005 tcp_set_ca_state(sk, TCP_CA_Recovery);
1913 } 2006 }
@@ -1919,9 +2012,9 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
1919} 2012}
1920 2013
1921/* Read draft-ietf-tcplw-high-performance before mucking 2014/* Read draft-ietf-tcplw-high-performance before mucking
1922 * with this code. (Superceeds RFC1323) 2015 * with this code. (Supersedes RFC1323)
1923 */ 2016 */
1924static void tcp_ack_saw_tstamp(struct sock *sk, u32 *usrtt, int flag) 2017static void tcp_ack_saw_tstamp(struct sock *sk, int flag)
1925{ 2018{
1926 /* RTTM Rule: A TSecr value received in a segment is used to 2019 /* RTTM Rule: A TSecr value received in a segment is used to
1927 * update the averaged RTT measurement only if the segment 2020 * update the averaged RTT measurement only if the segment
@@ -1932,7 +2025,7 @@ static void tcp_ack_saw_tstamp(struct sock *sk, u32 *usrtt, int flag)
1932 * 1998/04/10 Andrey V. Savochkin <saw@msu.ru> 2025 * 1998/04/10 Andrey V. Savochkin <saw@msu.ru>
1933 * 2026 *
1934 * Changed: reset backoff as soon as we see the first valid sample. 2027 * Changed: reset backoff as soon as we see the first valid sample.
1935 * If we do not, we get strongly overstimated rto. With timestamps 2028 * If we do not, we get strongly overestimated rto. With timestamps
1936 * samples are accepted even from very old segments: f.e., when rtt=1 2029 * samples are accepted even from very old segments: f.e., when rtt=1
1937 * increases to 8, we retransmit 5 times and after 8 seconds delayed 2030 * increases to 8, we retransmit 5 times and after 8 seconds delayed
1938 * answer arrives rto becomes 120 seconds! If at least one of segments 2031 * answer arrives rto becomes 120 seconds! If at least one of segments
@@ -1940,13 +2033,13 @@ static void tcp_ack_saw_tstamp(struct sock *sk, u32 *usrtt, int flag)
1940 */ 2033 */
1941 struct tcp_sock *tp = tcp_sk(sk); 2034 struct tcp_sock *tp = tcp_sk(sk);
1942 const __u32 seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr; 2035 const __u32 seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
1943 tcp_rtt_estimator(sk, seq_rtt, usrtt); 2036 tcp_rtt_estimator(sk, seq_rtt);
1944 tcp_set_rto(sk); 2037 tcp_set_rto(sk);
1945 inet_csk(sk)->icsk_backoff = 0; 2038 inet_csk(sk)->icsk_backoff = 0;
1946 tcp_bound_rto(sk); 2039 tcp_bound_rto(sk);
1947} 2040}
1948 2041
1949static void tcp_ack_no_tstamp(struct sock *sk, u32 seq_rtt, u32 *usrtt, int flag) 2042static void tcp_ack_no_tstamp(struct sock *sk, u32 seq_rtt, int flag)
1950{ 2043{
1951 /* We don't have a timestamp. Can only use 2044 /* We don't have a timestamp. Can only use
1952 * packets that are not retransmitted to determine 2045 * packets that are not retransmitted to determine
@@ -1960,21 +2053,21 @@ static void tcp_ack_no_tstamp(struct sock *sk, u32 seq_rtt, u32 *usrtt, int flag
1960 if (flag & FLAG_RETRANS_DATA_ACKED) 2053 if (flag & FLAG_RETRANS_DATA_ACKED)
1961 return; 2054 return;
1962 2055
1963 tcp_rtt_estimator(sk, seq_rtt, usrtt); 2056 tcp_rtt_estimator(sk, seq_rtt);
1964 tcp_set_rto(sk); 2057 tcp_set_rto(sk);
1965 inet_csk(sk)->icsk_backoff = 0; 2058 inet_csk(sk)->icsk_backoff = 0;
1966 tcp_bound_rto(sk); 2059 tcp_bound_rto(sk);
1967} 2060}
1968 2061
1969static inline void tcp_ack_update_rtt(struct sock *sk, const int flag, 2062static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
1970 const s32 seq_rtt, u32 *usrtt) 2063 const s32 seq_rtt)
1971{ 2064{
1972 const struct tcp_sock *tp = tcp_sk(sk); 2065 const struct tcp_sock *tp = tcp_sk(sk);
1973 /* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */ 2066 /* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */
1974 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) 2067 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
1975 tcp_ack_saw_tstamp(sk, usrtt, flag); 2068 tcp_ack_saw_tstamp(sk, flag);
1976 else if (seq_rtt >= 0) 2069 else if (seq_rtt >= 0)
1977 tcp_ack_no_tstamp(sk, seq_rtt, usrtt, flag); 2070 tcp_ack_no_tstamp(sk, seq_rtt, flag);
1978} 2071}
1979 2072
1980static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt, 2073static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
@@ -2054,20 +2147,27 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
2054 return acked; 2147 return acked;
2055} 2148}
2056 2149
2150static inline u32 tcp_usrtt(const struct sk_buff *skb)
2151{
2152 struct timeval tv, now;
2153
2154 do_gettimeofday(&now);
2155 skb_get_timestamp(skb, &tv);
2156 return (now.tv_sec - tv.tv_sec) * 1000000 + (now.tv_usec - tv.tv_usec);
2157}
2057 2158
2058/* Remove acknowledged frames from the retransmission queue. */ 2159/* Remove acknowledged frames from the retransmission queue. */
2059static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt) 2160static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2060{ 2161{
2061 struct tcp_sock *tp = tcp_sk(sk); 2162 struct tcp_sock *tp = tcp_sk(sk);
2163 const struct inet_connection_sock *icsk = inet_csk(sk);
2062 struct sk_buff *skb; 2164 struct sk_buff *skb;
2063 __u32 now = tcp_time_stamp; 2165 __u32 now = tcp_time_stamp;
2064 int acked = 0; 2166 int acked = 0;
2065 __s32 seq_rtt = -1; 2167 __s32 seq_rtt = -1;
2066 struct timeval usnow;
2067 u32 pkts_acked = 0; 2168 u32 pkts_acked = 0;
2068 2169 void (*rtt_sample)(struct sock *sk, u32 usrtt)
2069 if (seq_usrtt) 2170 = icsk->icsk_ca_ops->rtt_sample;
2070 do_gettimeofday(&usnow);
2071 2171
2072 while ((skb = skb_peek(&sk->sk_write_queue)) && 2172 while ((skb = skb_peek(&sk->sk_write_queue)) &&
2073 skb != sk->sk_send_head) { 2173 skb != sk->sk_send_head) {
@@ -2107,16 +2207,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt
2107 tp->retrans_out -= tcp_skb_pcount(skb); 2207 tp->retrans_out -= tcp_skb_pcount(skb);
2108 acked |= FLAG_RETRANS_DATA_ACKED; 2208 acked |= FLAG_RETRANS_DATA_ACKED;
2109 seq_rtt = -1; 2209 seq_rtt = -1;
2110 } else if (seq_rtt < 0) 2210 } else if (seq_rtt < 0) {
2111 seq_rtt = now - scb->when; 2211 seq_rtt = now - scb->when;
2112 if (seq_usrtt) { 2212 if (rtt_sample)
2113 struct timeval tv; 2213 (*rtt_sample)(sk, tcp_usrtt(skb));
2114
2115 skb_get_timestamp(skb, &tv);
2116 *seq_usrtt = (usnow.tv_sec - tv.tv_sec) * 1000000
2117 + (usnow.tv_usec - tv.tv_usec);
2118 } 2214 }
2119
2120 if (sacked & TCPCB_SACKED_ACKED) 2215 if (sacked & TCPCB_SACKED_ACKED)
2121 tp->sacked_out -= tcp_skb_pcount(skb); 2216 tp->sacked_out -= tcp_skb_pcount(skb);
2122 if (sacked & TCPCB_LOST) 2217 if (sacked & TCPCB_LOST)
@@ -2126,17 +2221,20 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt
2126 !before(scb->end_seq, tp->snd_up)) 2221 !before(scb->end_seq, tp->snd_up))
2127 tp->urg_mode = 0; 2222 tp->urg_mode = 0;
2128 } 2223 }
2129 } else if (seq_rtt < 0) 2224 } else if (seq_rtt < 0) {
2130 seq_rtt = now - scb->when; 2225 seq_rtt = now - scb->when;
2226 if (rtt_sample)
2227 (*rtt_sample)(sk, tcp_usrtt(skb));
2228 }
2131 tcp_dec_pcount_approx(&tp->fackets_out, skb); 2229 tcp_dec_pcount_approx(&tp->fackets_out, skb);
2132 tcp_packets_out_dec(tp, skb); 2230 tcp_packets_out_dec(tp, skb);
2133 __skb_unlink(skb, &sk->sk_write_queue); 2231 __skb_unlink(skb, &sk->sk_write_queue);
2134 sk_stream_free_skb(sk, skb); 2232 sk_stream_free_skb(sk, skb);
2233 clear_all_retrans_hints(tp);
2135 } 2234 }
2136 2235
2137 if (acked&FLAG_ACKED) { 2236 if (acked&FLAG_ACKED) {
2138 const struct inet_connection_sock *icsk = inet_csk(sk); 2237 tcp_ack_update_rtt(sk, acked, seq_rtt);
2139 tcp_ack_update_rtt(sk, acked, seq_rtt, seq_usrtt);
2140 tcp_ack_packets_out(sk, tp); 2238 tcp_ack_packets_out(sk, tp);
2141 2239
2142 if (icsk->icsk_ca_ops->pkts_acked) 2240 if (icsk->icsk_ca_ops->pkts_acked)
@@ -2284,7 +2382,7 @@ static void tcp_process_frto(struct sock *sk, u32 prior_snd_una)
2284 } 2382 }
2285 2383
2286 /* F-RTO affects on two new ACKs following RTO. 2384 /* F-RTO affects on two new ACKs following RTO.
2287 * At latest on third ACK the TCP behavor is back to normal. 2385 * At latest on third ACK the TCP behavior is back to normal.
2288 */ 2386 */
2289 tp->frto_counter = (tp->frto_counter + 1) % 3; 2387 tp->frto_counter = (tp->frto_counter + 1) % 3;
2290} 2388}
@@ -2299,7 +2397,6 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2299 u32 ack = TCP_SKB_CB(skb)->ack_seq; 2397 u32 ack = TCP_SKB_CB(skb)->ack_seq;
2300 u32 prior_in_flight; 2398 u32 prior_in_flight;
2301 s32 seq_rtt; 2399 s32 seq_rtt;
2302 s32 seq_usrtt = 0;
2303 int prior_packets; 2400 int prior_packets;
2304 2401
2305 /* If the ack is newer than sent or older than previous acks 2402 /* If the ack is newer than sent or older than previous acks
@@ -2311,6 +2408,9 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2311 if (before(ack, prior_snd_una)) 2408 if (before(ack, prior_snd_una))
2312 goto old_ack; 2409 goto old_ack;
2313 2410
2411 if (sysctl_tcp_abc && icsk->icsk_ca_state < TCP_CA_CWR)
2412 tp->bytes_acked += ack - prior_snd_una;
2413
2314 if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { 2414 if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
2315 /* Window is constant, pure forward advance. 2415 /* Window is constant, pure forward advance.
2316 * No more checks are required. 2416 * No more checks are required.
@@ -2352,14 +2452,13 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2352 prior_in_flight = tcp_packets_in_flight(tp); 2452 prior_in_flight = tcp_packets_in_flight(tp);
2353 2453
2354 /* See if we can take anything off of the retransmit queue. */ 2454 /* See if we can take anything off of the retransmit queue. */
2355 flag |= tcp_clean_rtx_queue(sk, &seq_rtt, 2455 flag |= tcp_clean_rtx_queue(sk, &seq_rtt);
2356 icsk->icsk_ca_ops->rtt_sample ? &seq_usrtt : NULL);
2357 2456
2358 if (tp->frto_counter) 2457 if (tp->frto_counter)
2359 tcp_process_frto(sk, prior_snd_una); 2458 tcp_process_frto(sk, prior_snd_una);
2360 2459
2361 if (tcp_ack_is_dubious(sk, flag)) { 2460 if (tcp_ack_is_dubious(sk, flag)) {
2362 /* Advanve CWND, if state allows this. */ 2461 /* Advance CWND, if state allows this. */
2363 if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag)) 2462 if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag))
2364 tcp_cong_avoid(sk, ack, seq_rtt, prior_in_flight, 0); 2463 tcp_cong_avoid(sk, ack, seq_rtt, prior_in_flight, 0);
2365 tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag); 2464 tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag);
@@ -3148,7 +3247,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
3148{ 3247{
3149 struct sk_buff *skb; 3248 struct sk_buff *skb;
3150 3249
3151 /* First, check that queue is collapsable and find 3250 /* First, check that queue is collapsible and find
3152 * the point where collapsing can be useful. */ 3251 * the point where collapsing can be useful. */
3153 for (skb = head; skb != tail; ) { 3252 for (skb = head; skb != tail; ) {
3154 /* No new bits? It is possible on ofo queue. */ 3253 /* No new bits? It is possible on ofo queue. */
@@ -3456,7 +3555,7 @@ static __inline__ void tcp_ack_snd_check(struct sock *sk)
3456 3555
3457/* 3556/*
3458 * This routine is only called when we have urgent data 3557 * This routine is only called when we have urgent data
3459 * signalled. Its the 'slow' part of tcp_urg. It could be 3558 * signaled. Its the 'slow' part of tcp_urg. It could be
3460 * moved inline now as tcp_urg is only called from one 3559 * moved inline now as tcp_urg is only called from one
3461 * place. We handle URGent data wrong. We have to - as 3560 * place. We handle URGent data wrong. We have to - as
3462 * BSD still doesn't use the correction from RFC961. 3561 * BSD still doesn't use the correction from RFC961.
@@ -3501,7 +3600,7 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
3501 * urgent. To do this requires some care. We cannot just ignore 3600 * urgent. To do this requires some care. We cannot just ignore
3502 * tp->copied_seq since we would read the last urgent byte again 3601 * tp->copied_seq since we would read the last urgent byte again
3503 * as data, nor can we alter copied_seq until this data arrives 3602 * as data, nor can we alter copied_seq until this data arrives
3504 * or we break the sematics of SIOCATMARK (and thus sockatmark()) 3603 * or we break the semantics of SIOCATMARK (and thus sockatmark())
3505 * 3604 *
3506 * NOTE. Double Dutch. Rendering to plain English: author of comment 3605 * NOTE. Double Dutch. Rendering to plain English: author of comment
3507 * above did something sort of send("A", MSG_OOB); send("B", MSG_OOB); 3606 * above did something sort of send("A", MSG_OOB); send("B", MSG_OOB);
@@ -3646,7 +3745,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
3646 tp->rx_opt.saw_tstamp = 0; 3745 tp->rx_opt.saw_tstamp = 0;
3647 3746
3648 /* pred_flags is 0xS?10 << 16 + snd_wnd 3747 /* pred_flags is 0xS?10 << 16 + snd_wnd
3649 * if header_predition is to be made 3748 * if header_prediction is to be made
3650 * 'S' will always be tp->tcp_header_len >> 2 3749 * 'S' will always be tp->tcp_header_len >> 2
3651 * '?' will be 0 for the fast path, otherwise pred_flags is 0 to 3750 * '?' will be 0 for the fast path, otherwise pred_flags is 0 to
3652 * turn it off (when there are holes in the receive 3751 * turn it off (when there are holes in the receive
@@ -4242,7 +4341,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
4242 */ 4341 */
4243 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr && 4342 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
4244 !tp->srtt) 4343 !tp->srtt)
4245 tcp_ack_saw_tstamp(sk, NULL, 0); 4344 tcp_ack_saw_tstamp(sk, 0);
4246 4345
4247 if (tp->rx_opt.tstamp_ok) 4346 if (tp->rx_opt.tstamp_ok)
4248 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; 4347 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
@@ -4372,6 +4471,7 @@ discard:
4372 4471
4373EXPORT_SYMBOL(sysctl_tcp_ecn); 4472EXPORT_SYMBOL(sysctl_tcp_ecn);
4374EXPORT_SYMBOL(sysctl_tcp_reordering); 4473EXPORT_SYMBOL(sysctl_tcp_reordering);
4474EXPORT_SYMBOL(sysctl_tcp_abc);
4375EXPORT_SYMBOL(tcp_parse_options); 4475EXPORT_SYMBOL(tcp_parse_options);
4376EXPORT_SYMBOL(tcp_rcv_established); 4476EXPORT_SYMBOL(tcp_rcv_established);
4377EXPORT_SYMBOL(tcp_rcv_state_process); 4477EXPORT_SYMBOL(tcp_rcv_state_process);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 634dabb558fd..4d5021e1929b 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -39,7 +39,7 @@
39 * request_sock handling and moved 39 * request_sock handling and moved
40 * most of it into the af independent code. 40 * most of it into the af independent code.
41 * Added tail drop and some other bugfixes. 41 * Added tail drop and some other bugfixes.
42 * Added new listen sematics. 42 * Added new listen semantics.
43 * Mike McLagan : Routing by source 43 * Mike McLagan : Routing by source
44 * Juan Jose Ciarlante: ip_dynaddr bits 44 * Juan Jose Ciarlante: ip_dynaddr bits
45 * Andi Kleen: various fixes. 45 * Andi Kleen: various fixes.
@@ -1110,24 +1110,18 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
1110static int tcp_v4_checksum_init(struct sk_buff *skb) 1110static int tcp_v4_checksum_init(struct sk_buff *skb)
1111{ 1111{
1112 if (skb->ip_summed == CHECKSUM_HW) { 1112 if (skb->ip_summed == CHECKSUM_HW) {
1113 skb->ip_summed = CHECKSUM_UNNECESSARY;
1114 if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr, 1113 if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr,
1115 skb->nh.iph->daddr, skb->csum)) 1114 skb->nh.iph->daddr, skb->csum)) {
1115 skb->ip_summed = CHECKSUM_UNNECESSARY;
1116 return 0; 1116 return 0;
1117 1117 }
1118 LIMIT_NETDEBUG(KERN_DEBUG "hw tcp v4 csum failed\n");
1119 skb->ip_summed = CHECKSUM_NONE;
1120 } 1118 }
1119
1120 skb->csum = csum_tcpudp_nofold(skb->nh.iph->saddr, skb->nh.iph->daddr,
1121 skb->len, IPPROTO_TCP, 0);
1122
1121 if (skb->len <= 76) { 1123 if (skb->len <= 76) {
1122 if (tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr, 1124 return __skb_checksum_complete(skb);
1123 skb->nh.iph->daddr,
1124 skb_checksum(skb, 0, skb->len, 0)))
1125 return -1;
1126 skb->ip_summed = CHECKSUM_UNNECESSARY;
1127 } else {
1128 skb->csum = ~tcp_v4_check(skb->h.th, skb->len,
1129 skb->nh.iph->saddr,
1130 skb->nh.iph->daddr, 0);
1131 } 1125 }
1132 return 0; 1126 return 0;
1133} 1127}
@@ -1216,10 +1210,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
1216 1210
1217 /* An explanation is required here, I think. 1211 /* An explanation is required here, I think.
1218 * Packet length and doff are validated by header prediction, 1212 * Packet length and doff are validated by header prediction,
1219 * provided case of th->doff==0 is elimineted. 1213 * provided case of th->doff==0 is eliminated.
1220 * So, we defer the checks. */ 1214 * So, we defer the checks. */
1221 if ((skb->ip_summed != CHECKSUM_UNNECESSARY && 1215 if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
1222 tcp_v4_checksum_init(skb) < 0)) 1216 tcp_v4_checksum_init(skb)))
1223 goto bad_packet; 1217 goto bad_packet;
1224 1218
1225 th = skb->h.th; 1219 th = skb->h.th;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index b1a63b2c6b4a..1b66a2ac4321 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -158,7 +158,7 @@ kill_with_rst:
158 /* I am shamed, but failed to make it more elegant. 158 /* I am shamed, but failed to make it more elegant.
159 * Yes, it is direct reference to IP, which is impossible 159 * Yes, it is direct reference to IP, which is impossible
160 * to generalize to IPv6. Taking into account that IPv6 160 * to generalize to IPv6. Taking into account that IPv6
161 * do not undertsnad recycling in any case, it not 161 * do not understand recycling in any case, it not
162 * a big problem in practice. --ANK */ 162 * a big problem in practice. --ANK */
163 if (tw->tw_family == AF_INET && 163 if (tw->tw_family == AF_INET &&
164 tcp_death_row.sysctl_tw_recycle && tcptw->tw_ts_recent_stamp && 164 tcp_death_row.sysctl_tw_recycle && tcptw->tw_ts_recent_stamp &&
@@ -194,7 +194,7 @@ kill_with_rst:
194 /* In window segment, it may be only reset or bare ack. */ 194 /* In window segment, it may be only reset or bare ack. */
195 195
196 if (th->rst) { 196 if (th->rst) {
197 /* This is TIME_WAIT assasination, in two flavors. 197 /* This is TIME_WAIT assassination, in two flavors.
198 * Oh well... nobody has a sufficient solution to this 198 * Oh well... nobody has a sufficient solution to this
199 * protocol bug yet. 199 * protocol bug yet.
200 */ 200 */
@@ -380,6 +380,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
380 */ 380 */
381 newtp->snd_cwnd = 2; 381 newtp->snd_cwnd = 2;
382 newtp->snd_cwnd_cnt = 0; 382 newtp->snd_cwnd_cnt = 0;
383 newtp->bytes_acked = 0;
383 384
384 newtp->frto_counter = 0; 385 newtp->frto_counter = 0;
385 newtp->frto_highmark = 0; 386 newtp->frto_highmark = 0;
@@ -550,7 +551,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
550 551
551 /* RFC793 page 36: "If the connection is in any non-synchronized state ... 552 /* RFC793 page 36: "If the connection is in any non-synchronized state ...
552 * and the incoming segment acknowledges something not yet 553 * and the incoming segment acknowledges something not yet
553 * sent (the segment carries an unaccaptable ACK) ... 554 * sent (the segment carries an unacceptable ACK) ...
554 * a reset is sent." 555 * a reset is sent."
555 * 556 *
556 * Invalid ACK: reset will be sent by listening socket 557 * Invalid ACK: reset will be sent by listening socket
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index b907456a79f4..029c70dfb585 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -436,6 +436,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
436 u16 flags; 436 u16 flags;
437 437
438 BUG_ON(len > skb->len); 438 BUG_ON(len > skb->len);
439
440 clear_all_retrans_hints(tp);
439 nsize = skb_headlen(skb) - len; 441 nsize = skb_headlen(skb) - len;
440 if (nsize < 0) 442 if (nsize < 0)
441 nsize = 0; 443 nsize = 0;
@@ -599,7 +601,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
599 for TCP options, but includes only bare TCP header. 601 for TCP options, but includes only bare TCP header.
600 602
601 tp->rx_opt.mss_clamp is mss negotiated at connection setup. 603 tp->rx_opt.mss_clamp is mss negotiated at connection setup.
602 It is minumum of user_mss and mss received with SYN. 604 It is minimum of user_mss and mss received with SYN.
603 It also does not include TCP options. 605 It also does not include TCP options.
604 606
605 tp->pmtu_cookie is last pmtu, seen by this function. 607 tp->pmtu_cookie is last pmtu, seen by this function.
@@ -1171,7 +1173,7 @@ u32 __tcp_select_window(struct sock *sk)
1171{ 1173{
1172 struct inet_connection_sock *icsk = inet_csk(sk); 1174 struct inet_connection_sock *icsk = inet_csk(sk);
1173 struct tcp_sock *tp = tcp_sk(sk); 1175 struct tcp_sock *tp = tcp_sk(sk);
1174 /* MSS for the peer's data. Previous verions used mss_clamp 1176 /* MSS for the peer's data. Previous versions used mss_clamp
1175 * here. I don't know if the value based on our guesses 1177 * here. I don't know if the value based on our guesses
1176 * of peer's MSS is better for the performance. It's more correct 1178 * of peer's MSS is better for the performance. It's more correct
1177 * but may be worse for the performance because of rcv_mss 1179 * but may be worse for the performance because of rcv_mss
@@ -1260,7 +1262,10 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
1260 BUG_ON(tcp_skb_pcount(skb) != 1 || 1262 BUG_ON(tcp_skb_pcount(skb) != 1 ||
1261 tcp_skb_pcount(next_skb) != 1); 1263 tcp_skb_pcount(next_skb) != 1);
1262 1264
1263 /* Ok. We will be able to collapse the packet. */ 1265 /* changing transmit queue under us so clear hints */
1266 clear_all_retrans_hints(tp);
1267
1268 /* Ok. We will be able to collapse the packet. */
1264 __skb_unlink(next_skb, &sk->sk_write_queue); 1269 __skb_unlink(next_skb, &sk->sk_write_queue);
1265 1270
1266 memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size); 1271 memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size);
@@ -1330,6 +1335,8 @@ void tcp_simple_retransmit(struct sock *sk)
1330 } 1335 }
1331 } 1336 }
1332 1337
1338 clear_all_retrans_hints(tp);
1339
1333 if (!lost) 1340 if (!lost)
1334 return; 1341 return;
1335 1342
@@ -1361,7 +1368,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
1361 int err; 1368 int err;
1362 1369
1363 /* Do not sent more than we queued. 1/4 is reserved for possible 1370 /* Do not sent more than we queued. 1/4 is reserved for possible
1364 * copying overhead: frgagmentation, tunneling, mangling etc. 1371 * copying overhead: fragmentation, tunneling, mangling etc.
1365 */ 1372 */
1366 if (atomic_read(&sk->sk_wmem_alloc) > 1373 if (atomic_read(&sk->sk_wmem_alloc) >
1367 min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf)) 1374 min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
@@ -1468,13 +1475,25 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
1468 const struct inet_connection_sock *icsk = inet_csk(sk); 1475 const struct inet_connection_sock *icsk = inet_csk(sk);
1469 struct tcp_sock *tp = tcp_sk(sk); 1476 struct tcp_sock *tp = tcp_sk(sk);
1470 struct sk_buff *skb; 1477 struct sk_buff *skb;
1471 int packet_cnt = tp->lost_out; 1478 int packet_cnt;
1479
1480 if (tp->retransmit_skb_hint) {
1481 skb = tp->retransmit_skb_hint;
1482 packet_cnt = tp->retransmit_cnt_hint;
1483 }else{
1484 skb = sk->sk_write_queue.next;
1485 packet_cnt = 0;
1486 }
1472 1487
1473 /* First pass: retransmit lost packets. */ 1488 /* First pass: retransmit lost packets. */
1474 if (packet_cnt) { 1489 if (tp->lost_out) {
1475 sk_stream_for_retrans_queue(skb, sk) { 1490 sk_stream_for_retrans_queue_from(skb, sk) {
1476 __u8 sacked = TCP_SKB_CB(skb)->sacked; 1491 __u8 sacked = TCP_SKB_CB(skb)->sacked;
1477 1492
1493 /* we could do better than to assign each time */
1494 tp->retransmit_skb_hint = skb;
1495 tp->retransmit_cnt_hint = packet_cnt;
1496
1478 /* Assume this retransmit will generate 1497 /* Assume this retransmit will generate
1479 * only one packet for congestion window 1498 * only one packet for congestion window
1480 * calculation purposes. This works because 1499 * calculation purposes. This works because
@@ -1485,10 +1504,12 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
1485 if (tcp_packets_in_flight(tp) >= tp->snd_cwnd) 1504 if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
1486 return; 1505 return;
1487 1506
1488 if (sacked&TCPCB_LOST) { 1507 if (sacked & TCPCB_LOST) {
1489 if (!(sacked&(TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) { 1508 if (!(sacked&(TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) {
1490 if (tcp_retransmit_skb(sk, skb)) 1509 if (tcp_retransmit_skb(sk, skb)) {
1510 tp->retransmit_skb_hint = NULL;
1491 return; 1511 return;
1512 }
1492 if (icsk->icsk_ca_state != TCP_CA_Loss) 1513 if (icsk->icsk_ca_state != TCP_CA_Loss)
1493 NET_INC_STATS_BH(LINUX_MIB_TCPFASTRETRANS); 1514 NET_INC_STATS_BH(LINUX_MIB_TCPFASTRETRANS);
1494 else 1515 else
@@ -1501,8 +1522,8 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
1501 TCP_RTO_MAX); 1522 TCP_RTO_MAX);
1502 } 1523 }
1503 1524
1504 packet_cnt -= tcp_skb_pcount(skb); 1525 packet_cnt += tcp_skb_pcount(skb);
1505 if (packet_cnt <= 0) 1526 if (packet_cnt >= tp->lost_out)
1506 break; 1527 break;
1507 } 1528 }
1508 } 1529 }
@@ -1528,9 +1549,18 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
1528 if (tcp_may_send_now(sk, tp)) 1549 if (tcp_may_send_now(sk, tp))
1529 return; 1550 return;
1530 1551
1531 packet_cnt = 0; 1552 if (tp->forward_skb_hint) {
1553 skb = tp->forward_skb_hint;
1554 packet_cnt = tp->forward_cnt_hint;
1555 } else{
1556 skb = sk->sk_write_queue.next;
1557 packet_cnt = 0;
1558 }
1559
1560 sk_stream_for_retrans_queue_from(skb, sk) {
1561 tp->forward_cnt_hint = packet_cnt;
1562 tp->forward_skb_hint = skb;
1532 1563
1533 sk_stream_for_retrans_queue(skb, sk) {
1534 /* Similar to the retransmit loop above we 1564 /* Similar to the retransmit loop above we
1535 * can pretend that the retransmitted SKB 1565 * can pretend that the retransmitted SKB
1536 * we send out here will be composed of one 1566 * we send out here will be composed of one
@@ -1547,8 +1577,10 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
1547 continue; 1577 continue;
1548 1578
1549 /* Ok, retransmit it. */ 1579 /* Ok, retransmit it. */
1550 if (tcp_retransmit_skb(sk, skb)) 1580 if (tcp_retransmit_skb(sk, skb)) {
1581 tp->forward_skb_hint = NULL;
1551 break; 1582 break;
1583 }
1552 1584
1553 if (skb == skb_peek(&sk->sk_write_queue)) 1585 if (skb == skb_peek(&sk->sk_write_queue))
1554 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 1586 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
@@ -2058,3 +2090,4 @@ EXPORT_SYMBOL(tcp_connect);
2058EXPORT_SYMBOL(tcp_make_synack); 2090EXPORT_SYMBOL(tcp_make_synack);
2059EXPORT_SYMBOL(tcp_simple_retransmit); 2091EXPORT_SYMBOL(tcp_simple_retransmit);
2060EXPORT_SYMBOL(tcp_sync_mss); 2092EXPORT_SYMBOL(tcp_sync_mss);
2093EXPORT_SYMBOL(sysctl_tcp_tso_win_divisor);
diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c
index 327770bf5522..26d7486ee501 100644
--- a/net/ipv4/tcp_scalable.c
+++ b/net/ipv4/tcp_scalable.c
@@ -20,20 +20,20 @@ static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
20 u32 in_flight, int flag) 20 u32 in_flight, int flag)
21{ 21{
22 struct tcp_sock *tp = tcp_sk(sk); 22 struct tcp_sock *tp = tcp_sk(sk);
23 if (in_flight < tp->snd_cwnd) 23
24 if (!tcp_is_cwnd_limited(sk, in_flight))
24 return; 25 return;
25 26
26 if (tp->snd_cwnd <= tp->snd_ssthresh) { 27 if (tp->snd_cwnd <= tp->snd_ssthresh)
27 tp->snd_cwnd++; 28 tcp_slow_start(tp);
28 } else { 29 else {
29 tp->snd_cwnd_cnt++; 30 tp->snd_cwnd_cnt++;
30 if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)){ 31 if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)){
31 tp->snd_cwnd++; 32 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
33 tp->snd_cwnd++;
32 tp->snd_cwnd_cnt = 0; 34 tp->snd_cwnd_cnt = 0;
33 } 35 }
34 } 36 }
35 tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
36 tp->snd_cwnd_stamp = tcp_time_stamp;
37} 37}
38 38
39static u32 tcp_scalable_ssthresh(struct sock *sk) 39static u32 tcp_scalable_ssthresh(struct sock *sk)
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 415ee47ac1c5..e1880959614a 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -58,7 +58,7 @@ static void tcp_write_err(struct sock *sk)
58 * to prevent DoS attacks. It is called when a retransmission timeout 58 * to prevent DoS attacks. It is called when a retransmission timeout
59 * or zero probe timeout occurs on orphaned socket. 59 * or zero probe timeout occurs on orphaned socket.
60 * 60 *
61 * Criterium is still not confirmed experimentally and may change. 61 * Criteria is still not confirmed experimentally and may change.
62 * We kill the socket, if: 62 * We kill the socket, if:
63 * 1. If number of orphaned sockets exceeds an administratively configured 63 * 1. If number of orphaned sockets exceeds an administratively configured
64 * limit. 64 * limit.
@@ -132,7 +132,7 @@ static int tcp_write_timeout(struct sock *sk)
132 hole detection. :-( 132 hole detection. :-(
133 133
134 It is place to make it. It is not made. I do not want 134 It is place to make it. It is not made. I do not want
135 to make it. It is disguisting. It does not work in any 135 to make it. It is disgusting. It does not work in any
136 case. Let me to cite the same draft, which requires for 136 case. Let me to cite the same draft, which requires for
137 us to implement this: 137 us to implement this:
138 138
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index 93c5f92070f9..b7d296a8ac6d 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -236,8 +236,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
236 /* We don't have enough RTT samples to do the Vegas 236 /* We don't have enough RTT samples to do the Vegas
237 * calculation, so we'll behave like Reno. 237 * calculation, so we'll behave like Reno.
238 */ 238 */
239 if (tp->snd_cwnd > tp->snd_ssthresh) 239 tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, flag);
240 tp->snd_cwnd++;
241 } else { 240 } else {
242 u32 rtt, target_cwnd, diff; 241 u32 rtt, target_cwnd, diff;
243 242
@@ -275,7 +274,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
275 */ 274 */
276 diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd; 275 diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
277 276
278 if (tp->snd_cwnd < tp->snd_ssthresh) { 277 if (tp->snd_cwnd <= tp->snd_ssthresh) {
279 /* Slow start. */ 278 /* Slow start. */
280 if (diff > gamma) { 279 if (diff > gamma) {
281 /* Going too fast. Time to slow down 280 /* Going too fast. Time to slow down
@@ -295,6 +294,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
295 V_PARAM_SHIFT)+1); 294 V_PARAM_SHIFT)+1);
296 295
297 } 296 }
297 tcp_slow_start(tp);
298 } else { 298 } else {
299 /* Congestion avoidance. */ 299 /* Congestion avoidance. */
300 u32 next_snd_cwnd; 300 u32 next_snd_cwnd;
@@ -327,37 +327,17 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
327 else if (next_snd_cwnd < tp->snd_cwnd) 327 else if (next_snd_cwnd < tp->snd_cwnd)
328 tp->snd_cwnd--; 328 tp->snd_cwnd--;
329 } 329 }
330 }
331 330
332 /* Wipe the slate clean for the next RTT. */ 331 if (tp->snd_cwnd < 2)
333 vegas->cntRTT = 0; 332 tp->snd_cwnd = 2;
334 vegas->minRTT = 0x7fffffff; 333 else if (tp->snd_cwnd > tp->snd_cwnd_clamp)
334 tp->snd_cwnd = tp->snd_cwnd_clamp;
335 }
335 } 336 }
336 337
337 /* The following code is executed for every ack we receive, 338 /* Wipe the slate clean for the next RTT. */
338 * except for conditions checked in should_advance_cwnd() 339 vegas->cntRTT = 0;
339 * before the call to tcp_cong_avoid(). Mainly this means that 340 vegas->minRTT = 0x7fffffff;
340 * we only execute this code if the ack actually acked some
341 * data.
342 */
343
344 /* If we are in slow start, increase our cwnd in response to this ACK.
345 * (If we are not in slow start then we are in congestion avoidance,
346 * and adjust our congestion window only once per RTT. See the code
347 * above.)
348 */
349 if (tp->snd_cwnd <= tp->snd_ssthresh)
350 tp->snd_cwnd++;
351
352 /* to keep cwnd from growing without bound */
353 tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
354
355 /* Make sure that we are never so timid as to reduce our cwnd below
356 * 2 MSS.
357 *
358 * Going below 2 MSS would risk huge delayed ACKs from our receiver.
359 */
360 tp->snd_cwnd = max(tp->snd_cwnd, 2U);
361} 341}
362 342
363/* Extract info for Tcp socket info provided via netlink. */ 343/* Extract info for Tcp socket info provided via netlink. */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e0bd1013cb0d..2422a5f7195d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -761,7 +761,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
761 761
762static __inline__ int __udp_checksum_complete(struct sk_buff *skb) 762static __inline__ int __udp_checksum_complete(struct sk_buff *skb)
763{ 763{
764 return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); 764 return __skb_checksum_complete(skb);
765} 765}
766 766
767static __inline__ int udp_checksum_complete(struct sk_buff *skb) 767static __inline__ int udp_checksum_complete(struct sk_buff *skb)
@@ -1100,11 +1100,8 @@ static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
1100 if (uh->check == 0) { 1100 if (uh->check == 0) {
1101 skb->ip_summed = CHECKSUM_UNNECESSARY; 1101 skb->ip_summed = CHECKSUM_UNNECESSARY;
1102 } else if (skb->ip_summed == CHECKSUM_HW) { 1102 } else if (skb->ip_summed == CHECKSUM_HW) {
1103 skb->ip_summed = CHECKSUM_UNNECESSARY;
1104 if (!udp_check(uh, ulen, saddr, daddr, skb->csum)) 1103 if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
1105 return 0; 1104 skb->ip_summed = CHECKSUM_UNNECESSARY;
1106 LIMIT_NETDEBUG(KERN_DEBUG "udp v4 hw csum failure.\n");
1107 skb->ip_summed = CHECKSUM_NONE;
1108 } 1105 }
1109 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 1106 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
1110 skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); 1107 skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b7a5f51238b3..ddcf7754eec2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1022,6 +1022,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1022 continue; 1022 continue;
1023 } 1023 }
1024 1024
1025#ifdef CONFIG_IPV6_PRIVACY
1025 /* Rule 7: Prefer public address 1026 /* Rule 7: Prefer public address
1026 * Note: prefer temprary address if use_tempaddr >= 2 1027 * Note: prefer temprary address if use_tempaddr >= 2
1027 */ 1028 */
@@ -1042,7 +1043,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1042 if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY) 1043 if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
1043 continue; 1044 continue;
1044 } 1045 }
1045 1046#endif
1046 /* Rule 8: Use longest matching prefix */ 1047 /* Rule 8: Use longest matching prefix */
1047 if (hiscore.rule < 8) 1048 if (hiscore.rule < 8)
1048 hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr); 1049 hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 23e540365a14..1bdf0fb8bf8a 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -585,17 +585,16 @@ static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
585 daddr = &skb->nh.ipv6h->daddr; 585 daddr = &skb->nh.ipv6h->daddr;
586 586
587 /* Perform checksum. */ 587 /* Perform checksum. */
588 if (skb->ip_summed == CHECKSUM_HW) { 588 switch (skb->ip_summed) {
589 skb->ip_summed = CHECKSUM_UNNECESSARY; 589 case CHECKSUM_HW:
590 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 590 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
591 skb->csum)) { 591 skb->csum))
592 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 hw checksum failed\n"); 592 break;
593 skb->ip_summed = CHECKSUM_NONE; 593 /* fall through */
594 } 594 case CHECKSUM_NONE:
595 } 595 skb->csum = ~csum_ipv6_magic(saddr, daddr, skb->len,
596 if (skb->ip_summed == CHECKSUM_NONE) { 596 IPPROTO_ICMPV6, 0);
597 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 597 if (__skb_checksum_complete(skb)) {
598 skb_checksum(skb, 0, skb->len, 0))) {
599 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n", 598 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
600 NIP6(*saddr), NIP6(*daddr)); 599 NIP6(*saddr), NIP6(*daddr));
601 goto discard_it; 600 goto discard_it;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6e3480426939..a6026d2787d2 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -176,6 +176,11 @@ resubmit:
176 if (ipprot->flags & INET6_PROTO_FINAL) { 176 if (ipprot->flags & INET6_PROTO_FINAL) {
177 struct ipv6hdr *hdr; 177 struct ipv6hdr *hdr;
178 178
179 /* Free reference early: we don't need it any more,
180 and it may hold ip_conntrack module loaded
181 indefinitely. */
182 nf_reset(skb);
183
179 skb_postpull_rcsum(skb, skb->nh.raw, 184 skb_postpull_rcsum(skb, skb->nh.raw,
180 skb->h.raw - skb->nh.raw); 185 skb->h.raw - skb->nh.raw);
181 hdr = skb->nh.ipv6h; 186 hdr = skb->nh.ipv6h;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index dbd9767b32e4..c1fa693511a1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -441,9 +441,15 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
441#ifdef CONFIG_NETFILTER 441#ifdef CONFIG_NETFILTER
442 to->nfmark = from->nfmark; 442 to->nfmark = from->nfmark;
443 /* Connection association is same as pre-frag packet */ 443 /* Connection association is same as pre-frag packet */
444 nf_conntrack_put(to->nfct);
444 to->nfct = from->nfct; 445 to->nfct = from->nfct;
445 nf_conntrack_get(to->nfct); 446 nf_conntrack_get(to->nfct);
446 to->nfctinfo = from->nfctinfo; 447 to->nfctinfo = from->nfctinfo;
448#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
449 nf_conntrack_put_reasm(to->nfct_reasm);
450 to->nfct_reasm = from->nfct_reasm;
451 nf_conntrack_get_reasm(to->nfct_reasm);
452#endif
447#ifdef CONFIG_BRIDGE_NETFILTER 453#ifdef CONFIG_BRIDGE_NETFILTER
448 nf_bridge_put(to->nf_bridge); 454 nf_bridge_put(to->nf_bridge);
449 to->nf_bridge = from->nf_bridge; 455 to->nf_bridge = from->nf_bridge;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e6b0e3954c02..e315d0f80af1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -525,6 +525,7 @@ ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
525 525
526 if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) { 526 if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
527 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 527 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
528 read_unlock(&ip6ip6_lock);
528 kfree_skb(skb); 529 kfree_skb(skb);
529 return 0; 530 return 0;
530 } 531 }
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index bb7ccfe33f23..971ba60bf6e9 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -278,5 +278,19 @@ config IP6_NF_RAW
278 If you want to compile it as a module, say M here and read 278 If you want to compile it as a module, say M here and read
279 <file:Documentation/modules.txt>. If unsure, say `N'. 279 <file:Documentation/modules.txt>. If unsure, say `N'.
280 280
281config NF_CONNTRACK_IPV6
282 tristate "IPv6 support for new connection tracking (EXPERIMENTAL)"
283 depends on EXPERIMENTAL && NF_CONNTRACK
284 ---help---
285 Connection tracking keeps a record of what packets have passed
286 through your machine, in order to figure out how they are related
287 into connections.
288
289 This is IPv6 support on Layer 3 independent connection tracking.
290 Layer 3 independent connection tracking is experimental scheme
291 which generalize ip_conntrack to support other layer 3 protocols.
292
293 To compile it as a module, choose M here. If unsure, say N.
294
281endmenu 295endmenu
282 296
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 2b2c370e8b1c..9ab5b2ca1f59 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -27,3 +27,9 @@ obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
27obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 27obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
28obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o 28obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
29obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o 29obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
30
31# objects for l3 independent conntrack
32nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
33
34# l3 independent conntrack
35obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c
index 0c7584f92172..eab8fb864ee0 100644
--- a/net/ipv6/netfilter/ip6t_MARK.c
+++ b/net/ipv6/netfilter/ip6t_MARK.c
@@ -56,9 +56,9 @@ checkentry(const char *tablename,
56 return 1; 56 return 1;
57} 57}
58 58
59static struct ip6t_target ip6t_mark_reg = { 59static struct ip6t_target ip6t_mark_reg = {
60 .name = "MARK", 60 .name = "MARK",
61 .target = target, 61 .target = target,
62 .checkentry = checkentry, 62 .checkentry = checkentry,
63 .me = THIS_MODULE 63 .me = THIS_MODULE
64}; 64};
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
new file mode 100644
index 000000000000..e2c90b3a8074
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -0,0 +1,556 @@
1/*
2 * Copyright (C)2004 USAGI/WIDE Project
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Author:
9 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
10 *
11 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - support Layer 3 protocol independent connection tracking.
13 * Based on the original ip_conntrack code which had the following
14 * copyright information:
15 * (C) 1999-2001 Paul `Rusty' Russell
16 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
17 *
18 * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
19 * - add get_features() to support various size of conntrack
20 * structures.
21 */
22
23#include <linux/config.h>
24#include <linux/types.h>
25#include <linux/ipv6.h>
26#include <linux/in6.h>
27#include <linux/netfilter.h>
28#include <linux/module.h>
29#include <linux/skbuff.h>
30#include <linux/icmp.h>
31#include <linux/sysctl.h>
32#include <net/ipv6.h>
33
34#include <linux/netfilter_ipv6.h>
35#include <net/netfilter/nf_conntrack.h>
36#include <net/netfilter/nf_conntrack_helper.h>
37#include <net/netfilter/nf_conntrack_protocol.h>
38#include <net/netfilter/nf_conntrack_l3proto.h>
39#include <net/netfilter/nf_conntrack_core.h>
40
41#if 0
42#define DEBUGP printk
43#else
44#define DEBUGP(format, args...)
45#endif
46
47DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
48
49static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
50 struct nf_conntrack_tuple *tuple)
51{
52 u_int32_t _addrs[8], *ap;
53
54 ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
55 sizeof(_addrs), _addrs);
56 if (ap == NULL)
57 return 0;
58
59 memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
60 memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6));
61
62 return 1;
63}
64
65static int ipv6_invert_tuple(struct nf_conntrack_tuple *tuple,
66 const struct nf_conntrack_tuple *orig)
67{
68 memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6));
69 memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6));
70
71 return 1;
72}
73
74static int ipv6_print_tuple(struct seq_file *s,
75 const struct nf_conntrack_tuple *tuple)
76{
77 return seq_printf(s, "src=%x:%x:%x:%x:%x:%x:%x:%x dst=%x:%x:%x:%x:%x:%x:%x:%x ",
78 NIP6(*((struct in6_addr *)tuple->src.u3.ip6)),
79 NIP6(*((struct in6_addr *)tuple->dst.u3.ip6)));
80}
81
82static int ipv6_print_conntrack(struct seq_file *s,
83 const struct nf_conn *conntrack)
84{
85 return 0;
86}
87
88/*
89 * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
90 *
91 * This function parses (probably truncated) exthdr set "hdr"
92 * of length "len". "nexthdrp" initially points to some place,
93 * where type of the first header can be found.
94 *
95 * It skips all well-known exthdrs, and returns pointer to the start
96 * of unparsable area i.e. the first header with unknown type.
97 * if success, *nexthdr is updated by type/protocol of this header.
98 *
99 * NOTES: - it may return pointer pointing beyond end of packet,
100 * if the last recognized header is truncated in the middle.
101 * - if packet is truncated, so that all parsed headers are skipped,
102 * it returns -1.
103 * - if packet is fragmented, return pointer of the fragment header.
104 * - ESP is unparsable for now and considered like
105 * normal payload protocol.
106 * - Note also special handling of AUTH header. Thanks to IPsec wizards.
107 */
108
109int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp,
110 int len)
111{
112 u8 nexthdr = *nexthdrp;
113
114 while (ipv6_ext_hdr(nexthdr)) {
115 struct ipv6_opt_hdr hdr;
116 int hdrlen;
117
118 if (len < (int)sizeof(struct ipv6_opt_hdr))
119 return -1;
120 if (nexthdr == NEXTHDR_NONE)
121 break;
122 if (nexthdr == NEXTHDR_FRAGMENT)
123 break;
124 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
125 BUG();
126 if (nexthdr == NEXTHDR_AUTH)
127 hdrlen = (hdr.hdrlen+2)<<2;
128 else
129 hdrlen = ipv6_optlen(&hdr);
130
131 nexthdr = hdr.nexthdr;
132 len -= hdrlen;
133 start += hdrlen;
134 }
135
136 *nexthdrp = nexthdr;
137 return start;
138}
139
140static int
141ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
142 u_int8_t *protonum)
143{
144 unsigned int extoff;
145 unsigned char pnum;
146 int protoff;
147
148 extoff = (u8*)((*pskb)->nh.ipv6h + 1) - (*pskb)->data;
149 pnum = (*pskb)->nh.ipv6h->nexthdr;
150
151 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
152 (*pskb)->len - extoff);
153
154 /*
155 * (protoff == (*pskb)->len) mean that the packet doesn't have no data
156 * except of IPv6 & ext headers. but it's tracked anyway. - YK
157 */
158 if ((protoff < 0) || (protoff > (*pskb)->len)) {
159 DEBUGP("ip6_conntrack_core: can't find proto in pkt\n");
160 NF_CT_STAT_INC(error);
161 NF_CT_STAT_INC(invalid);
162 return -NF_ACCEPT;
163 }
164
165 *dataoff = protoff;
166 *protonum = pnum;
167 return NF_ACCEPT;
168}
169
170static u_int32_t ipv6_get_features(const struct nf_conntrack_tuple *tuple)
171{
172 return NF_CT_F_BASIC;
173}
174
175static unsigned int ipv6_confirm(unsigned int hooknum,
176 struct sk_buff **pskb,
177 const struct net_device *in,
178 const struct net_device *out,
179 int (*okfn)(struct sk_buff *))
180{
181 struct nf_conn *ct;
182 enum ip_conntrack_info ctinfo;
183
184 /* This is where we call the helper: as the packet goes out. */
185 ct = nf_ct_get(*pskb, &ctinfo);
186 if (ct && ct->helper) {
187 unsigned int ret, protoff;
188 unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
189 - (*pskb)->data;
190 unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
191
192 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
193 (*pskb)->len - extoff);
194 if (protoff < 0 || protoff > (*pskb)->len ||
195 pnum == NEXTHDR_FRAGMENT) {
196 DEBUGP("proto header not found\n");
197 return NF_ACCEPT;
198 }
199
200 ret = ct->helper->help(pskb, protoff, ct, ctinfo);
201 if (ret != NF_ACCEPT)
202 return ret;
203 }
204
205 /* We've seen it coming out the other side: confirm it */
206
207 return nf_conntrack_confirm(pskb);
208}
209
210extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
211extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
212 struct net_device *in,
213 struct net_device *out,
214 int (*okfn)(struct sk_buff *));
215static unsigned int ipv6_defrag(unsigned int hooknum,
216 struct sk_buff **pskb,
217 const struct net_device *in,
218 const struct net_device *out,
219 int (*okfn)(struct sk_buff *))
220{
221 struct sk_buff *reasm;
222
223 /* Previously seen (loopback)? */
224 if ((*pskb)->nfct)
225 return NF_ACCEPT;
226
227 reasm = nf_ct_frag6_gather(*pskb);
228
229 /* queued */
230 if (reasm == NULL)
231 return NF_STOLEN;
232
233 /* error occured or not fragmented */
234 if (reasm == *pskb)
235 return NF_ACCEPT;
236
237 nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
238 (struct net_device *)out, okfn);
239
240 return NF_STOLEN;
241}
242
243static unsigned int ipv6_conntrack_in(unsigned int hooknum,
244 struct sk_buff **pskb,
245 const struct net_device *in,
246 const struct net_device *out,
247 int (*okfn)(struct sk_buff *))
248{
249 struct sk_buff *reasm = (*pskb)->nfct_reasm;
250
251 /* This packet is fragmented and has reassembled packet. */
252 if (reasm) {
253 /* Reassembled packet isn't parsed yet ? */
254 if (!reasm->nfct) {
255 unsigned int ret;
256
257 ret = nf_conntrack_in(PF_INET6, hooknum, &reasm);
258 if (ret != NF_ACCEPT)
259 return ret;
260 }
261 nf_conntrack_get(reasm->nfct);
262 (*pskb)->nfct = reasm->nfct;
263 return NF_ACCEPT;
264 }
265
266 return nf_conntrack_in(PF_INET6, hooknum, pskb);
267}
268
269static unsigned int ipv6_conntrack_local(unsigned int hooknum,
270 struct sk_buff **pskb,
271 const struct net_device *in,
272 const struct net_device *out,
273 int (*okfn)(struct sk_buff *))
274{
275 /* root is playing with raw sockets. */
276 if ((*pskb)->len < sizeof(struct ipv6hdr)) {
277 if (net_ratelimit())
278 printk("ipv6_conntrack_local: packet too short\n");
279 return NF_ACCEPT;
280 }
281 return ipv6_conntrack_in(hooknum, pskb, in, out, okfn);
282}
283
284/* Connection tracking may drop packets, but never alters them, so
285 make it the first hook. */
286static struct nf_hook_ops ipv6_conntrack_defrag_ops = {
287 .hook = ipv6_defrag,
288 .owner = THIS_MODULE,
289 .pf = PF_INET6,
290 .hooknum = NF_IP6_PRE_ROUTING,
291 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
292};
293
294static struct nf_hook_ops ipv6_conntrack_in_ops = {
295 .hook = ipv6_conntrack_in,
296 .owner = THIS_MODULE,
297 .pf = PF_INET6,
298 .hooknum = NF_IP6_PRE_ROUTING,
299 .priority = NF_IP6_PRI_CONNTRACK,
300};
301
302static struct nf_hook_ops ipv6_conntrack_local_out_ops = {
303 .hook = ipv6_conntrack_local,
304 .owner = THIS_MODULE,
305 .pf = PF_INET6,
306 .hooknum = NF_IP6_LOCAL_OUT,
307 .priority = NF_IP6_PRI_CONNTRACK,
308};
309
310static struct nf_hook_ops ipv6_conntrack_defrag_local_out_ops = {
311 .hook = ipv6_defrag,
312 .owner = THIS_MODULE,
313 .pf = PF_INET6,
314 .hooknum = NF_IP6_LOCAL_OUT,
315 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
316};
317
318/* Refragmenter; last chance. */
319static struct nf_hook_ops ipv6_conntrack_out_ops = {
320 .hook = ipv6_confirm,
321 .owner = THIS_MODULE,
322 .pf = PF_INET6,
323 .hooknum = NF_IP6_POST_ROUTING,
324 .priority = NF_IP6_PRI_LAST,
325};
326
327static struct nf_hook_ops ipv6_conntrack_local_in_ops = {
328 .hook = ipv6_confirm,
329 .owner = THIS_MODULE,
330 .pf = PF_INET6,
331 .hooknum = NF_IP6_LOCAL_IN,
332 .priority = NF_IP6_PRI_LAST-1,
333};
334
335#ifdef CONFIG_SYSCTL
336
337/* From nf_conntrack_proto_icmpv6.c */
338extern unsigned long nf_ct_icmpv6_timeout;
339
340/* From nf_conntrack_frag6.c */
341extern unsigned long nf_ct_frag6_timeout;
342extern unsigned long nf_ct_frag6_low_thresh;
343extern unsigned long nf_ct_frag6_high_thresh;
344
345static struct ctl_table_header *nf_ct_ipv6_sysctl_header;
346
347static ctl_table nf_ct_sysctl_table[] = {
348 {
349 .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
350 .procname = "nf_conntrack_icmpv6_timeout",
351 .data = &nf_ct_icmpv6_timeout,
352 .maxlen = sizeof(unsigned int),
353 .mode = 0644,
354 .proc_handler = &proc_dointvec_jiffies,
355 },
356 {
357 .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT,
358 .procname = "nf_conntrack_frag6_timeout",
359 .data = &nf_ct_frag6_timeout,
360 .maxlen = sizeof(unsigned int),
361 .mode = 0644,
362 .proc_handler = &proc_dointvec_jiffies,
363 },
364 {
365 .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
366 .procname = "nf_conntrack_frag6_low_thresh",
367 .data = &nf_ct_frag6_low_thresh,
368 .maxlen = sizeof(unsigned int),
369 .mode = 0644,
370 .proc_handler = &proc_dointvec_jiffies,
371 },
372 {
373 .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
374 .procname = "nf_conntrack_frag6_high_thresh",
375 .data = &nf_ct_frag6_high_thresh,
376 .maxlen = sizeof(unsigned int),
377 .mode = 0644,
378 .proc_handler = &proc_dointvec_jiffies,
379 },
380 { .ctl_name = 0 }
381};
382
383static ctl_table nf_ct_netfilter_table[] = {
384 {
385 .ctl_name = NET_NETFILTER,
386 .procname = "netfilter",
387 .mode = 0555,
388 .child = nf_ct_sysctl_table,
389 },
390 { .ctl_name = 0 }
391};
392
393static ctl_table nf_ct_net_table[] = {
394 {
395 .ctl_name = CTL_NET,
396 .procname = "net",
397 .mode = 0555,
398 .child = nf_ct_netfilter_table,
399 },
400 { .ctl_name = 0 }
401};
402#endif
403
404struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
405 .l3proto = PF_INET6,
406 .name = "ipv6",
407 .pkt_to_tuple = ipv6_pkt_to_tuple,
408 .invert_tuple = ipv6_invert_tuple,
409 .print_tuple = ipv6_print_tuple,
410 .print_conntrack = ipv6_print_conntrack,
411 .prepare = ipv6_prepare,
412 .get_features = ipv6_get_features,
413 .me = THIS_MODULE,
414};
415
416extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
417extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
418extern struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6;
419extern int nf_ct_frag6_init(void);
420extern void nf_ct_frag6_cleanup(void);
421static int init_or_cleanup(int init)
422{
423 int ret = 0;
424
425 if (!init) goto cleanup;
426
427 ret = nf_ct_frag6_init();
428 if (ret < 0) {
429 printk("nf_conntrack_ipv6: can't initialize frag6.\n");
430 goto cleanup_nothing;
431 }
432 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6);
433 if (ret < 0) {
434 printk("nf_conntrack_ipv6: can't register tcp.\n");
435 goto cleanup_frag6;
436 }
437
438 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp6);
439 if (ret < 0) {
440 printk("nf_conntrack_ipv6: can't register udp.\n");
441 goto cleanup_tcp;
442 }
443
444 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmpv6);
445 if (ret < 0) {
446 printk("nf_conntrack_ipv6: can't register icmpv6.\n");
447 goto cleanup_udp;
448 }
449
450 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
451 if (ret < 0) {
452 printk("nf_conntrack_ipv6: can't register ipv6\n");
453 goto cleanup_icmpv6;
454 }
455
456 ret = nf_register_hook(&ipv6_conntrack_defrag_ops);
457 if (ret < 0) {
458 printk("nf_conntrack_ipv6: can't register pre-routing defrag "
459 "hook.\n");
460 goto cleanup_ipv6;
461 }
462
463 ret = nf_register_hook(&ipv6_conntrack_defrag_local_out_ops);
464 if (ret < 0) {
465 printk("nf_conntrack_ipv6: can't register local_out defrag "
466 "hook.\n");
467 goto cleanup_defragops;
468 }
469
470 ret = nf_register_hook(&ipv6_conntrack_in_ops);
471 if (ret < 0) {
472 printk("nf_conntrack_ipv6: can't register pre-routing hook.\n");
473 goto cleanup_defraglocalops;
474 }
475
476 ret = nf_register_hook(&ipv6_conntrack_local_out_ops);
477 if (ret < 0) {
478 printk("nf_conntrack_ipv6: can't register local out hook.\n");
479 goto cleanup_inops;
480 }
481
482 ret = nf_register_hook(&ipv6_conntrack_out_ops);
483 if (ret < 0) {
484 printk("nf_conntrack_ipv6: can't register post-routing hook.\n");
485 goto cleanup_inandlocalops;
486 }
487
488 ret = nf_register_hook(&ipv6_conntrack_local_in_ops);
489 if (ret < 0) {
490 printk("nf_conntrack_ipv6: can't register local in hook.\n");
491 goto cleanup_inoutandlocalops;
492 }
493
494#ifdef CONFIG_SYSCTL
495 nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
496 if (nf_ct_ipv6_sysctl_header == NULL) {
497 printk("nf_conntrack: can't register to sysctl.\n");
498 ret = -ENOMEM;
499 goto cleanup_localinops;
500 }
501#endif
502 return ret;
503
504 cleanup:
505 synchronize_net();
506#ifdef CONFIG_SYSCTL
507 unregister_sysctl_table(nf_ct_ipv6_sysctl_header);
508 cleanup_localinops:
509#endif
510 nf_unregister_hook(&ipv6_conntrack_local_in_ops);
511 cleanup_inoutandlocalops:
512 nf_unregister_hook(&ipv6_conntrack_out_ops);
513 cleanup_inandlocalops:
514 nf_unregister_hook(&ipv6_conntrack_local_out_ops);
515 cleanup_inops:
516 nf_unregister_hook(&ipv6_conntrack_in_ops);
517 cleanup_defraglocalops:
518 nf_unregister_hook(&ipv6_conntrack_defrag_local_out_ops);
519 cleanup_defragops:
520 nf_unregister_hook(&ipv6_conntrack_defrag_ops);
521 cleanup_ipv6:
522 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
523 cleanup_icmpv6:
524 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6);
525 cleanup_udp:
526 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6);
527 cleanup_tcp:
528 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6);
529 cleanup_frag6:
530 nf_ct_frag6_cleanup();
531 cleanup_nothing:
532 return ret;
533}
534
535MODULE_LICENSE("GPL");
536MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
537
538static int __init init(void)
539{
540 need_nf_conntrack();
541 return init_or_cleanup(1);
542}
543
544static void __exit fini(void)
545{
546 init_or_cleanup(0);
547}
548
549module_init(init);
550module_exit(fini);
551
552void need_ip6_conntrack(void)
553{
554}
555
556EXPORT_SYMBOL(need_ip6_conntrack);
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
new file mode 100644
index 000000000000..c0f1da5497a9
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -0,0 +1,272 @@
1/*
2 * Copyright (C)2003,2004 USAGI/WIDE Project
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Author:
9 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
10 *
11 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - ICMPv6 tracking support. Derived from the original ip_conntrack code
13 * net/ipv4/netfilter/ip_conntrack_proto_icmp.c which had the following
14 * copyright information:
15 * (C) 1999-2001 Paul `Rusty' Russell
16 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
17 */
18
19#include <linux/types.h>
20#include <linux/sched.h>
21#include <linux/timer.h>
22#include <linux/module.h>
23#include <linux/netfilter.h>
24#include <linux/in6.h>
25#include <linux/icmpv6.h>
26#include <linux/ipv6.h>
27#include <net/ipv6.h>
28#include <net/ip6_checksum.h>
29#include <linux/seq_file.h>
30#include <linux/netfilter_ipv6.h>
31#include <net/netfilter/nf_conntrack_tuple.h>
32#include <net/netfilter/nf_conntrack_protocol.h>
33#include <net/netfilter/nf_conntrack_core.h>
34#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
35
36unsigned long nf_ct_icmpv6_timeout = 30*HZ;
37
38#if 0
39#define DEBUGP printk
40#else
41#define DEBUGP(format, args...)
42#endif
43
44static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
45 unsigned int dataoff,
46 struct nf_conntrack_tuple *tuple)
47{
48 struct icmp6hdr _hdr, *hp;
49
50 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
51 if (hp == NULL)
52 return 0;
53 tuple->dst.u.icmp.type = hp->icmp6_type;
54 tuple->src.u.icmp.id = hp->icmp6_identifier;
55 tuple->dst.u.icmp.code = hp->icmp6_code;
56
57 return 1;
58}
59
60static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
61 const struct nf_conntrack_tuple *orig)
62{
63 /* Add 1; spaces filled with 0. */
64 static u_int8_t invmap[] = {
65 [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
66 [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
67 [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
68 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
69 };
70
71 __u8 type = orig->dst.u.icmp.type - 128;
72 if (type >= sizeof(invmap) || !invmap[type])
73 return 0;
74
75 tuple->src.u.icmp.id = orig->src.u.icmp.id;
76 tuple->dst.u.icmp.type = invmap[type] - 1;
77 tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
78 return 1;
79}
80
81/* Print out the per-protocol part of the tuple. */
82static int icmpv6_print_tuple(struct seq_file *s,
83 const struct nf_conntrack_tuple *tuple)
84{
85 return seq_printf(s, "type=%u code=%u id=%u ",
86 tuple->dst.u.icmp.type,
87 tuple->dst.u.icmp.code,
88 ntohs(tuple->src.u.icmp.id));
89}
90
91/* Print out the private part of the conntrack. */
92static int icmpv6_print_conntrack(struct seq_file *s,
93 const struct nf_conn *conntrack)
94{
95 return 0;
96}
97
98/* Returns verdict for packet, or -1 for invalid. */
99static int icmpv6_packet(struct nf_conn *ct,
100 const struct sk_buff *skb,
101 unsigned int dataoff,
102 enum ip_conntrack_info ctinfo,
103 int pf,
104 unsigned int hooknum)
105{
106 /* Try to delete connection immediately after all replies:
107 won't actually vanish as we still have skb, and del_timer
108 means this will only run once even if count hits zero twice
109 (theoretically possible with SMP) */
110 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
111 if (atomic_dec_and_test(&ct->proto.icmp.count)
112 && del_timer(&ct->timeout))
113 ct->timeout.function((unsigned long)ct);
114 } else {
115 atomic_inc(&ct->proto.icmp.count);
116 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
117 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
118 }
119
120 return NF_ACCEPT;
121}
122
123/* Called when a new connection for this protocol found. */
124static int icmpv6_new(struct nf_conn *conntrack,
125 const struct sk_buff *skb,
126 unsigned int dataoff)
127{
128 static u_int8_t valid_new[] = {
129 [ICMPV6_ECHO_REQUEST - 128] = 1,
130 [ICMPV6_NI_QUERY - 128] = 1
131 };
132
133 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128 >= sizeof(valid_new)
134 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128]) {
135 /* Can't create a new ICMPv6 `conn' with this. */
136 DEBUGP("icmp: can't create new conn with type %u\n",
137 conntrack->tuplehash[0].tuple.dst.u.icmp.type);
138 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
139 return 0;
140 }
141 atomic_set(&conntrack->proto.icmp.count, 0);
142 return 1;
143}
144
145extern int
146nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, int len);
147extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
148static int
149icmpv6_error_message(struct sk_buff *skb,
150 unsigned int icmp6off,
151 enum ip_conntrack_info *ctinfo,
152 unsigned int hooknum)
153{
154 struct nf_conntrack_tuple intuple, origtuple;
155 struct nf_conntrack_tuple_hash *h;
156 struct icmp6hdr _hdr, *hp;
157 unsigned int inip6off;
158 struct nf_conntrack_protocol *inproto;
159 u_int8_t inprotonum;
160 unsigned int inprotoff;
161
162 NF_CT_ASSERT(skb->nfct == NULL);
163
164 hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
165 if (hp == NULL) {
166 DEBUGP("icmpv6_error: Can't get ICMPv6 hdr.\n");
167 return -NF_ACCEPT;
168 }
169
170 inip6off = icmp6off + sizeof(_hdr);
171 if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
172 &inprotonum, sizeof(inprotonum)) != 0) {
173 DEBUGP("icmpv6_error: Can't get nexthdr in inner IPv6 header.\n");
174 return -NF_ACCEPT;
175 }
176 inprotoff = nf_ct_ipv6_skip_exthdr(skb,
177 inip6off + sizeof(struct ipv6hdr),
178 &inprotonum,
179 skb->len - inip6off
180 - sizeof(struct ipv6hdr));
181
182 if ((inprotoff < 0) || (inprotoff > skb->len) ||
183 (inprotonum == NEXTHDR_FRAGMENT)) {
184 DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n");
185 return -NF_ACCEPT;
186 }
187
188 inproto = nf_ct_find_proto(PF_INET6, inprotonum);
189
190 /* Are they talking about one of our connections? */
191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
192 &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) {
193 DEBUGP("icmpv6_error: Can't get tuple\n");
194 return -NF_ACCEPT;
195 }
196
197 /* Ordinarily, we'd expect the inverted tupleproto, but it's
198 been preserved inside the ICMP. */
199 if (!nf_ct_invert_tuple(&intuple, &origtuple,
200 &nf_conntrack_l3proto_ipv6, inproto)) {
201 DEBUGP("icmpv6_error: Can't invert tuple\n");
202 return -NF_ACCEPT;
203 }
204
205 *ctinfo = IP_CT_RELATED;
206
207 h = nf_conntrack_find_get(&intuple, NULL);
208 if (!h) {
209 DEBUGP("icmpv6_error: no match\n");
210 return -NF_ACCEPT;
211 } else {
212 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
213 *ctinfo += IP_CT_IS_REPLY;
214 }
215
216 /* Update skb to refer to this connection */
217 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
218 skb->nfctinfo = *ctinfo;
219 return -NF_ACCEPT;
220}
221
222static int
223icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
224 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
225{
226 struct icmp6hdr _ih, *icmp6h;
227
228 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
229 if (icmp6h == NULL) {
230 if (LOG_INVALID(IPPROTO_ICMPV6))
231 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
232 "nf_ct_icmpv6: short packet ");
233 return -NF_ACCEPT;
234 }
235
236 if (hooknum != NF_IP6_PRE_ROUTING)
237 goto skipped;
238
239 /* Ignore it if the checksum's bogus. */
240 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
241 skb->len - dataoff, IPPROTO_ICMPV6,
242 skb_checksum(skb, dataoff,
243 skb->len - dataoff, 0))) {
244 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
245 "nf_ct_icmpv6: ICMPv6 checksum failed\n");
246 return -NF_ACCEPT;
247 }
248
249skipped:
250
251 /* is not error message ? */
252 if (icmp6h->icmp6_type >= 128)
253 return NF_ACCEPT;
254
255 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
256}
257
258struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
259{
260 .l3proto = PF_INET6,
261 .proto = IPPROTO_ICMPV6,
262 .name = "icmpv6",
263 .pkt_to_tuple = icmpv6_pkt_to_tuple,
264 .invert_tuple = icmpv6_invert_tuple,
265 .print_tuple = icmpv6_print_tuple,
266 .print_conntrack = icmpv6_print_conntrack,
267 .packet = icmpv6_packet,
268 .new = icmpv6_new,
269 .error = icmpv6_error,
270};
271
272EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
new file mode 100644
index 000000000000..7640b9bb7694
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -0,0 +1,885 @@
1/*
2 * IPv6 fragment reassembly for connection tracking
3 *
4 * Copyright (C)2004 USAGI/WIDE Project
5 *
6 * Author:
7 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
8 *
9 * Based on: net/ipv6/reassembly.c
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#include <linux/config.h>
18#include <linux/errno.h>
19#include <linux/types.h>
20#include <linux/string.h>
21#include <linux/socket.h>
22#include <linux/sockios.h>
23#include <linux/jiffies.h>
24#include <linux/net.h>
25#include <linux/list.h>
26#include <linux/netdevice.h>
27#include <linux/in6.h>
28#include <linux/ipv6.h>
29#include <linux/icmpv6.h>
30#include <linux/random.h>
31#include <linux/jhash.h>
32
33#include <net/sock.h>
34#include <net/snmp.h>
35
36#include <net/ipv6.h>
37#include <net/protocol.h>
38#include <net/transp_v6.h>
39#include <net/rawv6.h>
40#include <net/ndisc.h>
41#include <net/addrconf.h>
42#include <linux/sysctl.h>
43#include <linux/netfilter.h>
44#include <linux/netfilter_ipv6.h>
45#include <linux/kernel.h>
46#include <linux/module.h>
47
48#if 0
49#define DEBUGP printk
50#else
51#define DEBUGP(format, args...)
52#endif
53
54#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
55#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
56#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
57
58int nf_ct_frag6_high_thresh = 256*1024;
59int nf_ct_frag6_low_thresh = 192*1024;
60int nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT;
61
62struct nf_ct_frag6_skb_cb
63{
64 struct inet6_skb_parm h;
65 int offset;
66 struct sk_buff *orig;
67};
68
69#define NFCT_FRAG6_CB(skb) ((struct nf_ct_frag6_skb_cb*)((skb)->cb))
70
71struct nf_ct_frag6_queue
72{
73 struct nf_ct_frag6_queue *next;
74 struct list_head lru_list; /* lru list member */
75
76 __u32 id; /* fragment id */
77 struct in6_addr saddr;
78 struct in6_addr daddr;
79
80 spinlock_t lock;
81 atomic_t refcnt;
82 struct timer_list timer; /* expire timer */
83 struct sk_buff *fragments;
84 int len;
85 int meat;
86 struct timeval stamp;
87 unsigned int csum;
88 __u8 last_in; /* has first/last segment arrived? */
89#define COMPLETE 4
90#define FIRST_IN 2
91#define LAST_IN 1
92 __u16 nhoffset;
93 struct nf_ct_frag6_queue **pprev;
94};
95
96/* Hash table. */
97
98#define FRAG6Q_HASHSZ 64
99
100static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
101static rwlock_t nf_ct_frag6_lock = RW_LOCK_UNLOCKED;
102static u32 nf_ct_frag6_hash_rnd;
103static LIST_HEAD(nf_ct_frag6_lru_list);
104int nf_ct_frag6_nqueues = 0;
105
106static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq)
107{
108 if (fq->next)
109 fq->next->pprev = fq->pprev;
110 *fq->pprev = fq->next;
111 list_del(&fq->lru_list);
112 nf_ct_frag6_nqueues--;
113}
114
115static __inline__ void fq_unlink(struct nf_ct_frag6_queue *fq)
116{
117 write_lock(&nf_ct_frag6_lock);
118 __fq_unlink(fq);
119 write_unlock(&nf_ct_frag6_lock);
120}
121
122static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr,
123 struct in6_addr *daddr)
124{
125 u32 a, b, c;
126
127 a = saddr->s6_addr32[0];
128 b = saddr->s6_addr32[1];
129 c = saddr->s6_addr32[2];
130
131 a += JHASH_GOLDEN_RATIO;
132 b += JHASH_GOLDEN_RATIO;
133 c += nf_ct_frag6_hash_rnd;
134 __jhash_mix(a, b, c);
135
136 a += saddr->s6_addr32[3];
137 b += daddr->s6_addr32[0];
138 c += daddr->s6_addr32[1];
139 __jhash_mix(a, b, c);
140
141 a += daddr->s6_addr32[2];
142 b += daddr->s6_addr32[3];
143 c += id;
144 __jhash_mix(a, b, c);
145
146 return c & (FRAG6Q_HASHSZ - 1);
147}
148
149static struct timer_list nf_ct_frag6_secret_timer;
150int nf_ct_frag6_secret_interval = 10 * 60 * HZ;
151
152static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
153{
154 unsigned long now = jiffies;
155 int i;
156
157 write_lock(&nf_ct_frag6_lock);
158 get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32));
159 for (i = 0; i < FRAG6Q_HASHSZ; i++) {
160 struct nf_ct_frag6_queue *q;
161
162 q = nf_ct_frag6_hash[i];
163 while (q) {
164 struct nf_ct_frag6_queue *next = q->next;
165 unsigned int hval = ip6qhashfn(q->id,
166 &q->saddr,
167 &q->daddr);
168
169 if (hval != i) {
170 /* Unlink. */
171 if (q->next)
172 q->next->pprev = q->pprev;
173 *q->pprev = q->next;
174
175 /* Relink to new hash chain. */
176 if ((q->next = nf_ct_frag6_hash[hval]) != NULL)
177 q->next->pprev = &q->next;
178 nf_ct_frag6_hash[hval] = q;
179 q->pprev = &nf_ct_frag6_hash[hval];
180 }
181
182 q = next;
183 }
184 }
185 write_unlock(&nf_ct_frag6_lock);
186
187 mod_timer(&nf_ct_frag6_secret_timer, now + nf_ct_frag6_secret_interval);
188}
189
190atomic_t nf_ct_frag6_mem = ATOMIC_INIT(0);
191
192/* Memory Tracking Functions. */
193static inline void frag_kfree_skb(struct sk_buff *skb)
194{
195 atomic_sub(skb->truesize, &nf_ct_frag6_mem);
196 if (NFCT_FRAG6_CB(skb)->orig)
197 kfree_skb(NFCT_FRAG6_CB(skb)->orig);
198
199 kfree_skb(skb);
200}
201
202static inline void frag_free_queue(struct nf_ct_frag6_queue *fq)
203{
204 atomic_sub(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
205 kfree(fq);
206}
207
208static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
209{
210 struct nf_ct_frag6_queue *fq = kmalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC);
211
212 if (!fq)
213 return NULL;
214 atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
215 return fq;
216}
217
218/* Destruction primitives. */
219
220/* Complete destruction of fq. */
221static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq)
222{
223 struct sk_buff *fp;
224
225 BUG_TRAP(fq->last_in&COMPLETE);
226 BUG_TRAP(del_timer(&fq->timer) == 0);
227
228 /* Release all fragment data. */
229 fp = fq->fragments;
230 while (fp) {
231 struct sk_buff *xp = fp->next;
232
233 frag_kfree_skb(fp);
234 fp = xp;
235 }
236
237 frag_free_queue(fq);
238}
239
240static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
241{
242 if (atomic_dec_and_test(&fq->refcnt))
243 nf_ct_frag6_destroy(fq);
244}
245
246/* Kill fq entry. It is not destroyed immediately,
247 * because caller (and someone more) holds reference count.
248 */
249static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
250{
251 if (del_timer(&fq->timer))
252 atomic_dec(&fq->refcnt);
253
254 if (!(fq->last_in & COMPLETE)) {
255 fq_unlink(fq);
256 atomic_dec(&fq->refcnt);
257 fq->last_in |= COMPLETE;
258 }
259}
260
261static void nf_ct_frag6_evictor(void)
262{
263 struct nf_ct_frag6_queue *fq;
264 struct list_head *tmp;
265
266 for (;;) {
267 if (atomic_read(&nf_ct_frag6_mem) <= nf_ct_frag6_low_thresh)
268 return;
269 read_lock(&nf_ct_frag6_lock);
270 if (list_empty(&nf_ct_frag6_lru_list)) {
271 read_unlock(&nf_ct_frag6_lock);
272 return;
273 }
274 tmp = nf_ct_frag6_lru_list.next;
275 fq = list_entry(tmp, struct nf_ct_frag6_queue, lru_list);
276 atomic_inc(&fq->refcnt);
277 read_unlock(&nf_ct_frag6_lock);
278
279 spin_lock(&fq->lock);
280 if (!(fq->last_in&COMPLETE))
281 fq_kill(fq);
282 spin_unlock(&fq->lock);
283
284 fq_put(fq);
285 }
286}
287
288static void nf_ct_frag6_expire(unsigned long data)
289{
290 struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data;
291
292 spin_lock(&fq->lock);
293
294 if (fq->last_in & COMPLETE)
295 goto out;
296
297 fq_kill(fq);
298
299out:
300 spin_unlock(&fq->lock);
301 fq_put(fq);
302}
303
304/* Creation primitives. */
305
306
307static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
308 struct nf_ct_frag6_queue *fq_in)
309{
310 struct nf_ct_frag6_queue *fq;
311
312 write_lock(&nf_ct_frag6_lock);
313#ifdef CONFIG_SMP
314 for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
315 if (fq->id == fq_in->id &&
316 !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) &&
317 !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) {
318 atomic_inc(&fq->refcnt);
319 write_unlock(&nf_ct_frag6_lock);
320 fq_in->last_in |= COMPLETE;
321 fq_put(fq_in);
322 return fq;
323 }
324 }
325#endif
326 fq = fq_in;
327
328 if (!mod_timer(&fq->timer, jiffies + nf_ct_frag6_timeout))
329 atomic_inc(&fq->refcnt);
330
331 atomic_inc(&fq->refcnt);
332 if ((fq->next = nf_ct_frag6_hash[hash]) != NULL)
333 fq->next->pprev = &fq->next;
334 nf_ct_frag6_hash[hash] = fq;
335 fq->pprev = &nf_ct_frag6_hash[hash];
336 INIT_LIST_HEAD(&fq->lru_list);
337 list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
338 nf_ct_frag6_nqueues++;
339 write_unlock(&nf_ct_frag6_lock);
340 return fq;
341}
342
343
344static struct nf_ct_frag6_queue *
345nf_ct_frag6_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst)
346{
347 struct nf_ct_frag6_queue *fq;
348
349 if ((fq = frag_alloc_queue()) == NULL) {
350 DEBUGP("Can't alloc new queue\n");
351 goto oom;
352 }
353
354 memset(fq, 0, sizeof(struct nf_ct_frag6_queue));
355
356 fq->id = id;
357 ipv6_addr_copy(&fq->saddr, src);
358 ipv6_addr_copy(&fq->daddr, dst);
359
360 init_timer(&fq->timer);
361 fq->timer.function = nf_ct_frag6_expire;
362 fq->timer.data = (long) fq;
363 fq->lock = SPIN_LOCK_UNLOCKED;
364 atomic_set(&fq->refcnt, 1);
365
366 return nf_ct_frag6_intern(hash, fq);
367
368oom:
369 return NULL;
370}
371
372static __inline__ struct nf_ct_frag6_queue *
373fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
374{
375 struct nf_ct_frag6_queue *fq;
376 unsigned int hash = ip6qhashfn(id, src, dst);
377
378 read_lock(&nf_ct_frag6_lock);
379 for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
380 if (fq->id == id &&
381 !ipv6_addr_cmp(src, &fq->saddr) &&
382 !ipv6_addr_cmp(dst, &fq->daddr)) {
383 atomic_inc(&fq->refcnt);
384 read_unlock(&nf_ct_frag6_lock);
385 return fq;
386 }
387 }
388 read_unlock(&nf_ct_frag6_lock);
389
390 return nf_ct_frag6_create(hash, id, src, dst);
391}
392
393
394static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
395 struct frag_hdr *fhdr, int nhoff)
396{
397 struct sk_buff *prev, *next;
398 int offset, end;
399
400 if (fq->last_in & COMPLETE) {
401 DEBUGP("Allready completed\n");
402 goto err;
403 }
404
405 offset = ntohs(fhdr->frag_off) & ~0x7;
406 end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
407 ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
408
409 if ((unsigned int)end > IPV6_MAXPLEN) {
410 DEBUGP("offset is too large.\n");
411 return -1;
412 }
413
414 if (skb->ip_summed == CHECKSUM_HW)
415 skb->csum = csum_sub(skb->csum,
416 csum_partial(skb->nh.raw,
417 (u8*)(fhdr + 1) - skb->nh.raw,
418 0));
419
420 /* Is this the final fragment? */
421 if (!(fhdr->frag_off & htons(IP6_MF))) {
422 /* If we already have some bits beyond end
423 * or have different end, the segment is corrupted.
424 */
425 if (end < fq->len ||
426 ((fq->last_in & LAST_IN) && end != fq->len)) {
427 DEBUGP("already received last fragment\n");
428 goto err;
429 }
430 fq->last_in |= LAST_IN;
431 fq->len = end;
432 } else {
433 /* Check if the fragment is rounded to 8 bytes.
434 * Required by the RFC.
435 */
436 if (end & 0x7) {
437 /* RFC2460 says always send parameter problem in
438 * this case. -DaveM
439 */
440 DEBUGP("the end of this fragment is not rounded to 8 bytes.\n");
441 return -1;
442 }
443 if (end > fq->len) {
444 /* Some bits beyond end -> corruption. */
445 if (fq->last_in & LAST_IN) {
446 DEBUGP("last packet already reached.\n");
447 goto err;
448 }
449 fq->len = end;
450 }
451 }
452
453 if (end == offset)
454 goto err;
455
456 /* Point into the IP datagram 'data' part. */
457 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
458 DEBUGP("queue: message is too short.\n");
459 goto err;
460 }
461 if (end-offset < skb->len) {
462 if (pskb_trim(skb, end - offset)) {
463 DEBUGP("Can't trim\n");
464 goto err;
465 }
466 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
467 skb->ip_summed = CHECKSUM_NONE;
468 }
469
470 /* Find out which fragments are in front and at the back of us
471 * in the chain of fragments so far. We must know where to put
472 * this fragment, right?
473 */
474 prev = NULL;
475 for (next = fq->fragments; next != NULL; next = next->next) {
476 if (NFCT_FRAG6_CB(next)->offset >= offset)
477 break; /* bingo! */
478 prev = next;
479 }
480
481 /* We found where to put this one. Check for overlap with
482 * preceding fragment, and, if needed, align things so that
483 * any overlaps are eliminated.
484 */
485 if (prev) {
486 int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset;
487
488 if (i > 0) {
489 offset += i;
490 if (end <= offset) {
491 DEBUGP("overlap\n");
492 goto err;
493 }
494 if (!pskb_pull(skb, i)) {
495 DEBUGP("Can't pull\n");
496 goto err;
497 }
498 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
499 skb->ip_summed = CHECKSUM_NONE;
500 }
501 }
502
503 /* Look for overlap with succeeding segments.
504 * If we can merge fragments, do it.
505 */
506 while (next && NFCT_FRAG6_CB(next)->offset < end) {
507 /* overlap is 'i' bytes */
508 int i = end - NFCT_FRAG6_CB(next)->offset;
509
510 if (i < next->len) {
511 /* Eat head of the next overlapped fragment
512 * and leave the loop. The next ones cannot overlap.
513 */
514 DEBUGP("Eat head of the overlapped parts.: %d", i);
515 if (!pskb_pull(next, i))
516 goto err;
517
518 /* next fragment */
519 NFCT_FRAG6_CB(next)->offset += i;
520 fq->meat -= i;
521 if (next->ip_summed != CHECKSUM_UNNECESSARY)
522 next->ip_summed = CHECKSUM_NONE;
523 break;
524 } else {
525 struct sk_buff *free_it = next;
526
527 /* Old fragmnet is completely overridden with
528 * new one drop it.
529 */
530 next = next->next;
531
532 if (prev)
533 prev->next = next;
534 else
535 fq->fragments = next;
536
537 fq->meat -= free_it->len;
538 frag_kfree_skb(free_it);
539 }
540 }
541
542 NFCT_FRAG6_CB(skb)->offset = offset;
543
544 /* Insert this fragment in the chain of fragments. */
545 skb->next = next;
546 if (prev)
547 prev->next = skb;
548 else
549 fq->fragments = skb;
550
551 skb->dev = NULL;
552 skb_get_timestamp(skb, &fq->stamp);
553 fq->meat += skb->len;
554 atomic_add(skb->truesize, &nf_ct_frag6_mem);
555
556 /* The first fragment.
557 * nhoffset is obtained from the first fragment, of course.
558 */
559 if (offset == 0) {
560 fq->nhoffset = nhoff;
561 fq->last_in |= FIRST_IN;
562 }
563 write_lock(&nf_ct_frag6_lock);
564 list_move_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
565 write_unlock(&nf_ct_frag6_lock);
566 return 0;
567
568err:
569 return -1;
570}
571
572/*
573 * Check if this packet is complete.
574 * Returns NULL on failure by any reason, and pointer
575 * to current nexthdr field in reassembled frame.
576 *
577 * It is called with locked fq, and caller must check that
578 * queue is eligible for reassembly i.e. it is not COMPLETE,
579 * the last and the first frames arrived and all the bits are here.
580 */
581static struct sk_buff *
582nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
583{
584 struct sk_buff *fp, *op, *head = fq->fragments;
585 int payload_len;
586
587 fq_kill(fq);
588
589 BUG_TRAP(head != NULL);
590 BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0);
591
592 /* Unfragmented part is taken from the first segment. */
593 payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
594 if (payload_len > IPV6_MAXPLEN) {
595 DEBUGP("payload len is too large.\n");
596 goto out_oversize;
597 }
598
599 /* Head of list must not be cloned. */
600 if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) {
601 DEBUGP("skb is cloned but can't expand head");
602 goto out_oom;
603 }
604
605 /* If the first fragment is fragmented itself, we split
606 * it to two chunks: the first with data and paged part
607 * and the second, holding only fragments. */
608 if (skb_shinfo(head)->frag_list) {
609 struct sk_buff *clone;
610 int i, plen = 0;
611
612 if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) {
613 DEBUGP("Can't alloc skb\n");
614 goto out_oom;
615 }
616 clone->next = head->next;
617 head->next = clone;
618 skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
619 skb_shinfo(head)->frag_list = NULL;
620 for (i=0; i<skb_shinfo(head)->nr_frags; i++)
621 plen += skb_shinfo(head)->frags[i].size;
622 clone->len = clone->data_len = head->data_len - plen;
623 head->data_len -= clone->len;
624 head->len -= clone->len;
625 clone->csum = 0;
626 clone->ip_summed = head->ip_summed;
627
628 NFCT_FRAG6_CB(clone)->orig = NULL;
629 atomic_add(clone->truesize, &nf_ct_frag6_mem);
630 }
631
632 /* We have to remove fragment header from datagram and to relocate
633 * header in order to calculate ICV correctly. */
634 head->nh.raw[fq->nhoffset] = head->h.raw[0];
635 memmove(head->head + sizeof(struct frag_hdr), head->head,
636 (head->data - head->head) - sizeof(struct frag_hdr));
637 head->mac.raw += sizeof(struct frag_hdr);
638 head->nh.raw += sizeof(struct frag_hdr);
639
640 skb_shinfo(head)->frag_list = head->next;
641 head->h.raw = head->data;
642 skb_push(head, head->data - head->nh.raw);
643 atomic_sub(head->truesize, &nf_ct_frag6_mem);
644
645 for (fp=head->next; fp; fp = fp->next) {
646 head->data_len += fp->len;
647 head->len += fp->len;
648 if (head->ip_summed != fp->ip_summed)
649 head->ip_summed = CHECKSUM_NONE;
650 else if (head->ip_summed == CHECKSUM_HW)
651 head->csum = csum_add(head->csum, fp->csum);
652 head->truesize += fp->truesize;
653 atomic_sub(fp->truesize, &nf_ct_frag6_mem);
654 }
655
656 head->next = NULL;
657 head->dev = dev;
658 skb_set_timestamp(head, &fq->stamp);
659 head->nh.ipv6h->payload_len = htons(payload_len);
660
661 /* Yes, and fold redundant checksum back. 8) */
662 if (head->ip_summed == CHECKSUM_HW)
663 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
664
665 fq->fragments = NULL;
666
667 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
668 fp = skb_shinfo(head)->frag_list;
669 if (NFCT_FRAG6_CB(fp)->orig == NULL)
670 /* at above code, head skb is divided into two skbs. */
671 fp = fp->next;
672
673 op = NFCT_FRAG6_CB(head)->orig;
674 for (; fp; fp = fp->next) {
675 struct sk_buff *orig = NFCT_FRAG6_CB(fp)->orig;
676
677 op->next = orig;
678 op = orig;
679 NFCT_FRAG6_CB(fp)->orig = NULL;
680 }
681
682 return head;
683
684out_oversize:
685 if (net_ratelimit())
686 printk(KERN_DEBUG "nf_ct_frag6_reasm: payload len = %d\n", payload_len);
687 goto out_fail;
688out_oom:
689 if (net_ratelimit())
690 printk(KERN_DEBUG "nf_ct_frag6_reasm: no memory for reassembly\n");
691out_fail:
692 return NULL;
693}
694
695/*
696 * find the header just before Fragment Header.
697 *
698 * if success return 0 and set ...
699 * (*prevhdrp): the value of "Next Header Field" in the header
700 * just before Fragment Header.
701 * (*prevhoff): the offset of "Next Header Field" in the header
702 * just before Fragment Header.
703 * (*fhoff) : the offset of Fragment Header.
704 *
705 * Based on ipv6_skip_hdr() in net/ipv6/exthdr.c
706 *
707 */
708static int
709find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
710{
711 u8 nexthdr = skb->nh.ipv6h->nexthdr;
712 u8 prev_nhoff = (u8 *)&skb->nh.ipv6h->nexthdr - skb->data;
713 int start = (u8 *)(skb->nh.ipv6h+1) - skb->data;
714 int len = skb->len - start;
715 u8 prevhdr = NEXTHDR_IPV6;
716
717 while (nexthdr != NEXTHDR_FRAGMENT) {
718 struct ipv6_opt_hdr hdr;
719 int hdrlen;
720
721 if (!ipv6_ext_hdr(nexthdr)) {
722 return -1;
723 }
724 if (len < (int)sizeof(struct ipv6_opt_hdr)) {
725 DEBUGP("too short\n");
726 return -1;
727 }
728 if (nexthdr == NEXTHDR_NONE) {
729 DEBUGP("next header is none\n");
730 return -1;
731 }
732 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
733 BUG();
734 if (nexthdr == NEXTHDR_AUTH)
735 hdrlen = (hdr.hdrlen+2)<<2;
736 else
737 hdrlen = ipv6_optlen(&hdr);
738
739 prevhdr = nexthdr;
740 prev_nhoff = start;
741
742 nexthdr = hdr.nexthdr;
743 len -= hdrlen;
744 start += hdrlen;
745 }
746
747 if (len < 0)
748 return -1;
749
750 *prevhdrp = prevhdr;
751 *prevhoff = prev_nhoff;
752 *fhoff = start;
753
754 return 0;
755}
756
757struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
758{
759 struct sk_buff *clone;
760 struct net_device *dev = skb->dev;
761 struct frag_hdr *fhdr;
762 struct nf_ct_frag6_queue *fq;
763 struct ipv6hdr *hdr;
764 int fhoff, nhoff;
765 u8 prevhdr;
766 struct sk_buff *ret_skb = NULL;
767
768 /* Jumbo payload inhibits frag. header */
769 if (skb->nh.ipv6h->payload_len == 0) {
770 DEBUGP("payload len = 0\n");
771 return skb;
772 }
773
774 if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0)
775 return skb;
776
777 clone = skb_clone(skb, GFP_ATOMIC);
778 if (clone == NULL) {
779 DEBUGP("Can't clone skb\n");
780 return skb;
781 }
782
783 NFCT_FRAG6_CB(clone)->orig = skb;
784
785 if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
786 DEBUGP("message is too short.\n");
787 goto ret_orig;
788 }
789
790 clone->h.raw = clone->data + fhoff;
791 hdr = clone->nh.ipv6h;
792 fhdr = (struct frag_hdr *)clone->h.raw;
793
794 if (!(fhdr->frag_off & htons(0xFFF9))) {
795 DEBUGP("Invalid fragment offset\n");
796 /* It is not a fragmented frame */
797 goto ret_orig;
798 }
799
800 if (atomic_read(&nf_ct_frag6_mem) > nf_ct_frag6_high_thresh)
801 nf_ct_frag6_evictor();
802
803 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
804 if (fq == NULL) {
805 DEBUGP("Can't find and can't create new queue\n");
806 goto ret_orig;
807 }
808
809 spin_lock(&fq->lock);
810
811 if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
812 spin_unlock(&fq->lock);
813 DEBUGP("Can't insert skb to queue\n");
814 fq_put(fq);
815 goto ret_orig;
816 }
817
818 if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) {
819 ret_skb = nf_ct_frag6_reasm(fq, dev);
820 if (ret_skb == NULL)
821 DEBUGP("Can't reassemble fragmented packets\n");
822 }
823 spin_unlock(&fq->lock);
824
825 fq_put(fq);
826 return ret_skb;
827
828ret_orig:
829 kfree_skb(clone);
830 return skb;
831}
832
833void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
834 struct net_device *in, struct net_device *out,
835 int (*okfn)(struct sk_buff *))
836{
837 struct sk_buff *s, *s2;
838
839 for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
840 nf_conntrack_put_reasm(s->nfct_reasm);
841 nf_conntrack_get_reasm(skb);
842 s->nfct_reasm = skb;
843
844 s2 = s->next;
845 NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn,
846 NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
847 s = s2;
848 }
849 nf_conntrack_put_reasm(skb);
850}
851
852int nf_ct_frag6_kfree_frags(struct sk_buff *skb)
853{
854 struct sk_buff *s, *s2;
855
856 for (s = NFCT_FRAG6_CB(skb)->orig; s; s = s2) {
857
858 s2 = s->next;
859 kfree_skb(s);
860 }
861
862 kfree_skb(skb);
863
864 return 0;
865}
866
867int nf_ct_frag6_init(void)
868{
869 nf_ct_frag6_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
870 (jiffies ^ (jiffies >> 6)));
871
872 init_timer(&nf_ct_frag6_secret_timer);
873 nf_ct_frag6_secret_timer.function = nf_ct_frag6_secret_rebuild;
874 nf_ct_frag6_secret_timer.expires = jiffies
875 + nf_ct_frag6_secret_interval;
876 add_timer(&nf_ct_frag6_secret_timer);
877
878 return 0;
879}
880
881void nf_ct_frag6_cleanup(void)
882{
883 del_timer(&nf_ct_frag6_secret_timer);
884 nf_ct_frag6_evictor();
885}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a1265a320b11..8e9628f1c4c5 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -174,8 +174,10 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
174 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); 174 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
175 175
176 /* Not releasing hash table! */ 176 /* Not releasing hash table! */
177 if (clone) 177 if (clone) {
178 nf_reset(clone);
178 rawv6_rcv(sk, clone); 179 rawv6_rcv(sk, clone);
180 }
179 } 181 }
180 sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr, 182 sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
181 IP6CB(skb)->iif); 183 IP6CB(skb)->iif);
@@ -296,13 +298,10 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb,
296static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) 298static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
297{ 299{
298 if ((raw6_sk(sk)->checksum || sk->sk_filter) && 300 if ((raw6_sk(sk)->checksum || sk->sk_filter) &&
299 skb->ip_summed != CHECKSUM_UNNECESSARY) { 301 skb_checksum_complete(skb)) {
300 if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { 302 /* FIXME: increment a raw6 drops counter here */
301 /* FIXME: increment a raw6 drops counter here */ 303 kfree_skb(skb);
302 kfree_skb(skb); 304 return 0;
303 return 0;
304 }
305 skb->ip_summed = CHECKSUM_UNNECESSARY;
306 } 305 }
307 306
308 /* Charge it to the socket. */ 307 /* Charge it to the socket. */
@@ -335,32 +334,25 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
335 if (!rp->checksum) 334 if (!rp->checksum)
336 skb->ip_summed = CHECKSUM_UNNECESSARY; 335 skb->ip_summed = CHECKSUM_UNNECESSARY;
337 336
338 if (skb->ip_summed != CHECKSUM_UNNECESSARY) { 337 if (skb->ip_summed == CHECKSUM_HW) {
339 if (skb->ip_summed == CHECKSUM_HW) { 338 skb_postpull_rcsum(skb, skb->nh.raw,
340 skb_postpull_rcsum(skb, skb->nh.raw, 339 skb->h.raw - skb->nh.raw);
341 skb->h.raw - skb->nh.raw); 340 if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr,
341 &skb->nh.ipv6h->daddr,
342 skb->len, inet->num, skb->csum))
342 skb->ip_summed = CHECKSUM_UNNECESSARY; 343 skb->ip_summed = CHECKSUM_UNNECESSARY;
343 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
344 &skb->nh.ipv6h->daddr,
345 skb->len, inet->num, skb->csum)) {
346 LIMIT_NETDEBUG(KERN_DEBUG "raw v6 hw csum failure.\n");
347 skb->ip_summed = CHECKSUM_NONE;
348 }
349 }
350 if (skb->ip_summed == CHECKSUM_NONE)
351 skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
352 &skb->nh.ipv6h->daddr,
353 skb->len, inet->num, 0);
354 } 344 }
345 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
346 skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
347 &skb->nh.ipv6h->daddr,
348 skb->len, inet->num, 0);
355 349
356 if (inet->hdrincl) { 350 if (inet->hdrincl) {
357 if (skb->ip_summed != CHECKSUM_UNNECESSARY && 351 if (skb_checksum_complete(skb)) {
358 (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
359 /* FIXME: increment a raw6 drops counter here */ 352 /* FIXME: increment a raw6 drops counter here */
360 kfree_skb(skb); 353 kfree_skb(skb);
361 return 0; 354 return 0;
362 } 355 }
363 skb->ip_summed = CHECKSUM_UNNECESSARY;
364 } 356 }
365 357
366 rawv6_rcv_skb(sk, skb); 358 rawv6_rcv_skb(sk, skb);
@@ -405,7 +397,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
405 if (skb->ip_summed==CHECKSUM_UNNECESSARY) { 397 if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
406 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 398 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
407 } else if (msg->msg_flags&MSG_TRUNC) { 399 } else if (msg->msg_flags&MSG_TRUNC) {
408 if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) 400 if (__skb_checksum_complete(skb))
409 goto csum_copy_err; 401 goto csum_copy_err;
410 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 402 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
411 } else { 403 } else {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 227e99ed510c..f7f42c3e96cb 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1710,7 +1710,7 @@ static void fib6_dump_end(struct netlink_callback *cb)
1710static int fib6_dump_done(struct netlink_callback *cb) 1710static int fib6_dump_done(struct netlink_callback *cb)
1711{ 1711{
1712 fib6_dump_end(cb); 1712 fib6_dump_end(cb);
1713 return cb->done(cb); 1713 return cb->done ? cb->done(cb) : 0;
1714} 1714}
1715 1715
1716int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) 1716int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index d746d3b27efb..62c0e5bd931c 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1401,20 +1401,18 @@ out:
1401static int tcp_v6_checksum_init(struct sk_buff *skb) 1401static int tcp_v6_checksum_init(struct sk_buff *skb)
1402{ 1402{
1403 if (skb->ip_summed == CHECKSUM_HW) { 1403 if (skb->ip_summed == CHECKSUM_HW) {
1404 skb->ip_summed = CHECKSUM_UNNECESSARY;
1405 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1404 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1406 &skb->nh.ipv6h->daddr,skb->csum)) 1405 &skb->nh.ipv6h->daddr,skb->csum)) {
1406 skb->ip_summed = CHECKSUM_UNNECESSARY;
1407 return 0; 1407 return 0;
1408 LIMIT_NETDEBUG(KERN_DEBUG "hw tcp v6 csum failed\n"); 1408 }
1409 } 1409 }
1410
1411 skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1412 &skb->nh.ipv6h->daddr, 0);
1413
1410 if (skb->len <= 76) { 1414 if (skb->len <= 76) {
1411 if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1415 return __skb_checksum_complete(skb);
1412 &skb->nh.ipv6h->daddr,skb_checksum(skb, 0, skb->len, 0)))
1413 return -1;
1414 skb->ip_summed = CHECKSUM_UNNECESSARY;
1415 } else {
1416 skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1417 &skb->nh.ipv6h->daddr,0);
1418 } 1416 }
1419 return 0; 1417 return 0;
1420} 1418}
@@ -1575,7 +1573,7 @@ static int tcp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
1575 goto discard_it; 1573 goto discard_it;
1576 1574
1577 if ((skb->ip_summed != CHECKSUM_UNNECESSARY && 1575 if ((skb->ip_summed != CHECKSUM_UNNECESSARY &&
1578 tcp_v6_checksum_init(skb) < 0)) 1576 tcp_v6_checksum_init(skb)))
1579 goto bad_packet; 1577 goto bad_packet;
1580 1578
1581 th = skb->h.th; 1579 th = skb->h.th;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index bf9519341fd3..e671153b47b2 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -248,7 +248,7 @@ try_again:
248 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 248 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
249 copied); 249 copied);
250 } else if (msg->msg_flags&MSG_TRUNC) { 250 } else if (msg->msg_flags&MSG_TRUNC) {
251 if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) 251 if (__skb_checksum_complete(skb))
252 goto csum_copy_err; 252 goto csum_copy_err;
253 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 253 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
254 copied); 254 copied);
@@ -363,13 +363,10 @@ static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
363 return -1; 363 return -1;
364 } 364 }
365 365
366 if (skb->ip_summed != CHECKSUM_UNNECESSARY) { 366 if (skb_checksum_complete(skb)) {
367 if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { 367 UDP6_INC_STATS_BH(UDP_MIB_INERRORS);
368 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 368 kfree_skb(skb);
369 kfree_skb(skb); 369 return 0;
370 return 0;
371 }
372 skb->ip_summed = CHECKSUM_UNNECESSARY;
373 } 370 }
374 371
375 if (sock_queue_rcv_skb(sk,skb)<0) { 372 if (sock_queue_rcv_skb(sk,skb)<0) {
@@ -491,13 +488,10 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
491 uh = skb->h.uh; 488 uh = skb->h.uh;
492 } 489 }
493 490
494 if (skb->ip_summed==CHECKSUM_HW) { 491 if (skb->ip_summed == CHECKSUM_HW &&
492 !csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum))
495 skb->ip_summed = CHECKSUM_UNNECESSARY; 493 skb->ip_summed = CHECKSUM_UNNECESSARY;
496 if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) { 494
497 LIMIT_NETDEBUG(KERN_DEBUG "udp v6 hw csum failure.\n");
498 skb->ip_summed = CHECKSUM_NONE;
499 }
500 }
501 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 495 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
502 skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0); 496 skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0);
503 497
@@ -521,8 +515,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
521 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 515 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
522 goto discard; 516 goto discard;
523 517
524 if (skb->ip_summed != CHECKSUM_UNNECESSARY && 518 if (skb_checksum_complete(skb))
525 (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
526 goto discard; 519 goto discard;
527 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS); 520 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS);
528 521
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 8296b38bf270..a84f9221e5f0 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -1,3 +1,6 @@
1menu "Core Netfilter Configuration"
2 depends on NET && NETFILTER
3
1config NETFILTER_NETLINK 4config NETFILTER_NETLINK
2 tristate "Netfilter netlink interface" 5 tristate "Netfilter netlink interface"
3 help 6 help
@@ -22,3 +25,74 @@ config NETFILTER_NETLINK_LOG
22 and is also scheduled to replace the old syslog-based ipt_LOG 25 and is also scheduled to replace the old syslog-based ipt_LOG
23 and ip6t_LOG modules. 26 and ip6t_LOG modules.
24 27
28config NF_CONNTRACK
29 tristate "Layer 3 Independent Connection tracking (EXPERIMENTAL)"
30 depends on EXPERIMENTAL && IP_NF_CONNTRACK=n
31 default n
32 ---help---
33 Connection tracking keeps a record of what packets have passed
34 through your machine, in order to figure out how they are related
35 into connections.
36
37 Layer 3 independent connection tracking is experimental scheme
38 which generalize ip_conntrack to support other layer 3 protocols.
39
40 To compile it as a module, choose M here. If unsure, say N.
41
42config NF_CT_ACCT
43 bool "Connection tracking flow accounting"
44 depends on NF_CONNTRACK
45 help
46 If this option is enabled, the connection tracking code will
47 keep per-flow packet and byte counters.
48
49 Those counters can be used for flow-based accounting or the
50 `connbytes' match.
51
52 If unsure, say `N'.
53
54config NF_CONNTRACK_MARK
55 bool 'Connection mark tracking support'
56 depends on NF_CONNTRACK
57 help
58 This option enables support for connection marks, used by the
59 `CONNMARK' target and `connmark' match. Similar to the mark value
60 of packets, but this mark value is kept in the conntrack session
61 instead of the individual packets.
62
63config NF_CONNTRACK_EVENTS
64 bool "Connection tracking events"
65 depends on NF_CONNTRACK
66 help
67 If this option is enabled, the connection tracking code will
68 provide a notifier chain that can be used by other kernel code
69 to get notified aboutchanges in the connection tracking state.
70
71 If unsure, say `N'.
72
73config NF_CT_PROTO_SCTP
74 tristate 'SCTP protocol on new connection tracking support (EXPERIMENTAL)'
75 depends on EXPERIMENTAL && NF_CONNTRACK
76 default n
77 help
78 With this option enabled, the layer 3 independent connection
79 tracking code will be able to do state tracking on SCTP connections.
80
81 If you want to compile it as a module, say M here and read
82 Documentation/modules.txt. If unsure, say `N'.
83
84config NF_CONNTRACK_FTP
85 tristate "FTP support on new connection tracking (EXPERIMENTAL)"
86 depends on EXPERIMENTAL && NF_CONNTRACK
87 help
88 Tracking FTP connections is problematic: special helpers are
89 required for tracking them, and doing masquerading and other forms
90 of Network Address Translation on them.
91
92 This is FTP support on Layer 3 independent connection tracking.
93 Layer 3 independent connection tracking is experimental scheme
94 which generalize ip_conntrack to support other layer 3 protocols.
95
96 To compile it as a module, choose M here. If unsure, say N.
97
98endmenu
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index b3b44f8b415a..55f019ad2c08 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -5,3 +5,11 @@ obj-$(CONFIG_NETFILTER) = netfilter.o
5obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o 5obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
6obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o 6obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
7obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o 7obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
8
9nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o
10
11obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
12obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
13
14# SCTP protocol connection tracking
15obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
new file mode 100644
index 000000000000..9a67c796b385
--- /dev/null
+++ b/net/netfilter/nf_conntrack_core.c
@@ -0,0 +1,1538 @@
1/* Connection state tracking for netfilter. This is separated from,
2 but required by, the NAT layer; it can also be used by an iptables
3 extension. */
4
5/* (C) 1999-2001 Paul `Rusty' Russell
6 * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
7 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * 23 Apr 2001: Harald Welte <laforge@gnumonks.org>
14 * - new API and handling of conntrack/nat helpers
15 * - now capable of multiple expectations for one master
16 * 16 Jul 2002: Harald Welte <laforge@gnumonks.org>
17 * - add usage/reference counts to ip_conntrack_expect
18 * - export ip_conntrack[_expect]_{find_get,put} functions
19 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
20 * - generalize L3 protocol denendent part.
21 * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
22 * - add support various size of conntrack structures.
23 *
24 * Derived from net/ipv4/netfilter/ip_conntrack_core.c
25 */
26
27#include <linux/config.h>
28#include <linux/types.h>
29#include <linux/netfilter.h>
30#include <linux/module.h>
31#include <linux/skbuff.h>
32#include <linux/proc_fs.h>
33#include <linux/vmalloc.h>
34#include <linux/stddef.h>
35#include <linux/slab.h>
36#include <linux/random.h>
37#include <linux/jhash.h>
38#include <linux/err.h>
39#include <linux/percpu.h>
40#include <linux/moduleparam.h>
41#include <linux/notifier.h>
42#include <linux/kernel.h>
43#include <linux/netdevice.h>
44#include <linux/socket.h>
45
46/* This rwlock protects the main hash table, protocol/helper/expected
47 registrations, conntrack timers*/
48#define ASSERT_READ_LOCK(x)
49#define ASSERT_WRITE_LOCK(x)
50
51#include <net/netfilter/nf_conntrack.h>
52#include <net/netfilter/nf_conntrack_l3proto.h>
53#include <net/netfilter/nf_conntrack_protocol.h>
54#include <net/netfilter/nf_conntrack_helper.h>
55#include <net/netfilter/nf_conntrack_core.h>
56#include <linux/netfilter_ipv4/listhelp.h>
57
58#define NF_CONNTRACK_VERSION "0.4.1"
59
60#if 0
61#define DEBUGP printk
62#else
63#define DEBUGP(format, args...)
64#endif
65
66DEFINE_RWLOCK(nf_conntrack_lock);
67
68/* nf_conntrack_standalone needs this */
69atomic_t nf_conntrack_count = ATOMIC_INIT(0);
70
71void (*nf_conntrack_destroyed)(struct nf_conn *conntrack) = NULL;
72LIST_HEAD(nf_conntrack_expect_list);
73struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
74struct nf_conntrack_l3proto *nf_ct_l3protos[PF_MAX];
75static LIST_HEAD(helpers);
76unsigned int nf_conntrack_htable_size = 0;
77int nf_conntrack_max;
78struct list_head *nf_conntrack_hash;
79static kmem_cache_t *nf_conntrack_expect_cachep;
80struct nf_conn nf_conntrack_untracked;
81unsigned int nf_ct_log_invalid;
82static LIST_HEAD(unconfirmed);
83static int nf_conntrack_vmalloc;
84
85#ifdef CONFIG_NF_CONNTRACK_EVENTS
86struct notifier_block *nf_conntrack_chain;
87struct notifier_block *nf_conntrack_expect_chain;
88
89DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
90
91/* deliver cached events and clear cache entry - must be called with locally
92 * disabled softirqs */
93static inline void
94__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
95{
96 DEBUGP("ecache: delivering events for %p\n", ecache->ct);
97 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
98 && ecache->events)
99 notifier_call_chain(&nf_conntrack_chain, ecache->events,
100 ecache->ct);
101
102 ecache->events = 0;
103 nf_ct_put(ecache->ct);
104 ecache->ct = NULL;
105}
106
107/* Deliver all cached events for a particular conntrack. This is called
108 * by code prior to async packet handling for freeing the skb */
109void nf_ct_deliver_cached_events(const struct nf_conn *ct)
110{
111 struct nf_conntrack_ecache *ecache;
112
113 local_bh_disable();
114 ecache = &__get_cpu_var(nf_conntrack_ecache);
115 if (ecache->ct == ct)
116 __nf_ct_deliver_cached_events(ecache);
117 local_bh_enable();
118}
119
120/* Deliver cached events for old pending events, if current conntrack != old */
121void __nf_ct_event_cache_init(struct nf_conn *ct)
122{
123 struct nf_conntrack_ecache *ecache;
124
125 /* take care of delivering potentially old events */
126 ecache = &__get_cpu_var(nf_conntrack_ecache);
127 BUG_ON(ecache->ct == ct);
128 if (ecache->ct)
129 __nf_ct_deliver_cached_events(ecache);
130 /* initialize for this conntrack/packet */
131 ecache->ct = ct;
132 nf_conntrack_get(&ct->ct_general);
133}
134
135/* flush the event cache - touches other CPU's data and must not be called
136 * while packets are still passing through the code */
137static void nf_ct_event_cache_flush(void)
138{
139 struct nf_conntrack_ecache *ecache;
140 int cpu;
141
142 for_each_cpu(cpu) {
143 ecache = &per_cpu(nf_conntrack_ecache, cpu);
144 if (ecache->ct)
145 nf_ct_put(ecache->ct);
146 }
147}
148#else
149static inline void nf_ct_event_cache_flush(void) {}
150#endif /* CONFIG_NF_CONNTRACK_EVENTS */
151
152DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
153EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
154
155/*
156 * This scheme offers various size of "struct nf_conn" dependent on
157 * features(helper, nat, ...)
158 */
159
160#define NF_CT_FEATURES_NAMELEN 256
161static struct {
162 /* name of slab cache. printed in /proc/slabinfo */
163 char *name;
164
165 /* size of slab cache */
166 size_t size;
167
168 /* slab cache pointer */
169 kmem_cache_t *cachep;
170
171 /* allocated slab cache + modules which uses this slab cache */
172 int use;
173
174 /* Initialization */
175 int (*init_conntrack)(struct nf_conn *, u_int32_t);
176
177} nf_ct_cache[NF_CT_F_NUM];
178
179/* protect members of nf_ct_cache except of "use" */
180DEFINE_RWLOCK(nf_ct_cache_lock);
181
182/* This avoids calling kmem_cache_create() with same name simultaneously */
183DECLARE_MUTEX(nf_ct_cache_mutex);
184
185extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
186struct nf_conntrack_protocol *
187nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol)
188{
189 if (unlikely(nf_ct_protos[l3proto] == NULL))
190 return &nf_conntrack_generic_protocol;
191
192 return nf_ct_protos[l3proto][protocol];
193}
194
195static int nf_conntrack_hash_rnd_initted;
196static unsigned int nf_conntrack_hash_rnd;
197
198static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
199 unsigned int size, unsigned int rnd)
200{
201 unsigned int a, b;
202 a = jhash((void *)tuple->src.u3.all, sizeof(tuple->src.u3.all),
203 ((tuple->src.l3num) << 16) | tuple->dst.protonum);
204 b = jhash((void *)tuple->dst.u3.all, sizeof(tuple->dst.u3.all),
205 (tuple->src.u.all << 16) | tuple->dst.u.all);
206
207 return jhash_2words(a, b, rnd) % size;
208}
209
210static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
211{
212 return __hash_conntrack(tuple, nf_conntrack_htable_size,
213 nf_conntrack_hash_rnd);
214}
215
216/* Initialize "struct nf_conn" which has spaces for helper */
217static int
218init_conntrack_for_helper(struct nf_conn *conntrack, u_int32_t features)
219{
220
221 conntrack->help = (union nf_conntrack_help *)
222 (((unsigned long)conntrack->data
223 + (__alignof__(union nf_conntrack_help) - 1))
224 & (~((unsigned long)(__alignof__(union nf_conntrack_help) -1))));
225 return 0;
226}
227
228int nf_conntrack_register_cache(u_int32_t features, const char *name,
229 size_t size,
230 int (*init)(struct nf_conn *, u_int32_t))
231{
232 int ret = 0;
233 char *cache_name;
234 kmem_cache_t *cachep;
235
236 DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n",
237 features, name, size);
238
239 if (features < NF_CT_F_BASIC || features >= NF_CT_F_NUM) {
240 DEBUGP("nf_conntrack_register_cache: invalid features.: 0x%x\n",
241 features);
242 return -EINVAL;
243 }
244
245 down(&nf_ct_cache_mutex);
246
247 write_lock_bh(&nf_ct_cache_lock);
248 /* e.g: multiple helpers are loaded */
249 if (nf_ct_cache[features].use > 0) {
250 DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
251 if ((!strncmp(nf_ct_cache[features].name, name,
252 NF_CT_FEATURES_NAMELEN))
253 && nf_ct_cache[features].size == size
254 && nf_ct_cache[features].init_conntrack == init) {
255 DEBUGP("nf_conntrack_register_cache: reusing.\n");
256 nf_ct_cache[features].use++;
257 ret = 0;
258 } else
259 ret = -EBUSY;
260
261 write_unlock_bh(&nf_ct_cache_lock);
262 up(&nf_ct_cache_mutex);
263 return ret;
264 }
265 write_unlock_bh(&nf_ct_cache_lock);
266
267 /*
268 * The memory space for name of slab cache must be alive until
269 * cache is destroyed.
270 */
271 cache_name = kmalloc(sizeof(char)*NF_CT_FEATURES_NAMELEN, GFP_ATOMIC);
272 if (cache_name == NULL) {
273 DEBUGP("nf_conntrack_register_cache: can't alloc cache_name\n");
274 ret = -ENOMEM;
275 goto out_up_mutex;
276 }
277
278 if (strlcpy(cache_name, name, NF_CT_FEATURES_NAMELEN)
279 >= NF_CT_FEATURES_NAMELEN) {
280 printk("nf_conntrack_register_cache: name too long\n");
281 ret = -EINVAL;
282 goto out_free_name;
283 }
284
285 cachep = kmem_cache_create(cache_name, size, 0, 0,
286 NULL, NULL);
287 if (!cachep) {
288 printk("nf_conntrack_register_cache: Can't create slab cache "
289 "for the features = 0x%x\n", features);
290 ret = -ENOMEM;
291 goto out_free_name;
292 }
293
294 write_lock_bh(&nf_ct_cache_lock);
295 nf_ct_cache[features].use = 1;
296 nf_ct_cache[features].size = size;
297 nf_ct_cache[features].init_conntrack = init;
298 nf_ct_cache[features].cachep = cachep;
299 nf_ct_cache[features].name = cache_name;
300 write_unlock_bh(&nf_ct_cache_lock);
301
302 goto out_up_mutex;
303
304out_free_name:
305 kfree(cache_name);
306out_up_mutex:
307 up(&nf_ct_cache_mutex);
308 return ret;
309}
310
311/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */
312void nf_conntrack_unregister_cache(u_int32_t features)
313{
314 kmem_cache_t *cachep;
315 char *name;
316
317 /*
318 * This assures that kmem_cache_create() isn't called before destroying
319 * slab cache.
320 */
321 DEBUGP("nf_conntrack_unregister_cache: 0x%04x\n", features);
322 down(&nf_ct_cache_mutex);
323
324 write_lock_bh(&nf_ct_cache_lock);
325 if (--nf_ct_cache[features].use > 0) {
326 write_unlock_bh(&nf_ct_cache_lock);
327 up(&nf_ct_cache_mutex);
328 return;
329 }
330 cachep = nf_ct_cache[features].cachep;
331 name = nf_ct_cache[features].name;
332 nf_ct_cache[features].cachep = NULL;
333 nf_ct_cache[features].name = NULL;
334 nf_ct_cache[features].init_conntrack = NULL;
335 nf_ct_cache[features].size = 0;
336 write_unlock_bh(&nf_ct_cache_lock);
337
338 synchronize_net();
339
340 kmem_cache_destroy(cachep);
341 kfree(name);
342
343 up(&nf_ct_cache_mutex);
344}
345
346int
347nf_ct_get_tuple(const struct sk_buff *skb,
348 unsigned int nhoff,
349 unsigned int dataoff,
350 u_int16_t l3num,
351 u_int8_t protonum,
352 struct nf_conntrack_tuple *tuple,
353 const struct nf_conntrack_l3proto *l3proto,
354 const struct nf_conntrack_protocol *protocol)
355{
356 NF_CT_TUPLE_U_BLANK(tuple);
357
358 tuple->src.l3num = l3num;
359 if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
360 return 0;
361
362 tuple->dst.protonum = protonum;
363 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
364
365 return protocol->pkt_to_tuple(skb, dataoff, tuple);
366}
367
368int
369nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
370 const struct nf_conntrack_tuple *orig,
371 const struct nf_conntrack_l3proto *l3proto,
372 const struct nf_conntrack_protocol *protocol)
373{
374 NF_CT_TUPLE_U_BLANK(inverse);
375
376 inverse->src.l3num = orig->src.l3num;
377 if (l3proto->invert_tuple(inverse, orig) == 0)
378 return 0;
379
380 inverse->dst.dir = !orig->dst.dir;
381
382 inverse->dst.protonum = orig->dst.protonum;
383 return protocol->invert_tuple(inverse, orig);
384}
385
386/* nf_conntrack_expect helper functions */
387static void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
388{
389 ASSERT_WRITE_LOCK(&nf_conntrack_lock);
390 NF_CT_ASSERT(!timer_pending(&exp_timeout));
391 list_del(&exp->list);
392 NF_CT_STAT_INC(expect_delete);
393 exp->master->expecting--;
394 nf_conntrack_expect_put(exp);
395}
396
397static void expectation_timed_out(unsigned long ul_expect)
398{
399 struct nf_conntrack_expect *exp = (void *)ul_expect;
400
401 write_lock_bh(&nf_conntrack_lock);
402 nf_ct_unlink_expect(exp);
403 write_unlock_bh(&nf_conntrack_lock);
404 nf_conntrack_expect_put(exp);
405}
406
407/* If an expectation for this connection is found, it gets delete from
408 * global list then returned. */
409static struct nf_conntrack_expect *
410find_expectation(const struct nf_conntrack_tuple *tuple)
411{
412 struct nf_conntrack_expect *i;
413
414 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
415 /* If master is not in hash table yet (ie. packet hasn't left
416 this machine yet), how can other end know about expected?
417 Hence these are not the droids you are looking for (if
418 master ct never got confirmed, we'd hold a reference to it
419 and weird things would happen to future packets). */
420 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
421 && nf_ct_is_confirmed(i->master)) {
422 if (i->flags & NF_CT_EXPECT_PERMANENT) {
423 atomic_inc(&i->use);
424 return i;
425 } else if (del_timer(&i->timeout)) {
426 nf_ct_unlink_expect(i);
427 return i;
428 }
429 }
430 }
431 return NULL;
432}
433
434/* delete all expectations for this conntrack */
435static void remove_expectations(struct nf_conn *ct)
436{
437 struct nf_conntrack_expect *i, *tmp;
438
439 /* Optimization: most connection never expect any others. */
440 if (ct->expecting == 0)
441 return;
442
443 list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
444 if (i->master == ct && del_timer(&i->timeout)) {
445 nf_ct_unlink_expect(i);
446 nf_conntrack_expect_put(i);
447 }
448 }
449}
450
451static void
452clean_from_lists(struct nf_conn *ct)
453{
454 unsigned int ho, hr;
455
456 DEBUGP("clean_from_lists(%p)\n", ct);
457 ASSERT_WRITE_LOCK(&nf_conntrack_lock);
458
459 ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
460 hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
461 LIST_DELETE(&nf_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
462 LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]);
463
464 /* Destroy all pending expectations */
465 remove_expectations(ct);
466}
467
468static void
469destroy_conntrack(struct nf_conntrack *nfct)
470{
471 struct nf_conn *ct = (struct nf_conn *)nfct;
472 struct nf_conntrack_l3proto *l3proto;
473 struct nf_conntrack_protocol *proto;
474
475 DEBUGP("destroy_conntrack(%p)\n", ct);
476 NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
477 NF_CT_ASSERT(!timer_pending(&ct->timeout));
478
479 nf_conntrack_event(IPCT_DESTROY, ct);
480 set_bit(IPS_DYING_BIT, &ct->status);
481
482 /* To make sure we don't get any weird locking issues here:
483 * destroy_conntrack() MUST NOT be called with a write lock
484 * to nf_conntrack_lock!!! -HW */
485 l3proto = nf_ct_find_l3proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num);
486 if (l3proto && l3proto->destroy)
487 l3proto->destroy(ct);
488
489 proto = nf_ct_find_proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num,
490 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
491 if (proto && proto->destroy)
492 proto->destroy(ct);
493
494 if (nf_conntrack_destroyed)
495 nf_conntrack_destroyed(ct);
496
497 write_lock_bh(&nf_conntrack_lock);
498 /* Expectations will have been removed in clean_from_lists,
499 * except TFTP can create an expectation on the first packet,
500 * before connection is in the list, so we need to clean here,
501 * too. */
502 remove_expectations(ct);
503
504 /* We overload first tuple to link into unconfirmed list. */
505 if (!nf_ct_is_confirmed(ct)) {
506 BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
507 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
508 }
509
510 NF_CT_STAT_INC(delete);
511 write_unlock_bh(&nf_conntrack_lock);
512
513 if (ct->master)
514 nf_ct_put(ct->master);
515
516 DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
517 nf_conntrack_free(ct);
518}
519
520static void death_by_timeout(unsigned long ul_conntrack)
521{
522 struct nf_conn *ct = (void *)ul_conntrack;
523
524 write_lock_bh(&nf_conntrack_lock);
525 /* Inside lock so preempt is disabled on module removal path.
526 * Otherwise we can get spurious warnings. */
527 NF_CT_STAT_INC(delete_list);
528 clean_from_lists(ct);
529 write_unlock_bh(&nf_conntrack_lock);
530 nf_ct_put(ct);
531}
532
533static inline int
534conntrack_tuple_cmp(const struct nf_conntrack_tuple_hash *i,
535 const struct nf_conntrack_tuple *tuple,
536 const struct nf_conn *ignored_conntrack)
537{
538 ASSERT_READ_LOCK(&nf_conntrack_lock);
539 return nf_ct_tuplehash_to_ctrack(i) != ignored_conntrack
540 && nf_ct_tuple_equal(tuple, &i->tuple);
541}
542
543static struct nf_conntrack_tuple_hash *
544__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
545 const struct nf_conn *ignored_conntrack)
546{
547 struct nf_conntrack_tuple_hash *h;
548 unsigned int hash = hash_conntrack(tuple);
549
550 ASSERT_READ_LOCK(&nf_conntrack_lock);
551 list_for_each_entry(h, &nf_conntrack_hash[hash], list) {
552 if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) {
553 NF_CT_STAT_INC(found);
554 return h;
555 }
556 NF_CT_STAT_INC(searched);
557 }
558
559 return NULL;
560}
561
562/* Find a connection corresponding to a tuple. */
563struct nf_conntrack_tuple_hash *
564nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
565 const struct nf_conn *ignored_conntrack)
566{
567 struct nf_conntrack_tuple_hash *h;
568
569 read_lock_bh(&nf_conntrack_lock);
570 h = __nf_conntrack_find(tuple, ignored_conntrack);
571 if (h)
572 atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
573 read_unlock_bh(&nf_conntrack_lock);
574
575 return h;
576}
577
578/* Confirm a connection given skb; places it in hash table */
579int
580__nf_conntrack_confirm(struct sk_buff **pskb)
581{
582 unsigned int hash, repl_hash;
583 struct nf_conn *ct;
584 enum ip_conntrack_info ctinfo;
585
586 ct = nf_ct_get(*pskb, &ctinfo);
587
588 /* ipt_REJECT uses nf_conntrack_attach to attach related
589 ICMP/TCP RST packets in other direction. Actual packet
590 which created connection will be IP_CT_NEW or for an
591 expected connection, IP_CT_RELATED. */
592 if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
593 return NF_ACCEPT;
594
595 hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
596 repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
597
598 /* We're not in hash table, and we refuse to set up related
599 connections for unconfirmed conns. But packet copies and
600 REJECT will give spurious warnings here. */
601 /* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */
602
603 /* No external references means noone else could have
604 confirmed us. */
605 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
606 DEBUGP("Confirming conntrack %p\n", ct);
607
608 write_lock_bh(&nf_conntrack_lock);
609
610 /* See if there's one in the list already, including reverse:
611 NAT could have grabbed it without realizing, since we're
612 not in the hash. If there is, we lost race. */
613 if (!LIST_FIND(&nf_conntrack_hash[hash],
614 conntrack_tuple_cmp,
615 struct nf_conntrack_tuple_hash *,
616 &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, NULL)
617 && !LIST_FIND(&nf_conntrack_hash[repl_hash],
618 conntrack_tuple_cmp,
619 struct nf_conntrack_tuple_hash *,
620 &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
621 /* Remove from unconfirmed list */
622 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
623
624 list_prepend(&nf_conntrack_hash[hash],
625 &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
626 list_prepend(&nf_conntrack_hash[repl_hash],
627 &ct->tuplehash[IP_CT_DIR_REPLY]);
628 /* Timer relative to confirmation time, not original
629 setting time, otherwise we'd get timer wrap in
630 weird delay cases. */
631 ct->timeout.expires += jiffies;
632 add_timer(&ct->timeout);
633 atomic_inc(&ct->ct_general.use);
634 set_bit(IPS_CONFIRMED_BIT, &ct->status);
635 NF_CT_STAT_INC(insert);
636 write_unlock_bh(&nf_conntrack_lock);
637 if (ct->helper)
638 nf_conntrack_event_cache(IPCT_HELPER, *pskb);
639#ifdef CONFIG_NF_NAT_NEEDED
640 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
641 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
642 nf_conntrack_event_cache(IPCT_NATINFO, *pskb);
643#endif
644 nf_conntrack_event_cache(master_ct(ct) ?
645 IPCT_RELATED : IPCT_NEW, *pskb);
646 return NF_ACCEPT;
647 }
648
649 NF_CT_STAT_INC(insert_failed);
650 write_unlock_bh(&nf_conntrack_lock);
651 return NF_DROP;
652}
653
654/* Returns true if a connection correspondings to the tuple (required
655 for NAT). */
656int
657nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
658 const struct nf_conn *ignored_conntrack)
659{
660 struct nf_conntrack_tuple_hash *h;
661
662 read_lock_bh(&nf_conntrack_lock);
663 h = __nf_conntrack_find(tuple, ignored_conntrack);
664 read_unlock_bh(&nf_conntrack_lock);
665
666 return h != NULL;
667}
668
669/* There's a small race here where we may free a just-assured
670 connection. Too bad: we're in trouble anyway. */
671static inline int unreplied(const struct nf_conntrack_tuple_hash *i)
672{
673 return !(test_bit(IPS_ASSURED_BIT,
674 &nf_ct_tuplehash_to_ctrack(i)->status));
675}
676
677static int early_drop(struct list_head *chain)
678{
679 /* Traverse backwards: gives us oldest, which is roughly LRU */
680 struct nf_conntrack_tuple_hash *h;
681 struct nf_conn *ct = NULL;
682 int dropped = 0;
683
684 read_lock_bh(&nf_conntrack_lock);
685 h = LIST_FIND_B(chain, unreplied, struct nf_conntrack_tuple_hash *);
686 if (h) {
687 ct = nf_ct_tuplehash_to_ctrack(h);
688 atomic_inc(&ct->ct_general.use);
689 }
690 read_unlock_bh(&nf_conntrack_lock);
691
692 if (!ct)
693 return dropped;
694
695 if (del_timer(&ct->timeout)) {
696 death_by_timeout((unsigned long)ct);
697 dropped = 1;
698 NF_CT_STAT_INC(early_drop);
699 }
700 nf_ct_put(ct);
701 return dropped;
702}
703
704static inline int helper_cmp(const struct nf_conntrack_helper *i,
705 const struct nf_conntrack_tuple *rtuple)
706{
707 return nf_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask);
708}
709
710static struct nf_conntrack_helper *
711nf_ct_find_helper(const struct nf_conntrack_tuple *tuple)
712{
713 return LIST_FIND(&helpers, helper_cmp,
714 struct nf_conntrack_helper *,
715 tuple);
716}
717
718static struct nf_conn *
719__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
720 const struct nf_conntrack_tuple *repl,
721 const struct nf_conntrack_l3proto *l3proto)
722{
723 struct nf_conn *conntrack = NULL;
724 u_int32_t features = 0;
725
726 if (!nf_conntrack_hash_rnd_initted) {
727 get_random_bytes(&nf_conntrack_hash_rnd, 4);
728 nf_conntrack_hash_rnd_initted = 1;
729 }
730
731 if (nf_conntrack_max
732 && atomic_read(&nf_conntrack_count) >= nf_conntrack_max) {
733 unsigned int hash = hash_conntrack(orig);
734 /* Try dropping from this hash chain. */
735 if (!early_drop(&nf_conntrack_hash[hash])) {
736 if (net_ratelimit())
737 printk(KERN_WARNING
738 "nf_conntrack: table full, dropping"
739 " packet.\n");
740 return ERR_PTR(-ENOMEM);
741 }
742 }
743
744 /* find features needed by this conntrack. */
745 features = l3proto->get_features(orig);
746 read_lock_bh(&nf_conntrack_lock);
747 if (nf_ct_find_helper(repl) != NULL)
748 features |= NF_CT_F_HELP;
749 read_unlock_bh(&nf_conntrack_lock);
750
751 DEBUGP("nf_conntrack_alloc: features=0x%x\n", features);
752
753 read_lock_bh(&nf_ct_cache_lock);
754
755 if (!nf_ct_cache[features].use) {
756 DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
757 features);
758 goto out;
759 }
760
761 conntrack = kmem_cache_alloc(nf_ct_cache[features].cachep, GFP_ATOMIC);
762 if (conntrack == NULL) {
763 DEBUGP("nf_conntrack_alloc: Can't alloc conntrack from cache\n");
764 goto out;
765 }
766
767 memset(conntrack, 0, nf_ct_cache[features].size);
768 conntrack->features = features;
769 if (nf_ct_cache[features].init_conntrack &&
770 nf_ct_cache[features].init_conntrack(conntrack, features) < 0) {
771 DEBUGP("nf_conntrack_alloc: failed to init\n");
772 kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
773 conntrack = NULL;
774 goto out;
775 }
776
777 atomic_set(&conntrack->ct_general.use, 1);
778 conntrack->ct_general.destroy = destroy_conntrack;
779 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
780 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
781 /* Don't set timer yet: wait for confirmation */
782 init_timer(&conntrack->timeout);
783 conntrack->timeout.data = (unsigned long)conntrack;
784 conntrack->timeout.function = death_by_timeout;
785
786 atomic_inc(&nf_conntrack_count);
787out:
788 read_unlock_bh(&nf_ct_cache_lock);
789 return conntrack;
790}
791
792struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
793 const struct nf_conntrack_tuple *repl)
794{
795 struct nf_conntrack_l3proto *l3proto;
796
797 l3proto = nf_ct_find_l3proto(orig->src.l3num);
798 return __nf_conntrack_alloc(orig, repl, l3proto);
799}
800
801void nf_conntrack_free(struct nf_conn *conntrack)
802{
803 u_int32_t features = conntrack->features;
804 NF_CT_ASSERT(features >= NF_CT_F_BASIC && features < NF_CT_F_NUM);
805 DEBUGP("nf_conntrack_free: features = 0x%x, conntrack=%p\n", features,
806 conntrack);
807 kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
808 atomic_dec(&nf_conntrack_count);
809}
810
811/* Allocate a new conntrack: we return -ENOMEM if classification
812 failed due to stress. Otherwise it really is unclassifiable. */
813static struct nf_conntrack_tuple_hash *
814init_conntrack(const struct nf_conntrack_tuple *tuple,
815 struct nf_conntrack_l3proto *l3proto,
816 struct nf_conntrack_protocol *protocol,
817 struct sk_buff *skb,
818 unsigned int dataoff)
819{
820 struct nf_conn *conntrack;
821 struct nf_conntrack_tuple repl_tuple;
822 struct nf_conntrack_expect *exp;
823
824 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, protocol)) {
825 DEBUGP("Can't invert tuple.\n");
826 return NULL;
827 }
828
829 conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto);
830 if (conntrack == NULL || IS_ERR(conntrack)) {
831 DEBUGP("Can't allocate conntrack.\n");
832 return (struct nf_conntrack_tuple_hash *)conntrack;
833 }
834
835 if (!protocol->new(conntrack, skb, dataoff)) {
836 nf_conntrack_free(conntrack);
837 DEBUGP("init conntrack: can't track with proto module\n");
838 return NULL;
839 }
840
841 write_lock_bh(&nf_conntrack_lock);
842 exp = find_expectation(tuple);
843
844 if (exp) {
845 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
846 conntrack, exp);
847 /* Welcome, Mr. Bond. We've been expecting you... */
848 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
849 conntrack->master = exp->master;
850#ifdef CONFIG_NF_CONNTRACK_MARK
851 conntrack->mark = exp->master->mark;
852#endif
853 nf_conntrack_get(&conntrack->master->ct_general);
854 NF_CT_STAT_INC(expect_new);
855 } else {
856 conntrack->helper = nf_ct_find_helper(&repl_tuple);
857
858 NF_CT_STAT_INC(new);
859 }
860
861 /* Overload tuple linked list to put us in unconfirmed list. */
862 list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
863
864 write_unlock_bh(&nf_conntrack_lock);
865
866 if (exp) {
867 if (exp->expectfn)
868 exp->expectfn(conntrack, exp);
869 nf_conntrack_expect_put(exp);
870 }
871
872 return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
873}
874
875/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
876static inline struct nf_conn *
877resolve_normal_ct(struct sk_buff *skb,
878 unsigned int dataoff,
879 u_int16_t l3num,
880 u_int8_t protonum,
881 struct nf_conntrack_l3proto *l3proto,
882 struct nf_conntrack_protocol *proto,
883 int *set_reply,
884 enum ip_conntrack_info *ctinfo)
885{
886 struct nf_conntrack_tuple tuple;
887 struct nf_conntrack_tuple_hash *h;
888 struct nf_conn *ct;
889
890 if (!nf_ct_get_tuple(skb, (unsigned int)(skb->nh.raw - skb->data),
891 dataoff, l3num, protonum, &tuple, l3proto,
892 proto)) {
893 DEBUGP("resolve_normal_ct: Can't get tuple\n");
894 return NULL;
895 }
896
897 /* look for tuple match */
898 h = nf_conntrack_find_get(&tuple, NULL);
899 if (!h) {
900 h = init_conntrack(&tuple, l3proto, proto, skb, dataoff);
901 if (!h)
902 return NULL;
903 if (IS_ERR(h))
904 return (void *)h;
905 }
906 ct = nf_ct_tuplehash_to_ctrack(h);
907
908 /* It exists; we have (non-exclusive) reference. */
909 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
910 *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
911 /* Please set reply bit if this packet OK */
912 *set_reply = 1;
913 } else {
914 /* Once we've had two way comms, always ESTABLISHED. */
915 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
916 DEBUGP("nf_conntrack_in: normal packet for %p\n", ct);
917 *ctinfo = IP_CT_ESTABLISHED;
918 } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
919 DEBUGP("nf_conntrack_in: related packet for %p\n", ct);
920 *ctinfo = IP_CT_RELATED;
921 } else {
922 DEBUGP("nf_conntrack_in: new packet for %p\n", ct);
923 *ctinfo = IP_CT_NEW;
924 }
925 *set_reply = 0;
926 }
927 skb->nfct = &ct->ct_general;
928 skb->nfctinfo = *ctinfo;
929 return ct;
930}
931
932unsigned int
933nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
934{
935 struct nf_conn *ct;
936 enum ip_conntrack_info ctinfo;
937 struct nf_conntrack_l3proto *l3proto;
938 struct nf_conntrack_protocol *proto;
939 unsigned int dataoff;
940 u_int8_t protonum;
941 int set_reply = 0;
942 int ret;
943
944 /* Previously seen (loopback or untracked)? Ignore. */
945 if ((*pskb)->nfct) {
946 NF_CT_STAT_INC(ignore);
947 return NF_ACCEPT;
948 }
949
950 l3proto = nf_ct_find_l3proto((u_int16_t)pf);
951 if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
952 DEBUGP("not prepared to track yet or error occured\n");
953 return -ret;
954 }
955
956 proto = nf_ct_find_proto((u_int16_t)pf, protonum);
957
958 /* It may be an special packet, error, unclean...
959 * inverse of the return code tells to the netfilter
960 * core what to do with the packet. */
961 if (proto->error != NULL &&
962 (ret = proto->error(*pskb, dataoff, &ctinfo, pf, hooknum)) <= 0) {
963 NF_CT_STAT_INC(error);
964 NF_CT_STAT_INC(invalid);
965 return -ret;
966 }
967
968 ct = resolve_normal_ct(*pskb, dataoff, pf, protonum, l3proto, proto,
969 &set_reply, &ctinfo);
970 if (!ct) {
971 /* Not valid part of a connection */
972 NF_CT_STAT_INC(invalid);
973 return NF_ACCEPT;
974 }
975
976 if (IS_ERR(ct)) {
977 /* Too stressed to deal. */
978 NF_CT_STAT_INC(drop);
979 return NF_DROP;
980 }
981
982 NF_CT_ASSERT((*pskb)->nfct);
983
984 ret = proto->packet(ct, *pskb, dataoff, ctinfo, pf, hooknum);
985 if (ret < 0) {
986 /* Invalid: inverse of the return code tells
987 * the netfilter core what to do */
988 DEBUGP("nf_conntrack_in: Can't track with proto module\n");
989 nf_conntrack_put((*pskb)->nfct);
990 (*pskb)->nfct = NULL;
991 NF_CT_STAT_INC(invalid);
992 return -ret;
993 }
994
995 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
996 nf_conntrack_event_cache(IPCT_STATUS, *pskb);
997
998 return ret;
999}
1000
1001int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
1002 const struct nf_conntrack_tuple *orig)
1003{
1004 return nf_ct_invert_tuple(inverse, orig,
1005 nf_ct_find_l3proto(orig->src.l3num),
1006 nf_ct_find_proto(orig->src.l3num,
1007 orig->dst.protonum));
1008}
1009
1010/* Would two expected things clash? */
1011static inline int expect_clash(const struct nf_conntrack_expect *a,
1012 const struct nf_conntrack_expect *b)
1013{
1014 /* Part covered by intersection of masks must be unequal,
1015 otherwise they clash */
1016 struct nf_conntrack_tuple intersect_mask;
1017 int count;
1018
1019 intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
1020 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
1021 intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
1022 intersect_mask.dst.protonum = a->mask.dst.protonum
1023 & b->mask.dst.protonum;
1024
1025 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
1026 intersect_mask.src.u3.all[count] =
1027 a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
1028 }
1029
1030 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
1031 intersect_mask.dst.u3.all[count] =
1032 a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
1033 }
1034
1035 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
1036}
1037
1038static inline int expect_matches(const struct nf_conntrack_expect *a,
1039 const struct nf_conntrack_expect *b)
1040{
1041 return a->master == b->master
1042 && nf_ct_tuple_equal(&a->tuple, &b->tuple)
1043 && nf_ct_tuple_equal(&a->mask, &b->mask);
1044}
1045
1046/* Generally a bad idea to call this: could have matched already. */
1047void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp)
1048{
1049 struct nf_conntrack_expect *i;
1050
1051 write_lock_bh(&nf_conntrack_lock);
1052 /* choose the the oldest expectation to evict */
1053 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
1054 if (expect_matches(i, exp) && del_timer(&i->timeout)) {
1055 nf_ct_unlink_expect(i);
1056 write_unlock_bh(&nf_conntrack_lock);
1057 nf_conntrack_expect_put(i);
1058 return;
1059 }
1060 }
1061 write_unlock_bh(&nf_conntrack_lock);
1062}
1063
1064/* We don't increase the master conntrack refcount for non-fulfilled
1065 * conntracks. During the conntrack destruction, the expectations are
1066 * always killed before the conntrack itself */
1067struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
1068{
1069 struct nf_conntrack_expect *new;
1070
1071 new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC);
1072 if (!new) {
1073 DEBUGP("expect_related: OOM allocating expect\n");
1074 return NULL;
1075 }
1076 new->master = me;
1077 atomic_set(&new->use, 1);
1078 return new;
1079}
1080
1081void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
1082{
1083 if (atomic_dec_and_test(&exp->use))
1084 kmem_cache_free(nf_conntrack_expect_cachep, exp);
1085}
1086
1087static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
1088{
1089 atomic_inc(&exp->use);
1090 exp->master->expecting++;
1091 list_add(&exp->list, &nf_conntrack_expect_list);
1092
1093 init_timer(&exp->timeout);
1094 exp->timeout.data = (unsigned long)exp;
1095 exp->timeout.function = expectation_timed_out;
1096 exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
1097 add_timer(&exp->timeout);
1098
1099 atomic_inc(&exp->use);
1100 NF_CT_STAT_INC(expect_create);
1101}
1102
1103/* Race with expectations being used means we could have none to find; OK. */
1104static void evict_oldest_expect(struct nf_conn *master)
1105{
1106 struct nf_conntrack_expect *i;
1107
1108 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
1109 if (i->master == master) {
1110 if (del_timer(&i->timeout)) {
1111 nf_ct_unlink_expect(i);
1112 nf_conntrack_expect_put(i);
1113 }
1114 break;
1115 }
1116 }
1117}
1118
1119static inline int refresh_timer(struct nf_conntrack_expect *i)
1120{
1121 if (!del_timer(&i->timeout))
1122 return 0;
1123
1124 i->timeout.expires = jiffies + i->master->helper->timeout*HZ;
1125 add_timer(&i->timeout);
1126 return 1;
1127}
1128
1129int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
1130{
1131 struct nf_conntrack_expect *i;
1132 int ret;
1133
1134 DEBUGP("nf_conntrack_expect_related %p\n", related_to);
1135 DEBUGP("tuple: "); NF_CT_DUMP_TUPLE(&expect->tuple);
1136 DEBUGP("mask: "); NF_CT_DUMP_TUPLE(&expect->mask);
1137
1138 write_lock_bh(&nf_conntrack_lock);
1139 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
1140 if (expect_matches(i, expect)) {
1141 /* Refresh timer: if it's dying, ignore.. */
1142 if (refresh_timer(i)) {
1143 ret = 0;
1144 goto out;
1145 }
1146 } else if (expect_clash(i, expect)) {
1147 ret = -EBUSY;
1148 goto out;
1149 }
1150 }
1151 /* Will be over limit? */
1152 if (expect->master->helper->max_expected &&
1153 expect->master->expecting >= expect->master->helper->max_expected)
1154 evict_oldest_expect(expect->master);
1155
1156 nf_conntrack_expect_insert(expect);
1157 nf_conntrack_expect_event(IPEXP_NEW, expect);
1158 ret = 0;
1159out:
1160 write_unlock_bh(&nf_conntrack_lock);
1161 return ret;
1162}
1163
1164/* Alter reply tuple (maybe alter helper). This is for NAT, and is
1165 implicitly racy: see __nf_conntrack_confirm */
1166void nf_conntrack_alter_reply(struct nf_conn *conntrack,
1167 const struct nf_conntrack_tuple *newreply)
1168{
1169 write_lock_bh(&nf_conntrack_lock);
1170 /* Should be unconfirmed, so not in hash table yet */
1171 NF_CT_ASSERT(!nf_ct_is_confirmed(conntrack));
1172
1173 DEBUGP("Altering reply tuple of %p to ", conntrack);
1174 NF_CT_DUMP_TUPLE(newreply);
1175
1176 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
1177 if (!conntrack->master && conntrack->expecting == 0)
1178 conntrack->helper = nf_ct_find_helper(newreply);
1179 write_unlock_bh(&nf_conntrack_lock);
1180}
1181
1182int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
1183{
1184 int ret;
1185 BUG_ON(me->timeout == 0);
1186
1187 ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
1188 sizeof(struct nf_conn)
1189 + sizeof(union nf_conntrack_help)
1190 + __alignof__(union nf_conntrack_help),
1191 init_conntrack_for_helper);
1192 if (ret < 0) {
1193 printk(KERN_ERR "nf_conntrack_helper_reigster: Unable to create slab cache for conntracks\n");
1194 return ret;
1195 }
1196 write_lock_bh(&nf_conntrack_lock);
1197 list_prepend(&helpers, me);
1198 write_unlock_bh(&nf_conntrack_lock);
1199
1200 return 0;
1201}
1202
1203static inline int unhelp(struct nf_conntrack_tuple_hash *i,
1204 const struct nf_conntrack_helper *me)
1205{
1206 if (nf_ct_tuplehash_to_ctrack(i)->helper == me) {
1207 nf_conntrack_event(IPCT_HELPER, nf_ct_tuplehash_to_ctrack(i));
1208 nf_ct_tuplehash_to_ctrack(i)->helper = NULL;
1209 }
1210 return 0;
1211}
1212
1213void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
1214{
1215 unsigned int i;
1216 struct nf_conntrack_expect *exp, *tmp;
1217
1218 /* Need write lock here, to delete helper. */
1219 write_lock_bh(&nf_conntrack_lock);
1220 LIST_DELETE(&helpers, me);
1221
1222 /* Get rid of expectations */
1223 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
1224 if (exp->master->helper == me && del_timer(&exp->timeout)) {
1225 nf_ct_unlink_expect(exp);
1226 nf_conntrack_expect_put(exp);
1227 }
1228 }
1229
1230 /* Get rid of expecteds, set helpers to NULL. */
1231 LIST_FIND_W(&unconfirmed, unhelp, struct nf_conntrack_tuple_hash*, me);
1232 for (i = 0; i < nf_conntrack_htable_size; i++)
1233 LIST_FIND_W(&nf_conntrack_hash[i], unhelp,
1234 struct nf_conntrack_tuple_hash *, me);
1235 write_unlock_bh(&nf_conntrack_lock);
1236
1237 /* Someone could be still looking at the helper in a bh. */
1238 synchronize_net();
1239}
1240
1241/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
1242void __nf_ct_refresh_acct(struct nf_conn *ct,
1243 enum ip_conntrack_info ctinfo,
1244 const struct sk_buff *skb,
1245 unsigned long extra_jiffies,
1246 int do_acct)
1247{
1248 int event = 0;
1249
1250 NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
1251 NF_CT_ASSERT(skb);
1252
1253 write_lock_bh(&nf_conntrack_lock);
1254
1255 /* If not in hash table, timer will not be active yet */
1256 if (!nf_ct_is_confirmed(ct)) {
1257 ct->timeout.expires = extra_jiffies;
1258 event = IPCT_REFRESH;
1259 } else {
1260 /* Need del_timer for race avoidance (may already be dying). */
1261 if (del_timer(&ct->timeout)) {
1262 ct->timeout.expires = jiffies + extra_jiffies;
1263 add_timer(&ct->timeout);
1264 event = IPCT_REFRESH;
1265 }
1266 }
1267
1268#ifdef CONFIG_NF_CT_ACCT
1269 if (do_acct) {
1270 ct->counters[CTINFO2DIR(ctinfo)].packets++;
1271 ct->counters[CTINFO2DIR(ctinfo)].bytes +=
1272 skb->len - (unsigned int)(skb->nh.raw - skb->data);
1273 if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
1274 || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
1275 event |= IPCT_COUNTER_FILLING;
1276 }
1277#endif
1278
1279 write_unlock_bh(&nf_conntrack_lock);
1280
1281 /* must be unlocked when calling event cache */
1282 if (event)
1283 nf_conntrack_event_cache(event, skb);
1284}
1285
1286/* Used by ipt_REJECT and ip6t_REJECT. */
1287void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
1288{
1289 struct nf_conn *ct;
1290 enum ip_conntrack_info ctinfo;
1291
1292 /* This ICMP is in reverse direction to the packet which caused it */
1293 ct = nf_ct_get(skb, &ctinfo);
1294 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
1295 ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY;
1296 else
1297 ctinfo = IP_CT_RELATED;
1298
1299 /* Attach to new skbuff, and increment count */
1300 nskb->nfct = &ct->ct_general;
1301 nskb->nfctinfo = ctinfo;
1302 nf_conntrack_get(nskb->nfct);
1303}
1304
1305static inline int
1306do_iter(const struct nf_conntrack_tuple_hash *i,
1307 int (*iter)(struct nf_conn *i, void *data),
1308 void *data)
1309{
1310 return iter(nf_ct_tuplehash_to_ctrack(i), data);
1311}
1312
1313/* Bring out ya dead! */
1314static struct nf_conntrack_tuple_hash *
1315get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
1316 void *data, unsigned int *bucket)
1317{
1318 struct nf_conntrack_tuple_hash *h = NULL;
1319
1320 write_lock_bh(&nf_conntrack_lock);
1321 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
1322 h = LIST_FIND_W(&nf_conntrack_hash[*bucket], do_iter,
1323 struct nf_conntrack_tuple_hash *, iter, data);
1324 if (h)
1325 break;
1326 }
1327 if (!h)
1328 h = LIST_FIND_W(&unconfirmed, do_iter,
1329 struct nf_conntrack_tuple_hash *, iter, data);
1330 if (h)
1331 atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
1332 write_unlock_bh(&nf_conntrack_lock);
1333
1334 return h;
1335}
1336
1337void
1338nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data)
1339{
1340 struct nf_conntrack_tuple_hash *h;
1341 unsigned int bucket = 0;
1342
1343 while ((h = get_next_corpse(iter, data, &bucket)) != NULL) {
1344 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
1345 /* Time to push up daises... */
1346 if (del_timer(&ct->timeout))
1347 death_by_timeout((unsigned long)ct);
1348 /* ... else the timer will get him soon. */
1349
1350 nf_ct_put(ct);
1351 }
1352}
1353
1354static int kill_all(struct nf_conn *i, void *data)
1355{
1356 return 1;
1357}
1358
1359static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
1360{
1361 if (vmalloced)
1362 vfree(hash);
1363 else
1364 free_pages((unsigned long)hash,
1365 get_order(sizeof(struct list_head) * size));
1366}
1367
1368/* Mishearing the voices in his head, our hero wonders how he's
1369 supposed to kill the mall. */
1370void nf_conntrack_cleanup(void)
1371{
1372 int i;
1373
1374 /* This makes sure all current packets have passed through
1375 netfilter framework. Roll on, two-stage module
1376 delete... */
1377 synchronize_net();
1378
1379 nf_ct_event_cache_flush();
1380 i_see_dead_people:
1381 nf_ct_iterate_cleanup(kill_all, NULL);
1382 if (atomic_read(&nf_conntrack_count) != 0) {
1383 schedule();
1384 goto i_see_dead_people;
1385 }
1386
1387 for (i = 0; i < NF_CT_F_NUM; i++) {
1388 if (nf_ct_cache[i].use == 0)
1389 continue;
1390
1391 NF_CT_ASSERT(nf_ct_cache[i].use == 1);
1392 nf_ct_cache[i].use = 1;
1393 nf_conntrack_unregister_cache(i);
1394 }
1395 kmem_cache_destroy(nf_conntrack_expect_cachep);
1396 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
1397 nf_conntrack_htable_size);
1398}
1399
1400static struct list_head *alloc_hashtable(int size, int *vmalloced)
1401{
1402 struct list_head *hash;
1403 unsigned int i;
1404
1405 *vmalloced = 0;
1406 hash = (void*)__get_free_pages(GFP_KERNEL,
1407 get_order(sizeof(struct list_head)
1408 * size));
1409 if (!hash) {
1410 *vmalloced = 1;
1411 printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
1412 hash = vmalloc(sizeof(struct list_head) * size);
1413 }
1414
1415 if (hash)
1416 for (i = 0; i < size; i++)
1417 INIT_LIST_HEAD(&hash[i]);
1418
1419 return hash;
1420}
1421
1422int set_hashsize(const char *val, struct kernel_param *kp)
1423{
1424 int i, bucket, hashsize, vmalloced;
1425 int old_vmalloced, old_size;
1426 int rnd;
1427 struct list_head *hash, *old_hash;
1428 struct nf_conntrack_tuple_hash *h;
1429
1430 /* On boot, we can set this without any fancy locking. */
1431 if (!nf_conntrack_htable_size)
1432 return param_set_uint(val, kp);
1433
1434 hashsize = simple_strtol(val, NULL, 0);
1435 if (!hashsize)
1436 return -EINVAL;
1437
1438 hash = alloc_hashtable(hashsize, &vmalloced);
1439 if (!hash)
1440 return -ENOMEM;
1441
1442 /* We have to rehahs for the new table anyway, so we also can
1443 * use a newrandom seed */
1444 get_random_bytes(&rnd, 4);
1445
1446 write_lock_bh(&nf_conntrack_lock);
1447 for (i = 0; i < nf_conntrack_htable_size; i++) {
1448 while (!list_empty(&nf_conntrack_hash[i])) {
1449 h = list_entry(nf_conntrack_hash[i].next,
1450 struct nf_conntrack_tuple_hash, list);
1451 list_del(&h->list);
1452 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
1453 list_add_tail(&h->list, &hash[bucket]);
1454 }
1455 }
1456 old_size = nf_conntrack_htable_size;
1457 old_vmalloced = nf_conntrack_vmalloc;
1458 old_hash = nf_conntrack_hash;
1459
1460 nf_conntrack_htable_size = hashsize;
1461 nf_conntrack_vmalloc = vmalloced;
1462 nf_conntrack_hash = hash;
1463 nf_conntrack_hash_rnd = rnd;
1464 write_unlock_bh(&nf_conntrack_lock);
1465
1466 free_conntrack_hash(old_hash, old_vmalloced, old_size);
1467 return 0;
1468}
1469
1470module_param_call(hashsize, set_hashsize, param_get_uint,
1471 &nf_conntrack_htable_size, 0600);
1472
1473int __init nf_conntrack_init(void)
1474{
1475 unsigned int i;
1476 int ret;
1477
1478 /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
1479 * machine has 256 buckets. >= 1GB machines have 8192 buckets. */
1480 if (!nf_conntrack_htable_size) {
1481 nf_conntrack_htable_size
1482 = (((num_physpages << PAGE_SHIFT) / 16384)
1483 / sizeof(struct list_head));
1484 if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
1485 nf_conntrack_htable_size = 8192;
1486 if (nf_conntrack_htable_size < 16)
1487 nf_conntrack_htable_size = 16;
1488 }
1489 nf_conntrack_max = 8 * nf_conntrack_htable_size;
1490
1491 printk("nf_conntrack version %s (%u buckets, %d max)\n",
1492 NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
1493 nf_conntrack_max);
1494
1495 nf_conntrack_hash = alloc_hashtable(nf_conntrack_htable_size,
1496 &nf_conntrack_vmalloc);
1497 if (!nf_conntrack_hash) {
1498 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1499 goto err_out;
1500 }
1501
1502 ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic",
1503 sizeof(struct nf_conn), NULL);
1504 if (ret < 0) {
1505 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1506 goto err_free_hash;
1507 }
1508
1509 nf_conntrack_expect_cachep = kmem_cache_create("nf_conntrack_expect",
1510 sizeof(struct nf_conntrack_expect),
1511 0, 0, NULL, NULL);
1512 if (!nf_conntrack_expect_cachep) {
1513 printk(KERN_ERR "Unable to create nf_expect slab cache\n");
1514 goto err_free_conntrack_slab;
1515 }
1516
1517 /* Don't NEED lock here, but good form anyway. */
1518 write_lock_bh(&nf_conntrack_lock);
1519 for (i = 0; i < PF_MAX; i++)
1520 nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto;
1521 write_unlock_bh(&nf_conntrack_lock);
1522
1523 /* Set up fake conntrack:
1524 - to never be deleted, not in any hashes */
1525 atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
1526 /* - and look it like as a confirmed connection */
1527 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
1528
1529 return ret;
1530
1531err_free_conntrack_slab:
1532 nf_conntrack_unregister_cache(NF_CT_F_BASIC);
1533err_free_hash:
1534 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
1535 nf_conntrack_htable_size);
1536err_out:
1537 return -ENOMEM;
1538}
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
new file mode 100644
index 000000000000..65080e269f27
--- /dev/null
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -0,0 +1,698 @@
1/* FTP extension for connection tracking. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - enable working with Layer 3 protocol independent connection tracking.
13 * - track EPRT and EPSV commands with IPv6 address.
14 *
15 * Derived from net/ipv4/netfilter/ip_conntrack_ftp.c
16 */
17
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/netfilter.h>
22#include <linux/ip.h>
23#include <linux/ipv6.h>
24#include <linux/ctype.h>
25#include <net/checksum.h>
26#include <net/tcp.h>
27
28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_helper.h>
30#include <linux/netfilter/nf_conntrack_ftp.h>
31
32MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
34MODULE_DESCRIPTION("ftp connection tracking helper");
35
36/* This is slow, but it's simple. --RR */
37static char *ftp_buffer;
38
39static DEFINE_SPINLOCK(nf_ftp_lock);
40
41#define MAX_PORTS 8
42static u_int16_t ports[MAX_PORTS];
43static unsigned int ports_c;
44module_param_array(ports, ushort, &ports_c, 0400);
45
46static int loose;
47module_param(loose, int, 0600);
48
49unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
50 enum ip_conntrack_info ctinfo,
51 enum ip_ct_ftp_type type,
52 unsigned int matchoff,
53 unsigned int matchlen,
54 struct nf_conntrack_expect *exp,
55 u32 *seq);
56EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
57
58#if 0
59#define DEBUGP printk
60#else
61#define DEBUGP(format, args...)
62#endif
63
64static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
65static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
66static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
67 char);
68
69static struct ftp_search {
70 enum ip_conntrack_dir dir;
71 const char *pattern;
72 size_t plen;
73 char skip;
74 char term;
75 enum ip_ct_ftp_type ftptype;
76 int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char);
77} search[] = {
78 {
79 IP_CT_DIR_ORIGINAL,
80 "PORT", sizeof("PORT") - 1, ' ', '\r',
81 IP_CT_FTP_PORT,
82 try_rfc959,
83 },
84 {
85 IP_CT_DIR_REPLY,
86 "227 ", sizeof("227 ") - 1, '(', ')',
87 IP_CT_FTP_PASV,
88 try_rfc959,
89 },
90 {
91 IP_CT_DIR_ORIGINAL,
92 "EPRT", sizeof("EPRT") - 1, ' ', '\r',
93 IP_CT_FTP_EPRT,
94 try_eprt,
95 },
96 {
97 IP_CT_DIR_REPLY,
98 "229 ", sizeof("229 ") - 1, '(', ')',
99 IP_CT_FTP_EPSV,
100 try_epsv_response,
101 },
102};
103
104/* This code is based on inet_pton() in glibc-2.2.4 */
105static int
106get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term)
107{
108 static const char xdigits[] = "0123456789abcdef";
109 u_int8_t tmp[16], *tp, *endp, *colonp;
110 int ch, saw_xdigit;
111 u_int32_t val;
112 size_t clen = 0;
113
114 tp = memset(tmp, '\0', sizeof(tmp));
115 endp = tp + sizeof(tmp);
116 colonp = NULL;
117
118 /* Leading :: requires some special handling. */
119 if (*src == ':'){
120 if (*++src != ':') {
121 DEBUGP("invalid \":\" at the head of addr\n");
122 return 0;
123 }
124 clen++;
125 }
126
127 saw_xdigit = 0;
128 val = 0;
129 while ((clen < dlen) && (*src != term)) {
130 const char *pch;
131
132 ch = tolower(*src++);
133 clen++;
134
135 pch = strchr(xdigits, ch);
136 if (pch != NULL) {
137 val <<= 4;
138 val |= (pch - xdigits);
139 if (val > 0xffff)
140 return 0;
141
142 saw_xdigit = 1;
143 continue;
144 }
145 if (ch != ':') {
146 DEBUGP("get_ipv6_addr: invalid char. \'%c\'\n", ch);
147 return 0;
148 }
149
150 if (!saw_xdigit) {
151 if (colonp) {
152 DEBUGP("invalid location of \"::\".\n");
153 return 0;
154 }
155 colonp = tp;
156 continue;
157 } else if (*src == term) {
158 DEBUGP("trancated IPv6 addr\n");
159 return 0;
160 }
161
162 if (tp + 2 > endp)
163 return 0;
164 *tp++ = (u_int8_t) (val >> 8) & 0xff;
165 *tp++ = (u_int8_t) val & 0xff;
166
167 saw_xdigit = 0;
168 val = 0;
169 continue;
170 }
171 if (saw_xdigit) {
172 if (tp + 2 > endp)
173 return 0;
174 *tp++ = (u_int8_t) (val >> 8) & 0xff;
175 *tp++ = (u_int8_t) val & 0xff;
176 }
177 if (colonp != NULL) {
178 /*
179 * Since some memmove()'s erroneously fail to handle
180 * overlapping regions, we'll do the shift by hand.
181 */
182 const int n = tp - colonp;
183 int i;
184
185 if (tp == endp)
186 return 0;
187
188 for (i = 1; i <= n; i++) {
189 endp[- i] = colonp[n - i];
190 colonp[n - i] = 0;
191 }
192 tp = endp;
193 }
194 if (tp != endp || (*src != term))
195 return 0;
196
197 memcpy(dst->s6_addr, tmp, sizeof(dst->s6_addr));
198 return clen;
199}
200
201static int try_number(const char *data, size_t dlen, u_int32_t array[],
202 int array_size, char sep, char term)
203{
204 u_int32_t i, len;
205
206 memset(array, 0, sizeof(array[0])*array_size);
207
208 /* Keep data pointing at next char. */
209 for (i = 0, len = 0; len < dlen && i < array_size; len++, data++) {
210 if (*data >= '0' && *data <= '9') {
211 array[i] = array[i]*10 + *data - '0';
212 }
213 else if (*data == sep)
214 i++;
215 else {
216 /* Unexpected character; true if it's the
217 terminator and we're finished. */
218 if (*data == term && i == array_size - 1)
219 return len;
220
221 DEBUGP("Char %u (got %u nums) `%u' unexpected\n",
222 len, i, *data);
223 return 0;
224 }
225 }
226 DEBUGP("Failed to fill %u numbers separated by %c\n", array_size, sep);
227
228 return 0;
229}
230
231/* Returns 0, or length of numbers: 192,168,1,1,5,6 */
232static int try_rfc959(const char *data, size_t dlen,
233 struct nf_conntrack_man *cmd, char term)
234{
235 int length;
236 u_int32_t array[6];
237
238 length = try_number(data, dlen, array, 6, ',', term);
239 if (length == 0)
240 return 0;
241
242 cmd->u3.ip = htonl((array[0] << 24) | (array[1] << 16) |
243 (array[2] << 8) | array[3]);
244 cmd->u.tcp.port = htons((array[4] << 8) | array[5]);
245 return length;
246}
247
248/* Grab port: number up to delimiter */
249static int get_port(const char *data, int start, size_t dlen, char delim,
250 u_int16_t *port)
251{
252 u_int16_t tmp_port = 0;
253 int i;
254
255 for (i = start; i < dlen; i++) {
256 /* Finished? */
257 if (data[i] == delim) {
258 if (tmp_port == 0)
259 break;
260 *port = htons(tmp_port);
261 DEBUGP("get_port: return %d\n", tmp_port);
262 return i + 1;
263 }
264 else if (data[i] >= '0' && data[i] <= '9')
265 tmp_port = tmp_port*10 + data[i] - '0';
266 else { /* Some other crap */
267 DEBUGP("get_port: invalid char.\n");
268 break;
269 }
270 }
271 return 0;
272}
273
274/* Returns 0, or length of numbers: |1|132.235.1.2|6275| or |2|3ffe::1|6275| */
275static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
276 char term)
277{
278 char delim;
279 int length;
280
281 /* First character is delimiter, then "1" for IPv4 or "2" for IPv6,
282 then delimiter again. */
283 if (dlen <= 3) {
284 DEBUGP("EPRT: too short\n");
285 return 0;
286 }
287 delim = data[0];
288 if (isdigit(delim) || delim < 33 || delim > 126 || data[2] != delim) {
289 DEBUGP("try_eprt: invalid delimitter.\n");
290 return 0;
291 }
292
293 if ((cmd->l3num == PF_INET && data[1] != '1') ||
294 (cmd->l3num == PF_INET6 && data[1] != '2')) {
295 DEBUGP("EPRT: invalid protocol number.\n");
296 return 0;
297 }
298
299 DEBUGP("EPRT: Got %c%c%c\n", delim, data[1], delim);
300
301 if (data[1] == '1') {
302 u_int32_t array[4];
303
304 /* Now we have IP address. */
305 length = try_number(data + 3, dlen - 3, array, 4, '.', delim);
306 if (length != 0)
307 cmd->u3.ip = htonl((array[0] << 24) | (array[1] << 16)
308 | (array[2] << 8) | array[3]);
309 } else {
310 /* Now we have IPv6 address. */
311 length = get_ipv6_addr(data + 3, dlen - 3,
312 (struct in6_addr *)cmd->u3.ip6, delim);
313 }
314
315 if (length == 0)
316 return 0;
317 DEBUGP("EPRT: Got IP address!\n");
318 /* Start offset includes initial "|1|", and trailing delimiter */
319 return get_port(data, 3 + length + 1, dlen, delim, &cmd->u.tcp.port);
320}
321
322/* Returns 0, or length of numbers: |||6446| */
323static int try_epsv_response(const char *data, size_t dlen,
324 struct nf_conntrack_man *cmd, char term)
325{
326 char delim;
327
328 /* Three delimiters. */
329 if (dlen <= 3) return 0;
330 delim = data[0];
331 if (isdigit(delim) || delim < 33 || delim > 126
332 || data[1] != delim || data[2] != delim)
333 return 0;
334
335 return get_port(data, 3, dlen, delim, &cmd->u.tcp.port);
336}
337
338/* Return 1 for match, 0 for accept, -1 for partial. */
339static int find_pattern(const char *data, size_t dlen,
340 const char *pattern, size_t plen,
341 char skip, char term,
342 unsigned int *numoff,
343 unsigned int *numlen,
344 struct nf_conntrack_man *cmd,
345 int (*getnum)(const char *, size_t,
346 struct nf_conntrack_man *, char))
347{
348 size_t i;
349
350 DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen);
351 if (dlen == 0)
352 return 0;
353
354 if (dlen <= plen) {
355 /* Short packet: try for partial? */
356 if (strnicmp(data, pattern, dlen) == 0)
357 return -1;
358 else return 0;
359 }
360
361 if (strnicmp(data, pattern, plen) != 0) {
362#if 0
363 size_t i;
364
365 DEBUGP("ftp: string mismatch\n");
366 for (i = 0; i < plen; i++) {
367 DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
368 i, data[i], data[i],
369 pattern[i], pattern[i]);
370 }
371#endif
372 return 0;
373 }
374
375 DEBUGP("Pattern matches!\n");
376 /* Now we've found the constant string, try to skip
377 to the 'skip' character */
378 for (i = plen; data[i] != skip; i++)
379 if (i == dlen - 1) return -1;
380
381 /* Skip over the last character */
382 i++;
383
384 DEBUGP("Skipped up to `%c'!\n", skip);
385
386 *numoff = i;
387 *numlen = getnum(data + i, dlen - i, cmd, term);
388 if (!*numlen)
389 return -1;
390
391 DEBUGP("Match succeeded!\n");
392 return 1;
393}
394
395/* Look up to see if we're just after a \n. */
396static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
397{
398 unsigned int i;
399
400 for (i = 0; i < info->seq_aft_nl_num[dir]; i++)
401 if (info->seq_aft_nl[dir][i] == seq)
402 return 1;
403 return 0;
404}
405
406/* We don't update if it's older than what we have. */
407static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir,
408 struct sk_buff *skb)
409{
410 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
411
412 /* Look for oldest: if we find exact match, we're done. */
413 for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
414 if (info->seq_aft_nl[dir][i] == nl_seq)
415 return;
416
417 if (oldest == info->seq_aft_nl_num[dir]
418 || before(info->seq_aft_nl[dir][i], oldest))
419 oldest = i;
420 }
421
422 if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
423 info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
424 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
425 } else if (oldest != NUM_SEQ_TO_REMEMBER) {
426 info->seq_aft_nl[dir][oldest] = nl_seq;
427 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
428 }
429}
430
431static int help(struct sk_buff **pskb,
432 unsigned int protoff,
433 struct nf_conn *ct,
434 enum ip_conntrack_info ctinfo)
435{
436 unsigned int dataoff, datalen;
437 struct tcphdr _tcph, *th;
438 char *fb_ptr;
439 int ret;
440 u32 seq;
441 int dir = CTINFO2DIR(ctinfo);
442 unsigned int matchlen, matchoff;
443 struct ip_ct_ftp_master *ct_ftp_info = &ct->help->ct_ftp_info;
444 struct nf_conntrack_expect *exp;
445 struct nf_conntrack_man cmd = {};
446
447 unsigned int i;
448 int found = 0, ends_in_nl;
449
450 /* Until there's been traffic both ways, don't look in packets. */
451 if (ctinfo != IP_CT_ESTABLISHED
452 && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
453 DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo);
454 return NF_ACCEPT;
455 }
456
457 th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
458 if (th == NULL)
459 return NF_ACCEPT;
460
461 dataoff = protoff + th->doff * 4;
462 /* No data? */
463 if (dataoff >= (*pskb)->len) {
464 DEBUGP("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
465 (*pskb)->len);
466 return NF_ACCEPT;
467 }
468 datalen = (*pskb)->len - dataoff;
469
470 spin_lock_bh(&nf_ftp_lock);
471 fb_ptr = skb_header_pointer(*pskb, dataoff, datalen, ftp_buffer);
472 BUG_ON(fb_ptr == NULL);
473
474 ends_in_nl = (fb_ptr[datalen - 1] == '\n');
475 seq = ntohl(th->seq) + datalen;
476
477 /* Look up to see if we're just after a \n. */
478 if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
479 /* Now if this ends in \n, update ftp info. */
480 DEBUGP("nf_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",
481 ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
482 ct_ftp_info->seq_aft_nl[dir][0],
483 ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
484 ct_ftp_info->seq_aft_nl[dir][1]);
485 ret = NF_ACCEPT;
486 goto out_update_nl;
487 }
488
489 /* Initialize IP/IPv6 addr to expected address (it's not mentioned
490 in EPSV responses) */
491 cmd.l3num = ct->tuplehash[dir].tuple.src.l3num;
492 memcpy(cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
493 sizeof(cmd.u3.all));
494
495 for (i = 0; i < ARRAY_SIZE(search); i++) {
496 if (search[i].dir != dir) continue;
497
498 found = find_pattern(fb_ptr, datalen,
499 search[i].pattern,
500 search[i].plen,
501 search[i].skip,
502 search[i].term,
503 &matchoff, &matchlen,
504 &cmd,
505 search[i].getnum);
506 if (found) break;
507 }
508 if (found == -1) {
509 /* We don't usually drop packets. After all, this is
510 connection tracking, not packet filtering.
511 However, it is necessary for accurate tracking in
512 this case. */
513 if (net_ratelimit())
514 printk("conntrack_ftp: partial %s %u+%u\n",
515 search[i].pattern,
516 ntohl(th->seq), datalen);
517 ret = NF_DROP;
518 goto out;
519 } else if (found == 0) { /* No match */
520 ret = NF_ACCEPT;
521 goto out_update_nl;
522 }
523
524 DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
525 (int)matchlen, fb_ptr + matchoff,
526 matchlen, ntohl(th->seq) + matchoff);
527
528 exp = nf_conntrack_expect_alloc(ct);
529 if (exp == NULL) {
530 ret = NF_DROP;
531 goto out;
532 }
533
534 /* We refer to the reverse direction ("!dir") tuples here,
535 * because we're expecting something in the other direction.
536 * Doesn't matter unless NAT is happening. */
537 exp->tuple.dst.u3 = ct->tuplehash[!dir].tuple.dst.u3;
538
539 /* Update the ftp info */
540 if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) &&
541 memcmp(&cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
542 sizeof(cmd.u3.all))) {
543 /* Enrico Scholz's passive FTP to partially RNAT'd ftp
544 server: it really wants us to connect to a
545 different IP address. Simply don't record it for
546 NAT. */
547 if (cmd.l3num == PF_INET) {
548 DEBUGP("conntrack_ftp: NOT RECORDING: %u,%u,%u,%u != %u.%u.%u.%u\n",
549 NIPQUAD(cmd.u3.ip),
550 NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
551 } else {
552 DEBUGP("conntrack_ftp: NOT RECORDING: %x:%x:%x:%x:%x:%x:%x:%x != %x:%x:%x:%x:%x:%x:%x:%x\n",
553 NIP6(*((struct in6_addr *)cmd.u3.ip6)),
554 NIP6(*((struct in6_addr *)ct->tuplehash[dir]
555 .tuple.src.u3.ip6)));
556 }
557
558 /* Thanks to Cristiano Lincoln Mattos
559 <lincoln@cesar.org.br> for reporting this potential
560 problem (DMZ machines opening holes to internal
561 networks, or the packet filter itself). */
562 if (!loose) {
563 ret = NF_ACCEPT;
564 goto out_put_expect;
565 }
566 memcpy(&exp->tuple.dst.u3, &cmd.u3.all,
567 sizeof(exp->tuple.dst.u3));
568 }
569
570 exp->tuple.src.u3 = ct->tuplehash[!dir].tuple.src.u3;
571 exp->tuple.src.l3num = cmd.l3num;
572 exp->tuple.src.u.tcp.port = 0;
573 exp->tuple.dst.u.tcp.port = cmd.u.tcp.port;
574 exp->tuple.dst.protonum = IPPROTO_TCP;
575
576 exp->mask = (struct nf_conntrack_tuple)
577 { .src = { .l3num = 0xFFFF,
578 .u = { .tcp = { 0 }},
579 },
580 .dst = { .protonum = 0xFF,
581 .u = { .tcp = { 0xFFFF }},
582 },
583 };
584 if (cmd.l3num == PF_INET) {
585 exp->mask.src.u3.ip = 0xFFFFFFFF;
586 exp->mask.dst.u3.ip = 0xFFFFFFFF;
587 } else {
588 memset(exp->mask.src.u3.ip6, 0xFF,
589 sizeof(exp->mask.src.u3.ip6));
590 memset(exp->mask.dst.u3.ip6, 0xFF,
591 sizeof(exp->mask.src.u3.ip6));
592 }
593
594 exp->expectfn = NULL;
595 exp->flags = 0;
596
597 /* Now, NAT might want to mangle the packet, and register the
598 * (possibly changed) expectation itself. */
599 if (nf_nat_ftp_hook)
600 ret = nf_nat_ftp_hook(pskb, ctinfo, search[i].ftptype,
601 matchoff, matchlen, exp, &seq);
602 else {
603 /* Can't expect this? Best to drop packet now. */
604 if (nf_conntrack_expect_related(exp) != 0)
605 ret = NF_DROP;
606 else
607 ret = NF_ACCEPT;
608 }
609
610out_put_expect:
611 nf_conntrack_expect_put(exp);
612
613out_update_nl:
614 /* Now if this ends in \n, update ftp info. Seq may have been
615 * adjusted by NAT code. */
616 if (ends_in_nl)
617 update_nl_seq(seq, ct_ftp_info, dir, *pskb);
618 out:
619 spin_unlock_bh(&nf_ftp_lock);
620 return ret;
621}
622
623static struct nf_conntrack_helper ftp[MAX_PORTS][2];
624static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")];
625
626/* don't make this __exit, since it's called from __init ! */
627static void fini(void)
628{
629 int i, j;
630 for (i = 0; i < ports_c; i++) {
631 for (j = 0; j < 2; j++) {
632 if (ftp[i][j].me == NULL)
633 continue;
634
635 DEBUGP("nf_ct_ftp: unregistering helper for pf: %d "
636 "port: %d\n",
637 ftp[i][j].tuple.src.l3num, ports[i]);
638 nf_conntrack_helper_unregister(&ftp[i][j]);
639 }
640 }
641
642 kfree(ftp_buffer);
643}
644
645static int __init init(void)
646{
647 int i, j = -1, ret = 0;
648 char *tmpname;
649
650 ftp_buffer = kmalloc(65536, GFP_KERNEL);
651 if (!ftp_buffer)
652 return -ENOMEM;
653
654 if (ports_c == 0)
655 ports[ports_c++] = FTP_PORT;
656
657 /* FIXME should be configurable whether IPv4 and IPv6 FTP connections
658 are tracked or not - YK */
659 for (i = 0; i < ports_c; i++) {
660 memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper));
661
662 ftp[i][0].tuple.src.l3num = PF_INET;
663 ftp[i][1].tuple.src.l3num = PF_INET6;
664 for (j = 0; j < 2; j++) {
665 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
666 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
667 ftp[i][j].mask.src.u.tcp.port = 0xFFFF;
668 ftp[i][j].mask.dst.protonum = 0xFF;
669 ftp[i][j].max_expected = 1;
670 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
671 ftp[i][j].me = THIS_MODULE;
672 ftp[i][j].help = help;
673 tmpname = &ftp_names[i][j][0];
674 if (ports[i] == FTP_PORT)
675 sprintf(tmpname, "ftp");
676 else
677 sprintf(tmpname, "ftp-%d", ports[i]);
678 ftp[i][j].name = tmpname;
679
680 DEBUGP("nf_ct_ftp: registering helper for pf: %d "
681 "port: %d\n",
682 ftp[i][j].tuple.src.l3num, ports[i]);
683 ret = nf_conntrack_helper_register(&ftp[i][j]);
684 if (ret) {
685 printk("nf_ct_ftp: failed to register helper "
686 " for pf: %d port: %d\n",
687 ftp[i][j].tuple.src.l3num, ports[i]);
688 fini();
689 return ret;
690 }
691 }
692 }
693
694 return 0;
695}
696
697module_init(init);
698module_exit(fini);
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
new file mode 100644
index 000000000000..7de4f06c63c5
--- /dev/null
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -0,0 +1,98 @@
1/*
2 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
3 *
4 * Based largely upon the original ip_conntrack code which
5 * had the following copyright information:
6 *
7 * (C) 1999-2001 Paul `Rusty' Russell
8 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Author:
15 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
16 */
17
18#include <linux/config.h>
19#include <linux/types.h>
20#include <linux/ip.h>
21#include <linux/netfilter.h>
22#include <linux/module.h>
23#include <linux/skbuff.h>
24#include <linux/icmp.h>
25#include <linux/sysctl.h>
26#include <net/ip.h>
27
28#include <linux/netfilter_ipv4.h>
29#include <net/netfilter/nf_conntrack.h>
30#include <net/netfilter/nf_conntrack_protocol.h>
31#include <net/netfilter/nf_conntrack_l3proto.h>
32#include <net/netfilter/nf_conntrack_core.h>
33#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
34
35#if 0
36#define DEBUGP printk
37#else
38#define DEBUGP(format, args...)
39#endif
40
41DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
42
43static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
44 struct nf_conntrack_tuple *tuple)
45{
46 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
47 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
48
49 return 1;
50}
51
52static int generic_invert_tuple(struct nf_conntrack_tuple *tuple,
53 const struct nf_conntrack_tuple *orig)
54{
55 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
56 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
57
58 return 1;
59}
60
61static int generic_print_tuple(struct seq_file *s,
62 const struct nf_conntrack_tuple *tuple)
63{
64 return 0;
65}
66
67static int generic_print_conntrack(struct seq_file *s,
68 const struct nf_conn *conntrack)
69{
70 return 0;
71}
72
73static int
74generic_prepare(struct sk_buff **pskb, unsigned int hooknum,
75 unsigned int *dataoff, u_int8_t *protonum)
76{
77 /* Never track !!! */
78 return -NF_ACCEPT;
79}
80
81
82static u_int32_t generic_get_features(const struct nf_conntrack_tuple *tuple)
83
84{
85 return NF_CT_F_BASIC;
86}
87
88struct nf_conntrack_l3proto nf_conntrack_generic_l3proto = {
89 .l3proto = PF_UNSPEC,
90 .name = "unknown",
91 .pkt_to_tuple = generic_pkt_to_tuple,
92 .invert_tuple = generic_invert_tuple,
93 .print_tuple = generic_print_tuple,
94 .print_conntrack = generic_print_conntrack,
95 .prepare = generic_prepare,
96 .get_features = generic_get_features,
97 .me = THIS_MODULE,
98};
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
new file mode 100644
index 000000000000..36425f6c833f
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -0,0 +1,85 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - enable working with L3 protocol independent connection tracking.
10 *
11 * Derived from net/ipv4/netfilter/ip_conntrack_proto_generic.c
12 */
13
14#include <linux/types.h>
15#include <linux/sched.h>
16#include <linux/timer.h>
17#include <linux/netfilter.h>
18#include <net/netfilter/nf_conntrack_protocol.h>
19
20unsigned long nf_ct_generic_timeout = 600*HZ;
21
22static int generic_pkt_to_tuple(const struct sk_buff *skb,
23 unsigned int dataoff,
24 struct nf_conntrack_tuple *tuple)
25{
26 tuple->src.u.all = 0;
27 tuple->dst.u.all = 0;
28
29 return 1;
30}
31
32static int generic_invert_tuple(struct nf_conntrack_tuple *tuple,
33 const struct nf_conntrack_tuple *orig)
34{
35 tuple->src.u.all = 0;
36 tuple->dst.u.all = 0;
37
38 return 1;
39}
40
41/* Print out the per-protocol part of the tuple. */
42static int generic_print_tuple(struct seq_file *s,
43 const struct nf_conntrack_tuple *tuple)
44{
45 return 0;
46}
47
48/* Print out the private part of the conntrack. */
49static int generic_print_conntrack(struct seq_file *s,
50 const struct nf_conn *state)
51{
52 return 0;
53}
54
55/* Returns verdict for packet, or -1 for invalid. */
56static int packet(struct nf_conn *conntrack,
57 const struct sk_buff *skb,
58 unsigned int dataoff,
59 enum ip_conntrack_info ctinfo,
60 int pf,
61 unsigned int hooknum)
62{
63 nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_generic_timeout);
64 return NF_ACCEPT;
65}
66
67/* Called when a new connection for this protocol found. */
68static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
69 unsigned int dataoff)
70{
71 return 1;
72}
73
74struct nf_conntrack_protocol nf_conntrack_generic_protocol =
75{
76 .l3proto = PF_UNSPEC,
77 .proto = 0,
78 .name = "unknown",
79 .pkt_to_tuple = generic_pkt_to_tuple,
80 .invert_tuple = generic_invert_tuple,
81 .print_tuple = generic_print_tuple,
82 .print_conntrack = generic_print_conntrack,
83 .packet = packet,
84 .new = new,
85};
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
new file mode 100644
index 000000000000..3a600f77b4e0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -0,0 +1,670 @@
1/*
2 * Connection tracking protocol helper module for SCTP.
3 *
4 * SCTP is defined in RFC 2960. References to various sections in this code
5 * are to this RFC.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * 17 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - enable working with L3 protocol independent connection tracking.
13 *
14 * Derived from net/ipv4/ip_conntrack_sctp.c
15 */
16
17/*
18 * Added support for proc manipulation of timeouts.
19 */
20
21#include <linux/types.h>
22#include <linux/sched.h>
23#include <linux/timer.h>
24#include <linux/netfilter.h>
25#include <linux/module.h>
26#include <linux/in.h>
27#include <linux/ip.h>
28#include <linux/sctp.h>
29#include <linux/string.h>
30#include <linux/seq_file.h>
31
32#include <net/netfilter/nf_conntrack.h>
33#include <net/netfilter/nf_conntrack_protocol.h>
34
35#if 0
36#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
37#else
38#define DEBUGP(format, args...)
39#endif
40
41/* Protects conntrack->proto.sctp */
42static DEFINE_RWLOCK(sctp_lock);
43
44/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
45 closely. They're more complex. --RR
46
47 And so for me for SCTP :D -Kiran */
48
49static const char *sctp_conntrack_names[] = {
50 "NONE",
51 "CLOSED",
52 "COOKIE_WAIT",
53 "COOKIE_ECHOED",
54 "ESTABLISHED",
55 "SHUTDOWN_SENT",
56 "SHUTDOWN_RECD",
57 "SHUTDOWN_ACK_SENT",
58};
59
60#define SECS * HZ
61#define MINS * 60 SECS
62#define HOURS * 60 MINS
63#define DAYS * 24 HOURS
64
65static unsigned long nf_ct_sctp_timeout_closed = 10 SECS;
66static unsigned long nf_ct_sctp_timeout_cookie_wait = 3 SECS;
67static unsigned long nf_ct_sctp_timeout_cookie_echoed = 3 SECS;
68static unsigned long nf_ct_sctp_timeout_established = 5 DAYS;
69static unsigned long nf_ct_sctp_timeout_shutdown_sent = 300 SECS / 1000;
70static unsigned long nf_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000;
71static unsigned long nf_ct_sctp_timeout_shutdown_ack_sent = 3 SECS;
72
73static unsigned long * sctp_timeouts[]
74= { NULL, /* SCTP_CONNTRACK_NONE */
75 &nf_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */
76 &nf_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */
77 &nf_ct_sctp_timeout_cookie_echoed, /* SCTP_CONNTRACK_COOKIE_ECHOED */
78 &nf_ct_sctp_timeout_established, /* SCTP_CONNTRACK_ESTABLISHED */
79 &nf_ct_sctp_timeout_shutdown_sent, /* SCTP_CONNTRACK_SHUTDOWN_SENT */
80 &nf_ct_sctp_timeout_shutdown_recd, /* SCTP_CONNTRACK_SHUTDOWN_RECD */
81 &nf_ct_sctp_timeout_shutdown_ack_sent /* SCTP_CONNTRACK_SHUTDOWN_ACK_SENT */
82 };
83
84#define sNO SCTP_CONNTRACK_NONE
85#define sCL SCTP_CONNTRACK_CLOSED
86#define sCW SCTP_CONNTRACK_COOKIE_WAIT
87#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
88#define sES SCTP_CONNTRACK_ESTABLISHED
89#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
90#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
91#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
92#define sIV SCTP_CONNTRACK_MAX
93
94/*
95 These are the descriptions of the states:
96
97NOTE: These state names are tantalizingly similar to the states of an
98SCTP endpoint. But the interpretation of the states is a little different,
99considering that these are the states of the connection and not of an end
100point. Please note the subtleties. -Kiran
101
102NONE - Nothing so far.
103COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
104 an INIT_ACK chunk in the reply direction.
105COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
106ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
107SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
108SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
109SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
110 to that of the SHUTDOWN chunk.
111CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
112 the SHUTDOWN chunk. Connection is closed.
113*/
114
115/* TODO
116 - I have assumed that the first INIT is in the original direction.
117 This messes things when an INIT comes in the reply direction in CLOSED
118 state.
119 - Check the error type in the reply dir before transitioning from
120cookie echoed to closed.
121 - Sec 5.2.4 of RFC 2960
122 - Multi Homing support.
123*/
124
125/* SCTP conntrack state transitions */
126static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
127 {
128/* ORIGINAL */
129/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
130/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
131/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
132/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
133/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
134/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
135/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/
136/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
137/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */
138/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
139 },
140 {
141/* REPLY */
142/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
143/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
144/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
145/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
146/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
147/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
148/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
149/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */
150/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
151/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
152 }
153};
154
155static int sctp_pkt_to_tuple(const struct sk_buff *skb,
156 unsigned int dataoff,
157 struct nf_conntrack_tuple *tuple)
158{
159 sctp_sctphdr_t _hdr, *hp;
160
161 DEBUGP(__FUNCTION__);
162 DEBUGP("\n");
163
164 /* Actually only need first 8 bytes. */
165 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
166 if (hp == NULL)
167 return 0;
168
169 tuple->src.u.sctp.port = hp->source;
170 tuple->dst.u.sctp.port = hp->dest;
171 return 1;
172}
173
174static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
175 const struct nf_conntrack_tuple *orig)
176{
177 DEBUGP(__FUNCTION__);
178 DEBUGP("\n");
179
180 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
181 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
182 return 1;
183}
184
185/* Print out the per-protocol part of the tuple. */
186static int sctp_print_tuple(struct seq_file *s,
187 const struct nf_conntrack_tuple *tuple)
188{
189 DEBUGP(__FUNCTION__);
190 DEBUGP("\n");
191
192 return seq_printf(s, "sport=%hu dport=%hu ",
193 ntohs(tuple->src.u.sctp.port),
194 ntohs(tuple->dst.u.sctp.port));
195}
196
197/* Print out the private part of the conntrack. */
198static int sctp_print_conntrack(struct seq_file *s,
199 const struct nf_conn *conntrack)
200{
201 enum sctp_conntrack state;
202
203 DEBUGP(__FUNCTION__);
204 DEBUGP("\n");
205
206 read_lock_bh(&sctp_lock);
207 state = conntrack->proto.sctp.state;
208 read_unlock_bh(&sctp_lock);
209
210 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
211}
212
213#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
214for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0; \
215 offset < skb->len && \
216 (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
217 offset += (htons(sch->length) + 3) & ~3, count++)
218
219/* Some validity checks to make sure the chunks are fine */
220static int do_basic_checks(struct nf_conn *conntrack,
221 const struct sk_buff *skb,
222 unsigned int dataoff,
223 char *map)
224{
225 u_int32_t offset, count;
226 sctp_chunkhdr_t _sch, *sch;
227 int flag;
228
229 DEBUGP(__FUNCTION__);
230 DEBUGP("\n");
231
232 flag = 0;
233
234 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
235 DEBUGP("Chunk Num: %d Type: %d\n", count, sch->type);
236
237 if (sch->type == SCTP_CID_INIT
238 || sch->type == SCTP_CID_INIT_ACK
239 || sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
240 flag = 1;
241 }
242
243 /* Cookie Ack/Echo chunks not the first OR
244 Init / Init Ack / Shutdown compl chunks not the only chunks */
245 if ((sch->type == SCTP_CID_COOKIE_ACK
246 || sch->type == SCTP_CID_COOKIE_ECHO
247 || flag)
248 && count !=0 ) {
249 DEBUGP("Basic checks failed\n");
250 return 1;
251 }
252
253 if (map) {
254 set_bit(sch->type, (void *)map);
255 }
256 }
257
258 DEBUGP("Basic checks passed\n");
259 return 0;
260}
261
262static int new_state(enum ip_conntrack_dir dir,
263 enum sctp_conntrack cur_state,
264 int chunk_type)
265{
266 int i;
267
268 DEBUGP(__FUNCTION__);
269 DEBUGP("\n");
270
271 DEBUGP("Chunk type: %d\n", chunk_type);
272
273 switch (chunk_type) {
274 case SCTP_CID_INIT:
275 DEBUGP("SCTP_CID_INIT\n");
276 i = 0; break;
277 case SCTP_CID_INIT_ACK:
278 DEBUGP("SCTP_CID_INIT_ACK\n");
279 i = 1; break;
280 case SCTP_CID_ABORT:
281 DEBUGP("SCTP_CID_ABORT\n");
282 i = 2; break;
283 case SCTP_CID_SHUTDOWN:
284 DEBUGP("SCTP_CID_SHUTDOWN\n");
285 i = 3; break;
286 case SCTP_CID_SHUTDOWN_ACK:
287 DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
288 i = 4; break;
289 case SCTP_CID_ERROR:
290 DEBUGP("SCTP_CID_ERROR\n");
291 i = 5; break;
292 case SCTP_CID_COOKIE_ECHO:
293 DEBUGP("SCTP_CID_COOKIE_ECHO\n");
294 i = 6; break;
295 case SCTP_CID_COOKIE_ACK:
296 DEBUGP("SCTP_CID_COOKIE_ACK\n");
297 i = 7; break;
298 case SCTP_CID_SHUTDOWN_COMPLETE:
299 DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n");
300 i = 8; break;
301 default:
302 /* Other chunks like DATA, SACK, HEARTBEAT and
303 its ACK do not cause a change in state */
304 DEBUGP("Unknown chunk type, Will stay in %s\n",
305 sctp_conntrack_names[cur_state]);
306 return cur_state;
307 }
308
309 DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
310 dir, sctp_conntrack_names[cur_state], chunk_type,
311 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
312
313 return sctp_conntracks[dir][i][cur_state];
314}
315
316/* Returns verdict for packet, or -1 for invalid. */
317static int sctp_packet(struct nf_conn *conntrack,
318 const struct sk_buff *skb,
319 unsigned int dataoff,
320 enum ip_conntrack_info ctinfo,
321 int pf,
322 unsigned int hooknum)
323{
324 enum sctp_conntrack newconntrack, oldsctpstate;
325 sctp_sctphdr_t _sctph, *sh;
326 sctp_chunkhdr_t _sch, *sch;
327 u_int32_t offset, count;
328 char map[256 / sizeof (char)] = {0};
329
330 DEBUGP(__FUNCTION__);
331 DEBUGP("\n");
332
333 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
334 if (sh == NULL)
335 return -1;
336
337 if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
338 return -1;
339
340 /* Check the verification tag (Sec 8.5) */
341 if (!test_bit(SCTP_CID_INIT, (void *)map)
342 && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)
343 && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)
344 && !test_bit(SCTP_CID_ABORT, (void *)map)
345 && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
346 && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
347 DEBUGP("Verification tag check failed\n");
348 return -1;
349 }
350
351 oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
352 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
353 write_lock_bh(&sctp_lock);
354
355 /* Special cases of Verification tag check (Sec 8.5.1) */
356 if (sch->type == SCTP_CID_INIT) {
357 /* Sec 8.5.1 (A) */
358 if (sh->vtag != 0) {
359 write_unlock_bh(&sctp_lock);
360 return -1;
361 }
362 } else if (sch->type == SCTP_CID_ABORT) {
363 /* Sec 8.5.1 (B) */
364 if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
365 && !(sh->vtag == conntrack->proto.sctp.vtag
366 [1 - CTINFO2DIR(ctinfo)])) {
367 write_unlock_bh(&sctp_lock);
368 return -1;
369 }
370 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
371 /* Sec 8.5.1 (C) */
372 if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
373 && !(sh->vtag == conntrack->proto.sctp.vtag
374 [1 - CTINFO2DIR(ctinfo)]
375 && (sch->flags & 1))) {
376 write_unlock_bh(&sctp_lock);
377 return -1;
378 }
379 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
380 /* Sec 8.5.1 (D) */
381 if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
382 write_unlock_bh(&sctp_lock);
383 return -1;
384 }
385 }
386
387 oldsctpstate = conntrack->proto.sctp.state;
388 newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);
389
390 /* Invalid */
391 if (newconntrack == SCTP_CONNTRACK_MAX) {
392 DEBUGP("nf_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
393 CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
394 write_unlock_bh(&sctp_lock);
395 return -1;
396 }
397
398 /* If it is an INIT or an INIT ACK note down the vtag */
399 if (sch->type == SCTP_CID_INIT
400 || sch->type == SCTP_CID_INIT_ACK) {
401 sctp_inithdr_t _inithdr, *ih;
402
403 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
404 sizeof(_inithdr), &_inithdr);
405 if (ih == NULL) {
406 write_unlock_bh(&sctp_lock);
407 return -1;
408 }
409 DEBUGP("Setting vtag %x for dir %d\n",
410 ih->init_tag, !CTINFO2DIR(ctinfo));
411 conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
412 }
413
414 conntrack->proto.sctp.state = newconntrack;
415 if (oldsctpstate != newconntrack)
416 nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
417 write_unlock_bh(&sctp_lock);
418 }
419
420 nf_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
421
422 if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
423 && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
424 && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
425 DEBUGP("Setting assured bit\n");
426 set_bit(IPS_ASSURED_BIT, &conntrack->status);
427 nf_conntrack_event_cache(IPCT_STATUS, skb);
428 }
429
430 return NF_ACCEPT;
431}
432
433/* Called when a new connection for this protocol found. */
434static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
435 unsigned int dataoff)
436{
437 enum sctp_conntrack newconntrack;
438 sctp_sctphdr_t _sctph, *sh;
439 sctp_chunkhdr_t _sch, *sch;
440 u_int32_t offset, count;
441 char map[256 / sizeof (char)] = {0};
442
443 DEBUGP(__FUNCTION__);
444 DEBUGP("\n");
445
446 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
447 if (sh == NULL)
448 return 0;
449
450 if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
451 return 0;
452
453 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
454 if ((test_bit (SCTP_CID_ABORT, (void *)map))
455 || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))
456 || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {
457 return 0;
458 }
459
460 newconntrack = SCTP_CONNTRACK_MAX;
461 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
462 /* Don't need lock here: this conntrack not in circulation yet */
463 newconntrack = new_state(IP_CT_DIR_ORIGINAL,
464 SCTP_CONNTRACK_NONE, sch->type);
465
466 /* Invalid: delete conntrack */
467 if (newconntrack == SCTP_CONNTRACK_MAX) {
468 DEBUGP("nf_conntrack_sctp: invalid new deleting.\n");
469 return 0;
470 }
471
472 /* Copy the vtag into the state info */
473 if (sch->type == SCTP_CID_INIT) {
474 if (sh->vtag == 0) {
475 sctp_inithdr_t _inithdr, *ih;
476
477 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
478 sizeof(_inithdr), &_inithdr);
479 if (ih == NULL)
480 return 0;
481
482 DEBUGP("Setting vtag %x for new conn\n",
483 ih->init_tag);
484
485 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
486 ih->init_tag;
487 } else {
488 /* Sec 8.5.1 (A) */
489 return 0;
490 }
491 }
492 /* If it is a shutdown ack OOTB packet, we expect a return
493 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
494 else {
495 DEBUGP("Setting vtag %x for new conn OOTB\n",
496 sh->vtag);
497 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
498 }
499
500 conntrack->proto.sctp.state = newconntrack;
501 }
502
503 return 1;
504}
505
506struct nf_conntrack_protocol nf_conntrack_protocol_sctp4 = {
507 .l3proto = PF_INET,
508 .proto = IPPROTO_SCTP,
509 .name = "sctp",
510 .pkt_to_tuple = sctp_pkt_to_tuple,
511 .invert_tuple = sctp_invert_tuple,
512 .print_tuple = sctp_print_tuple,
513 .print_conntrack = sctp_print_conntrack,
514 .packet = sctp_packet,
515 .new = sctp_new,
516 .destroy = NULL,
517 .me = THIS_MODULE
518};
519
520struct nf_conntrack_protocol nf_conntrack_protocol_sctp6 = {
521 .l3proto = PF_INET6,
522 .proto = IPPROTO_SCTP,
523 .name = "sctp",
524 .pkt_to_tuple = sctp_pkt_to_tuple,
525 .invert_tuple = sctp_invert_tuple,
526 .print_tuple = sctp_print_tuple,
527 .print_conntrack = sctp_print_conntrack,
528 .packet = sctp_packet,
529 .new = sctp_new,
530 .destroy = NULL,
531 .me = THIS_MODULE
532};
533
534#ifdef CONFIG_SYSCTL
535static ctl_table nf_ct_sysctl_table[] = {
536 {
537 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
538 .procname = "nf_conntrack_sctp_timeout_closed",
539 .data = &nf_ct_sctp_timeout_closed,
540 .maxlen = sizeof(unsigned int),
541 .mode = 0644,
542 .proc_handler = &proc_dointvec_jiffies,
543 },
544 {
545 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
546 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
547 .data = &nf_ct_sctp_timeout_cookie_wait,
548 .maxlen = sizeof(unsigned int),
549 .mode = 0644,
550 .proc_handler = &proc_dointvec_jiffies,
551 },
552 {
553 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
554 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
555 .data = &nf_ct_sctp_timeout_cookie_echoed,
556 .maxlen = sizeof(unsigned int),
557 .mode = 0644,
558 .proc_handler = &proc_dointvec_jiffies,
559 },
560 {
561 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
562 .procname = "nf_conntrack_sctp_timeout_established",
563 .data = &nf_ct_sctp_timeout_established,
564 .maxlen = sizeof(unsigned int),
565 .mode = 0644,
566 .proc_handler = &proc_dointvec_jiffies,
567 },
568 {
569 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
570 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
571 .data = &nf_ct_sctp_timeout_shutdown_sent,
572 .maxlen = sizeof(unsigned int),
573 .mode = 0644,
574 .proc_handler = &proc_dointvec_jiffies,
575 },
576 {
577 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
578 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
579 .data = &nf_ct_sctp_timeout_shutdown_recd,
580 .maxlen = sizeof(unsigned int),
581 .mode = 0644,
582 .proc_handler = &proc_dointvec_jiffies,
583 },
584 {
585 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
586 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
587 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
588 .maxlen = sizeof(unsigned int),
589 .mode = 0644,
590 .proc_handler = &proc_dointvec_jiffies,
591 },
592 { .ctl_name = 0 }
593};
594
595static ctl_table nf_ct_netfilter_table[] = {
596 {
597 .ctl_name = NET_NETFILTER,
598 .procname = "netfilter",
599 .mode = 0555,
600 .child = nf_ct_sysctl_table,
601 },
602 { .ctl_name = 0 }
603};
604
605static ctl_table nf_ct_net_table[] = {
606 {
607 .ctl_name = CTL_NET,
608 .procname = "net",
609 .mode = 0555,
610 .child = nf_ct_netfilter_table,
611 },
612 { .ctl_name = 0 }
613};
614
615static struct ctl_table_header *nf_ct_sysctl_header;
616#endif
617
618int __init init(void)
619{
620 int ret;
621
622 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp4);
623 if (ret) {
624 printk("nf_conntrack_proto_sctp4: protocol register failed\n");
625 goto out;
626 }
627 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp6);
628 if (ret) {
629 printk("nf_conntrack_proto_sctp6: protocol register failed\n");
630 goto cleanup_sctp4;
631 }
632
633#ifdef CONFIG_SYSCTL
634 nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
635 if (nf_ct_sysctl_header == NULL) {
636 printk("nf_conntrack_proto_sctp: can't register to sysctl.\n");
637 goto cleanup;
638 }
639#endif
640
641 return ret;
642
643#ifdef CONFIG_SYSCTL
644 cleanup:
645 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
646#endif
647 cleanup_sctp4:
648 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
649 out:
650 DEBUGP("SCTP conntrack module loading %s\n",
651 ret ? "failed": "succeeded");
652 return ret;
653}
654
655void __exit fini(void)
656{
657 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
658 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
659#ifdef CONFIG_SYSCTL
660 unregister_sysctl_table(nf_ct_sysctl_header);
661#endif
662 DEBUGP("SCTP conntrack module unloaded\n");
663}
664
665module_init(init);
666module_exit(fini);
667
668MODULE_LICENSE("GPL");
669MODULE_AUTHOR("Kiran Kumar Immidi");
670MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
new file mode 100644
index 000000000000..83d90dd624f0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -0,0 +1,1162 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>:
9 * - Real stateful connection tracking
10 * - Modified state transitions table
11 * - Window scaling support added
12 * - SACK support added
13 *
14 * Willy Tarreau:
15 * - State table bugfixes
16 * - More robust state changes
17 * - Tuning timer parameters
18 *
19 * 27 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
20 * - genelized Layer 3 protocol part.
21 *
22 * Derived from net/ipv4/netfilter/ip_conntrack_proto_tcp.c
23 *
24 * version 2.2
25 */
26
27#include <linux/config.h>
28#include <linux/types.h>
29#include <linux/sched.h>
30#include <linux/timer.h>
31#include <linux/netfilter.h>
32#include <linux/module.h>
33#include <linux/in.h>
34#include <linux/tcp.h>
35#include <linux/spinlock.h>
36#include <linux/skbuff.h>
37#include <linux/ipv6.h>
38#include <net/ip6_checksum.h>
39
40#include <net/tcp.h>
41
42#include <linux/netfilter.h>
43#include <linux/netfilter_ipv4.h>
44#include <linux/netfilter_ipv6.h>
45#include <net/netfilter/nf_conntrack.h>
46#include <net/netfilter/nf_conntrack_protocol.h>
47
48#if 0
49#define DEBUGP printk
50#define DEBUGP_VARS
51#else
52#define DEBUGP(format, args...)
53#endif
54
55/* Protects conntrack->proto.tcp */
56static DEFINE_RWLOCK(tcp_lock);
57
58/* "Be conservative in what you do,
59 be liberal in what you accept from others."
60 If it's non-zero, we mark only out of window RST segments as INVALID. */
61int nf_ct_tcp_be_liberal = 0;
62
63/* When connection is picked up from the middle, how many packets are required
64 to pass in each direction when we assume we are in sync - if any side uses
65 window scaling, we lost the game.
66 If it is set to zero, we disable picking up already established
67 connections. */
68int nf_ct_tcp_loose = 3;
69
70/* Max number of the retransmitted packets without receiving an (acceptable)
71 ACK from the destination. If this number is reached, a shorter timer
72 will be started. */
73int nf_ct_tcp_max_retrans = 3;
74
75 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
76 closely. They're more complex. --RR */
77
78static const char *tcp_conntrack_names[] = {
79 "NONE",
80 "SYN_SENT",
81 "SYN_RECV",
82 "ESTABLISHED",
83 "FIN_WAIT",
84 "CLOSE_WAIT",
85 "LAST_ACK",
86 "TIME_WAIT",
87 "CLOSE",
88 "LISTEN"
89};
90
91#define SECS * HZ
92#define MINS * 60 SECS
93#define HOURS * 60 MINS
94#define DAYS * 24 HOURS
95
96unsigned long nf_ct_tcp_timeout_syn_sent = 2 MINS;
97unsigned long nf_ct_tcp_timeout_syn_recv = 60 SECS;
98unsigned long nf_ct_tcp_timeout_established = 5 DAYS;
99unsigned long nf_ct_tcp_timeout_fin_wait = 2 MINS;
100unsigned long nf_ct_tcp_timeout_close_wait = 60 SECS;
101unsigned long nf_ct_tcp_timeout_last_ack = 30 SECS;
102unsigned long nf_ct_tcp_timeout_time_wait = 2 MINS;
103unsigned long nf_ct_tcp_timeout_close = 10 SECS;
104
105/* RFC1122 says the R2 limit should be at least 100 seconds.
106 Linux uses 15 packets as limit, which corresponds
107 to ~13-30min depending on RTO. */
108unsigned long nf_ct_tcp_timeout_max_retrans = 5 MINS;
109
110static unsigned long * tcp_timeouts[]
111= { NULL, /* TCP_CONNTRACK_NONE */
112 &nf_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
113 &nf_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
114 &nf_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */
115 &nf_ct_tcp_timeout_fin_wait, /* TCP_CONNTRACK_FIN_WAIT, */
116 &nf_ct_tcp_timeout_close_wait, /* TCP_CONNTRACK_CLOSE_WAIT, */
117 &nf_ct_tcp_timeout_last_ack, /* TCP_CONNTRACK_LAST_ACK, */
118 &nf_ct_tcp_timeout_time_wait, /* TCP_CONNTRACK_TIME_WAIT, */
119 &nf_ct_tcp_timeout_close, /* TCP_CONNTRACK_CLOSE, */
120 NULL, /* TCP_CONNTRACK_LISTEN */
121 };
122
123#define sNO TCP_CONNTRACK_NONE
124#define sSS TCP_CONNTRACK_SYN_SENT
125#define sSR TCP_CONNTRACK_SYN_RECV
126#define sES TCP_CONNTRACK_ESTABLISHED
127#define sFW TCP_CONNTRACK_FIN_WAIT
128#define sCW TCP_CONNTRACK_CLOSE_WAIT
129#define sLA TCP_CONNTRACK_LAST_ACK
130#define sTW TCP_CONNTRACK_TIME_WAIT
131#define sCL TCP_CONNTRACK_CLOSE
132#define sLI TCP_CONNTRACK_LISTEN
133#define sIV TCP_CONNTRACK_MAX
134#define sIG TCP_CONNTRACK_IGNORE
135
136/* What TCP flags are set from RST/SYN/FIN/ACK. */
137enum tcp_bit_set {
138 TCP_SYN_SET,
139 TCP_SYNACK_SET,
140 TCP_FIN_SET,
141 TCP_ACK_SET,
142 TCP_RST_SET,
143 TCP_NONE_SET,
144};
145
146/*
147 * The TCP state transition table needs a few words...
148 *
149 * We are the man in the middle. All the packets go through us
150 * but might get lost in transit to the destination.
151 * It is assumed that the destinations can't receive segments
152 * we haven't seen.
153 *
154 * The checked segment is in window, but our windows are *not*
155 * equivalent with the ones of the sender/receiver. We always
156 * try to guess the state of the current sender.
157 *
158 * The meaning of the states are:
159 *
160 * NONE: initial state
161 * SYN_SENT: SYN-only packet seen
162 * SYN_RECV: SYN-ACK packet seen
163 * ESTABLISHED: ACK packet seen
164 * FIN_WAIT: FIN packet seen
165 * CLOSE_WAIT: ACK seen (after FIN)
166 * LAST_ACK: FIN seen (after FIN)
167 * TIME_WAIT: last ACK seen
168 * CLOSE: closed connection
169 *
170 * LISTEN state is not used.
171 *
172 * Packets marked as IGNORED (sIG):
173 * if they may be either invalid or valid
174 * and the receiver may send back a connection
175 * closing RST or a SYN/ACK.
176 *
177 * Packets marked as INVALID (sIV):
178 * if they are invalid
179 * or we do not support the request (simultaneous open)
180 */
181static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
182 {
183/* ORIGINAL */
184/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
185/*syn*/ { sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sIV },
186/*
187 * sNO -> sSS Initialize a new connection
188 * sSS -> sSS Retransmitted SYN
189 * sSR -> sIG Late retransmitted SYN?
190 * sES -> sIG Error: SYNs in window outside the SYN_SENT state
191 * are errors. Receiver will reply with RST
192 * and close the connection.
193 * Or we are not in sync and hold a dead connection.
194 * sFW -> sIG
195 * sCW -> sIG
196 * sLA -> sIG
197 * sTW -> sSS Reopened connection (RFC 1122).
198 * sCL -> sSS
199 */
200/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
201/*synack*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
202/*
203 * A SYN/ACK from the client is always invalid:
204 * - either it tries to set up a simultaneous open, which is
205 * not supported;
206 * - or the firewall has just been inserted between the two hosts
207 * during the session set-up. The SYN will be retransmitted
208 * by the true client (or it'll time out).
209 */
210/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
211/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
212/*
213 * sNO -> sIV Too late and no reason to do anything...
214 * sSS -> sIV Client migth not send FIN in this state:
215 * we enforce waiting for a SYN/ACK reply first.
216 * sSR -> sFW Close started.
217 * sES -> sFW
218 * sFW -> sLA FIN seen in both directions, waiting for
219 * the last ACK.
220 * Migth be a retransmitted FIN as well...
221 * sCW -> sLA
222 * sLA -> sLA Retransmitted FIN. Remain in the same state.
223 * sTW -> sTW
224 * sCL -> sCL
225 */
226/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
227/*ack*/ { sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV },
228/*
229 * sNO -> sES Assumed.
230 * sSS -> sIV ACK is invalid: we haven't seen a SYN/ACK yet.
231 * sSR -> sES Established state is reached.
232 * sES -> sES :-)
233 * sFW -> sCW Normal close request answered by ACK.
234 * sCW -> sCW
235 * sLA -> sTW Last ACK detected.
236 * sTW -> sTW Retransmitted last ACK. Remain in the same state.
237 * sCL -> sCL
238 */
239/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
240/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
241/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
242 },
243 {
244/* REPLY */
245/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
246/*syn*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
247/*
248 * sNO -> sIV Never reached.
249 * sSS -> sIV Simultaneous open, not supported
250 * sSR -> sIV Simultaneous open, not supported.
251 * sES -> sIV Server may not initiate a connection.
252 * sFW -> sIV
253 * sCW -> sIV
254 * sLA -> sIV
255 * sTW -> sIV Reopened connection, but server may not do it.
256 * sCL -> sIV
257 */
258/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
259/*synack*/ { sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sIV },
260/*
261 * sSS -> sSR Standard open.
262 * sSR -> sSR Retransmitted SYN/ACK.
263 * sES -> sIG Late retransmitted SYN/ACK?
264 * sFW -> sIG Might be SYN/ACK answering ignored SYN
265 * sCW -> sIG
266 * sLA -> sIG
267 * sTW -> sIG
268 * sCL -> sIG
269 */
270/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
271/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
272/*
273 * sSS -> sIV Server might not send FIN in this state.
274 * sSR -> sFW Close started.
275 * sES -> sFW
276 * sFW -> sLA FIN seen in both directions.
277 * sCW -> sLA
278 * sLA -> sLA Retransmitted FIN.
279 * sTW -> sTW
280 * sCL -> sCL
281 */
282/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
283/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
284/*
285 * sSS -> sIV Might be a half-open connection.
286 * sSR -> sSR Might answer late resent SYN.
287 * sES -> sES :-)
288 * sFW -> sCW Normal close request answered by ACK.
289 * sCW -> sCW
290 * sLA -> sTW Last ACK detected.
291 * sTW -> sTW Retransmitted last ACK.
292 * sCL -> sCL
293 */
294/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
295/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
296/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
297 }
298};
299
300static int tcp_pkt_to_tuple(const struct sk_buff *skb,
301 unsigned int dataoff,
302 struct nf_conntrack_tuple *tuple)
303{
304 struct tcphdr _hdr, *hp;
305
306 /* Actually only need first 8 bytes. */
307 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
308 if (hp == NULL)
309 return 0;
310
311 tuple->src.u.tcp.port = hp->source;
312 tuple->dst.u.tcp.port = hp->dest;
313
314 return 1;
315}
316
317static int tcp_invert_tuple(struct nf_conntrack_tuple *tuple,
318 const struct nf_conntrack_tuple *orig)
319{
320 tuple->src.u.tcp.port = orig->dst.u.tcp.port;
321 tuple->dst.u.tcp.port = orig->src.u.tcp.port;
322 return 1;
323}
324
325/* Print out the per-protocol part of the tuple. */
326static int tcp_print_tuple(struct seq_file *s,
327 const struct nf_conntrack_tuple *tuple)
328{
329 return seq_printf(s, "sport=%hu dport=%hu ",
330 ntohs(tuple->src.u.tcp.port),
331 ntohs(tuple->dst.u.tcp.port));
332}
333
334/* Print out the private part of the conntrack. */
335static int tcp_print_conntrack(struct seq_file *s,
336 const struct nf_conn *conntrack)
337{
338 enum tcp_conntrack state;
339
340 read_lock_bh(&tcp_lock);
341 state = conntrack->proto.tcp.state;
342 read_unlock_bh(&tcp_lock);
343
344 return seq_printf(s, "%s ", tcp_conntrack_names[state]);
345}
346
347static unsigned int get_conntrack_index(const struct tcphdr *tcph)
348{
349 if (tcph->rst) return TCP_RST_SET;
350 else if (tcph->syn) return (tcph->ack ? TCP_SYNACK_SET : TCP_SYN_SET);
351 else if (tcph->fin) return TCP_FIN_SET;
352 else if (tcph->ack) return TCP_ACK_SET;
353 else return TCP_NONE_SET;
354}
355
356/* TCP connection tracking based on 'Real Stateful TCP Packet Filtering
357 in IP Filter' by Guido van Rooij.
358
359 http://www.nluug.nl/events/sane2000/papers.html
360 http://www.iae.nl/users/guido/papers/tcp_filtering.ps.gz
361
362 The boundaries and the conditions are changed according to RFC793:
363 the packet must intersect the window (i.e. segments may be
364 after the right or before the left edge) and thus receivers may ACK
365 segments after the right edge of the window.
366
367 td_maxend = max(sack + max(win,1)) seen in reply packets
368 td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets
369 td_maxwin += seq + len - sender.td_maxend
370 if seq + len > sender.td_maxend
371 td_end = max(seq + len) seen in sent packets
372
373 I. Upper bound for valid data: seq <= sender.td_maxend
374 II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin
375 III. Upper bound for valid ack: sack <= receiver.td_end
376 IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW
377
378 where sack is the highest right edge of sack block found in the packet.
379
380 The upper bound limit for a valid ack is not ignored -
381 we doesn't have to deal with fragments.
382*/
383
384static inline __u32 segment_seq_plus_len(__u32 seq,
385 size_t len,
386 unsigned int dataoff,
387 struct tcphdr *tcph)
388{
389 /* XXX Should I use payload length field in IP/IPv6 header ?
390 * - YK */
391 return (seq + len - dataoff - tcph->doff*4
392 + (tcph->syn ? 1 : 0) + (tcph->fin ? 1 : 0));
393}
394
395/* Fixme: what about big packets? */
396#define MAXACKWINCONST 66000
397#define MAXACKWINDOW(sender) \
398 ((sender)->td_maxwin > MAXACKWINCONST ? (sender)->td_maxwin \
399 : MAXACKWINCONST)
400
401/*
402 * Simplified tcp_parse_options routine from tcp_input.c
403 */
404static void tcp_options(const struct sk_buff *skb,
405 unsigned int dataoff,
406 struct tcphdr *tcph,
407 struct ip_ct_tcp_state *state)
408{
409 unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
410 unsigned char *ptr;
411 int length = (tcph->doff*4) - sizeof(struct tcphdr);
412
413 if (!length)
414 return;
415
416 ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
417 length, buff);
418 BUG_ON(ptr == NULL);
419
420 state->td_scale =
421 state->flags = 0;
422
423 while (length > 0) {
424 int opcode=*ptr++;
425 int opsize;
426
427 switch (opcode) {
428 case TCPOPT_EOL:
429 return;
430 case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
431 length--;
432 continue;
433 default:
434 opsize=*ptr++;
435 if (opsize < 2) /* "silly options" */
436 return;
437 if (opsize > length)
438 break; /* don't parse partial options */
439
440 if (opcode == TCPOPT_SACK_PERM
441 && opsize == TCPOLEN_SACK_PERM)
442 state->flags |= IP_CT_TCP_FLAG_SACK_PERM;
443 else if (opcode == TCPOPT_WINDOW
444 && opsize == TCPOLEN_WINDOW) {
445 state->td_scale = *(u_int8_t *)ptr;
446
447 if (state->td_scale > 14) {
448 /* See RFC1323 */
449 state->td_scale = 14;
450 }
451 state->flags |=
452 IP_CT_TCP_FLAG_WINDOW_SCALE;
453 }
454 ptr += opsize - 2;
455 length -= opsize;
456 }
457 }
458}
459
460static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
461 struct tcphdr *tcph, __u32 *sack)
462{
463 unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
464 unsigned char *ptr;
465 int length = (tcph->doff*4) - sizeof(struct tcphdr);
466 __u32 tmp;
467
468 if (!length)
469 return;
470
471 ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
472 length, buff);
473 BUG_ON(ptr == NULL);
474
475 /* Fast path for timestamp-only option */
476 if (length == TCPOLEN_TSTAMP_ALIGNED*4
477 && *(__u32 *)ptr ==
478 __constant_ntohl((TCPOPT_NOP << 24)
479 | (TCPOPT_NOP << 16)
480 | (TCPOPT_TIMESTAMP << 8)
481 | TCPOLEN_TIMESTAMP))
482 return;
483
484 while (length > 0) {
485 int opcode = *ptr++;
486 int opsize, i;
487
488 switch (opcode) {
489 case TCPOPT_EOL:
490 return;
491 case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
492 length--;
493 continue;
494 default:
495 opsize = *ptr++;
496 if (opsize < 2) /* "silly options" */
497 return;
498 if (opsize > length)
499 break; /* don't parse partial options */
500
501 if (opcode == TCPOPT_SACK
502 && opsize >= (TCPOLEN_SACK_BASE
503 + TCPOLEN_SACK_PERBLOCK)
504 && !((opsize - TCPOLEN_SACK_BASE)
505 % TCPOLEN_SACK_PERBLOCK)) {
506 for (i = 0;
507 i < (opsize - TCPOLEN_SACK_BASE);
508 i += TCPOLEN_SACK_PERBLOCK) {
509 memcpy(&tmp, (__u32 *)(ptr + i) + 1,
510 sizeof(__u32));
511 tmp = ntohl(tmp);
512
513 if (after(tmp, *sack))
514 *sack = tmp;
515 }
516 return;
517 }
518 ptr += opsize - 2;
519 length -= opsize;
520 }
521 }
522}
523
524static int tcp_in_window(struct ip_ct_tcp *state,
525 enum ip_conntrack_dir dir,
526 unsigned int index,
527 const struct sk_buff *skb,
528 unsigned int dataoff,
529 struct tcphdr *tcph,
530 int pf)
531{
532 struct ip_ct_tcp_state *sender = &state->seen[dir];
533 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
534 __u32 seq, ack, sack, end, win, swin;
535 int res;
536
537 /*
538 * Get the required data from the packet.
539 */
540 seq = ntohl(tcph->seq);
541 ack = sack = ntohl(tcph->ack_seq);
542 win = ntohs(tcph->window);
543 end = segment_seq_plus_len(seq, skb->len, dataoff, tcph);
544
545 if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
546 tcp_sack(skb, dataoff, tcph, &sack);
547
548 DEBUGP("tcp_in_window: START\n");
549 DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
550 "seq=%u ack=%u sack=%u win=%u end=%u\n",
551 NIPQUAD(iph->saddr), ntohs(tcph->source),
552 NIPQUAD(iph->daddr), ntohs(tcph->dest),
553 seq, ack, sack, win, end);
554 DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
555 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
556 sender->td_end, sender->td_maxend, sender->td_maxwin,
557 sender->td_scale,
558 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
559 receiver->td_scale);
560
561 if (sender->td_end == 0) {
562 /*
563 * Initialize sender data.
564 */
565 if (tcph->syn && tcph->ack) {
566 /*
567 * Outgoing SYN-ACK in reply to a SYN.
568 */
569 sender->td_end =
570 sender->td_maxend = end;
571 sender->td_maxwin = (win == 0 ? 1 : win);
572
573 tcp_options(skb, dataoff, tcph, sender);
574 /*
575 * RFC 1323:
576 * Both sides must send the Window Scale option
577 * to enable window scaling in either direction.
578 */
579 if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE
580 && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE))
581 sender->td_scale =
582 receiver->td_scale = 0;
583 } else {
584 /*
585 * We are in the middle of a connection,
586 * its history is lost for us.
587 * Let's try to use the data from the packet.
588 */
589 sender->td_end = end;
590 sender->td_maxwin = (win == 0 ? 1 : win);
591 sender->td_maxend = end + sender->td_maxwin;
592 }
593 } else if (((state->state == TCP_CONNTRACK_SYN_SENT
594 && dir == IP_CT_DIR_ORIGINAL)
595 || (state->state == TCP_CONNTRACK_SYN_RECV
596 && dir == IP_CT_DIR_REPLY))
597 && after(end, sender->td_end)) {
598 /*
599 * RFC 793: "if a TCP is reinitialized ... then it need
600 * not wait at all; it must only be sure to use sequence
601 * numbers larger than those recently used."
602 */
603 sender->td_end =
604 sender->td_maxend = end;
605 sender->td_maxwin = (win == 0 ? 1 : win);
606
607 tcp_options(skb, dataoff, tcph, sender);
608 }
609
610 if (!(tcph->ack)) {
611 /*
612 * If there is no ACK, just pretend it was set and OK.
613 */
614 ack = sack = receiver->td_end;
615 } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) ==
616 (TCP_FLAG_ACK|TCP_FLAG_RST))
617 && (ack == 0)) {
618 /*
619 * Broken TCP stacks, that set ACK in RST packets as well
620 * with zero ack value.
621 */
622 ack = sack = receiver->td_end;
623 }
624
625 if (seq == end
626 && (!tcph->rst
627 || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)))
628 /*
629 * Packets contains no data: we assume it is valid
630 * and check the ack value only.
631 * However RST segments are always validated by their
632 * SEQ number, except when seq == 0 (reset sent answering
633 * SYN.
634 */
635 seq = end = sender->td_end;
636
637 DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
638 "seq=%u ack=%u sack =%u win=%u end=%u\n",
639 NIPQUAD(iph->saddr), ntohs(tcph->source),
640 NIPQUAD(iph->daddr), ntohs(tcph->dest),
641 seq, ack, sack, win, end);
642 DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
643 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
644 sender->td_end, sender->td_maxend, sender->td_maxwin,
645 sender->td_scale,
646 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
647 receiver->td_scale);
648
649 DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
650 before(seq, sender->td_maxend + 1),
651 after(end, sender->td_end - receiver->td_maxwin - 1),
652 before(sack, receiver->td_end + 1),
653 after(ack, receiver->td_end - MAXACKWINDOW(sender)));
654
655 if (sender->loose || receiver->loose ||
656 (before(seq, sender->td_maxend + 1) &&
657 after(end, sender->td_end - receiver->td_maxwin - 1) &&
658 before(sack, receiver->td_end + 1) &&
659 after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
660 /*
661 * Take into account window scaling (RFC 1323).
662 */
663 if (!tcph->syn)
664 win <<= sender->td_scale;
665
666 /*
667 * Update sender data.
668 */
669 swin = win + (sack - ack);
670 if (sender->td_maxwin < swin)
671 sender->td_maxwin = swin;
672 if (after(end, sender->td_end))
673 sender->td_end = end;
674 /*
675 * Update receiver data.
676 */
677 if (after(end, sender->td_maxend))
678 receiver->td_maxwin += end - sender->td_maxend;
679 if (after(sack + win, receiver->td_maxend - 1)) {
680 receiver->td_maxend = sack + win;
681 if (win == 0)
682 receiver->td_maxend++;
683 }
684
685 /*
686 * Check retransmissions.
687 */
688 if (index == TCP_ACK_SET) {
689 if (state->last_dir == dir
690 && state->last_seq == seq
691 && state->last_ack == ack
692 && state->last_end == end)
693 state->retrans++;
694 else {
695 state->last_dir = dir;
696 state->last_seq = seq;
697 state->last_ack = ack;
698 state->last_end = end;
699 state->retrans = 0;
700 }
701 }
702 /*
703 * Close the window of disabled window tracking :-)
704 */
705 if (sender->loose)
706 sender->loose--;
707
708 res = 1;
709 } else {
710 if (LOG_INVALID(IPPROTO_TCP))
711 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
712 "nf_ct_tcp: %s ",
713 before(seq, sender->td_maxend + 1) ?
714 after(end, sender->td_end - receiver->td_maxwin - 1) ?
715 before(sack, receiver->td_end + 1) ?
716 after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG"
717 : "ACK is under the lower bound (possible overly delayed ACK)"
718 : "ACK is over the upper bound (ACKed data not seen yet)"
719 : "SEQ is under the lower bound (already ACKed data retransmitted)"
720 : "SEQ is over the upper bound (over the window of the receiver)");
721
722 res = nf_ct_tcp_be_liberal;
723 }
724
725 DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
726 "receiver end=%u maxend=%u maxwin=%u\n",
727 res, sender->td_end, sender->td_maxend, sender->td_maxwin,
728 receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
729
730 return res;
731}
732
733#ifdef CONFIG_IP_NF_NAT_NEEDED
734/* Update sender->td_end after NAT successfully mangled the packet */
735/* Caller must linearize skb at tcp header. */
736void nf_conntrack_tcp_update(struct sk_buff *skb,
737 unsigned int dataoff,
738 struct nf_conn *conntrack,
739 int dir)
740{
741 struct tcphdr *tcph = (void *)skb->data + dataoff;
742 __u32 end;
743#ifdef DEBUGP_VARS
744 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
745 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
746#endif
747
748 end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
749
750 write_lock_bh(&tcp_lock);
751 /*
752 * We have to worry for the ack in the reply packet only...
753 */
754 if (after(end, conntrack->proto.tcp.seen[dir].td_end))
755 conntrack->proto.tcp.seen[dir].td_end = end;
756 conntrack->proto.tcp.last_end = end;
757 write_unlock_bh(&tcp_lock);
758 DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
759 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
760 sender->td_end, sender->td_maxend, sender->td_maxwin,
761 sender->td_scale,
762 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
763 receiver->td_scale);
764}
765
766#endif
767
768#define TH_FIN 0x01
769#define TH_SYN 0x02
770#define TH_RST 0x04
771#define TH_PUSH 0x08
772#define TH_ACK 0x10
773#define TH_URG 0x20
774#define TH_ECE 0x40
775#define TH_CWR 0x80
776
777/* table of valid flag combinations - ECE and CWR are always valid */
778static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
779{
780 [TH_SYN] = 1,
781 [TH_SYN|TH_ACK] = 1,
782 [TH_SYN|TH_ACK|TH_PUSH] = 1,
783 [TH_RST] = 1,
784 [TH_RST|TH_ACK] = 1,
785 [TH_RST|TH_ACK|TH_PUSH] = 1,
786 [TH_FIN|TH_ACK] = 1,
787 [TH_ACK] = 1,
788 [TH_ACK|TH_PUSH] = 1,
789 [TH_ACK|TH_URG] = 1,
790 [TH_ACK|TH_URG|TH_PUSH] = 1,
791 [TH_FIN|TH_ACK|TH_PUSH] = 1,
792 [TH_FIN|TH_ACK|TH_URG] = 1,
793 [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1,
794};
795
796/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
797static int tcp_error(struct sk_buff *skb,
798 unsigned int dataoff,
799 enum ip_conntrack_info *ctinfo,
800 int pf,
801 unsigned int hooknum,
802 int(*csum)(const struct sk_buff *,unsigned int))
803{
804 struct tcphdr _tcph, *th;
805 unsigned int tcplen = skb->len - dataoff;
806 u_int8_t tcpflags;
807
808 /* Smaller that minimal TCP header? */
809 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
810 if (th == NULL) {
811 if (LOG_INVALID(IPPROTO_TCP))
812 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
813 "nf_ct_tcp: short packet ");
814 return -NF_ACCEPT;
815 }
816
817 /* Not whole TCP header or malformed packet */
818 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
819 if (LOG_INVALID(IPPROTO_TCP))
820 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
821 "nf_ct_tcp: truncated/malformed packet ");
822 return -NF_ACCEPT;
823 }
824
825 /* Checksum invalid? Ignore.
826 * We skip checking packets on the outgoing path
827 * because the semantic of CHECKSUM_HW is different there
828 * and moreover root might send raw packets.
829 */
830 /* FIXME: Source route IP option packets --RR */
831 if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
832 (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))
833 && skb->ip_summed != CHECKSUM_UNNECESSARY
834 && csum(skb, dataoff)) {
835 if (LOG_INVALID(IPPROTO_TCP))
836 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
837 "nf_ct_tcp: bad TCP checksum ");
838 return -NF_ACCEPT;
839 }
840
841 /* Check TCP flags. */
842 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR));
843 if (!tcp_valid_flags[tcpflags]) {
844 if (LOG_INVALID(IPPROTO_TCP))
845 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
846 "nf_ct_tcp: invalid TCP flag combination ");
847 return -NF_ACCEPT;
848 }
849
850 return NF_ACCEPT;
851}
852
853static int csum4(const struct sk_buff *skb, unsigned int dataoff)
854{
855 return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
856 skb->len - dataoff, IPPROTO_TCP,
857 skb->ip_summed == CHECKSUM_HW ? skb->csum
858 : skb_checksum(skb, dataoff,
859 skb->len - dataoff, 0));
860}
861
862static int csum6(const struct sk_buff *skb, unsigned int dataoff)
863{
864 return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
865 skb->len - dataoff, IPPROTO_TCP,
866 skb->ip_summed == CHECKSUM_HW ? skb->csum
867 : skb_checksum(skb, dataoff, skb->len - dataoff,
868 0));
869}
870
871static int tcp_error4(struct sk_buff *skb,
872 unsigned int dataoff,
873 enum ip_conntrack_info *ctinfo,
874 int pf,
875 unsigned int hooknum)
876{
877 return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
878}
879
880static int tcp_error6(struct sk_buff *skb,
881 unsigned int dataoff,
882 enum ip_conntrack_info *ctinfo,
883 int pf,
884 unsigned int hooknum)
885{
886 return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
887}
888
889/* Returns verdict for packet, or -1 for invalid. */
890static int tcp_packet(struct nf_conn *conntrack,
891 const struct sk_buff *skb,
892 unsigned int dataoff,
893 enum ip_conntrack_info ctinfo,
894 int pf,
895 unsigned int hooknum)
896{
897 enum tcp_conntrack new_state, old_state;
898 enum ip_conntrack_dir dir;
899 struct tcphdr *th, _tcph;
900 unsigned long timeout;
901 unsigned int index;
902
903 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
904 BUG_ON(th == NULL);
905
906 write_lock_bh(&tcp_lock);
907 old_state = conntrack->proto.tcp.state;
908 dir = CTINFO2DIR(ctinfo);
909 index = get_conntrack_index(th);
910 new_state = tcp_conntracks[dir][index][old_state];
911
912 switch (new_state) {
913 case TCP_CONNTRACK_IGNORE:
914 /* Either SYN in ORIGINAL
915 * or SYN/ACK in REPLY. */
916 if (index == TCP_SYNACK_SET
917 && conntrack->proto.tcp.last_index == TCP_SYN_SET
918 && conntrack->proto.tcp.last_dir != dir
919 && ntohl(th->ack_seq) ==
920 conntrack->proto.tcp.last_end) {
921 /* This SYN/ACK acknowledges a SYN that we earlier
922 * ignored as invalid. This means that the client and
923 * the server are both in sync, while the firewall is
924 * not. We kill this session and block the SYN/ACK so
925 * that the client cannot but retransmit its SYN and
926 * thus initiate a clean new session.
927 */
928 write_unlock_bh(&tcp_lock);
929 if (LOG_INVALID(IPPROTO_TCP))
930 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
931 "nf_ct_tcp: killing out of sync session ");
932 if (del_timer(&conntrack->timeout))
933 conntrack->timeout.function((unsigned long)
934 conntrack);
935 return -NF_DROP;
936 }
937 conntrack->proto.tcp.last_index = index;
938 conntrack->proto.tcp.last_dir = dir;
939 conntrack->proto.tcp.last_seq = ntohl(th->seq);
940 conntrack->proto.tcp.last_end =
941 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
942
943 write_unlock_bh(&tcp_lock);
944 if (LOG_INVALID(IPPROTO_TCP))
945 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
946 "nf_ct_tcp: invalid packed ignored ");
947 return NF_ACCEPT;
948 case TCP_CONNTRACK_MAX:
949 /* Invalid packet */
950 DEBUGP("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
951 dir, get_conntrack_index(th),
952 old_state);
953 write_unlock_bh(&tcp_lock);
954 if (LOG_INVALID(IPPROTO_TCP))
955 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
956 "nf_ct_tcp: invalid state ");
957 return -NF_ACCEPT;
958 case TCP_CONNTRACK_SYN_SENT:
959 if (old_state < TCP_CONNTRACK_TIME_WAIT)
960 break;
961 if ((conntrack->proto.tcp.seen[dir].flags &
962 IP_CT_TCP_FLAG_CLOSE_INIT)
963 || after(ntohl(th->seq),
964 conntrack->proto.tcp.seen[dir].td_end)) {
965 /* Attempt to reopen a closed connection.
966 * Delete this connection and look up again. */
967 write_unlock_bh(&tcp_lock);
968 if (del_timer(&conntrack->timeout))
969 conntrack->timeout.function((unsigned long)
970 conntrack);
971 return -NF_REPEAT;
972 }
973 case TCP_CONNTRACK_CLOSE:
974 if (index == TCP_RST_SET
975 && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
976 && conntrack->proto.tcp.last_index == TCP_SYN_SET
977 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
978 /* RST sent to invalid SYN we had let trough
979 * SYN was in window then, tear down connection.
980 * We skip window checking, because packet might ACK
981 * segments we ignored in the SYN. */
982 goto in_window;
983 }
984 /* Just fall trough */
985 default:
986 /* Keep compilers happy. */
987 break;
988 }
989
990 if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
991 skb, dataoff, th, pf)) {
992 write_unlock_bh(&tcp_lock);
993 return -NF_ACCEPT;
994 }
995 in_window:
996 /* From now on we have got in-window packets */
997 conntrack->proto.tcp.last_index = index;
998
999 DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
1000 "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
1001 NIPQUAD(iph->saddr), ntohs(th->source),
1002 NIPQUAD(iph->daddr), ntohs(th->dest),
1003 (th->syn ? 1 : 0), (th->ack ? 1 : 0),
1004 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
1005 old_state, new_state);
1006
1007 conntrack->proto.tcp.state = new_state;
1008 if (old_state != new_state
1009 && (new_state == TCP_CONNTRACK_FIN_WAIT
1010 || new_state == TCP_CONNTRACK_CLOSE))
1011 conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
1012 timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
1013 && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
1014 ? nf_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
1015 write_unlock_bh(&tcp_lock);
1016
1017 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
1018 if (new_state != old_state)
1019 nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
1020
1021 if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
1022 /* If only reply is a RST, we can consider ourselves not to
1023 have an established connection: this is a fairly common
1024 problem case, so we can delete the conntrack
1025 immediately. --RR */
1026 if (th->rst) {
1027 if (del_timer(&conntrack->timeout))
1028 conntrack->timeout.function((unsigned long)
1029 conntrack);
1030 return NF_ACCEPT;
1031 }
1032 } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
1033 && (old_state == TCP_CONNTRACK_SYN_RECV
1034 || old_state == TCP_CONNTRACK_ESTABLISHED)
1035 && new_state == TCP_CONNTRACK_ESTABLISHED) {
1036 /* Set ASSURED if we see see valid ack in ESTABLISHED
1037 after SYN_RECV or a valid answer for a picked up
1038 connection. */
1039 set_bit(IPS_ASSURED_BIT, &conntrack->status);
1040 nf_conntrack_event_cache(IPCT_STATUS, skb);
1041 }
1042 nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout);
1043
1044 return NF_ACCEPT;
1045}
1046
1047/* Called when a new connection for this protocol found. */
1048static int tcp_new(struct nf_conn *conntrack,
1049 const struct sk_buff *skb,
1050 unsigned int dataoff)
1051{
1052 enum tcp_conntrack new_state;
1053 struct tcphdr *th, _tcph;
1054#ifdef DEBUGP_VARS
1055 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
1056 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
1057#endif
1058
1059 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
1060 BUG_ON(th == NULL);
1061
1062 /* Don't need lock here: this conntrack not in circulation yet */
1063 new_state
1064 = tcp_conntracks[0][get_conntrack_index(th)]
1065 [TCP_CONNTRACK_NONE];
1066
1067 /* Invalid: delete conntrack */
1068 if (new_state >= TCP_CONNTRACK_MAX) {
1069 DEBUGP("nf_ct_tcp: invalid new deleting.\n");
1070 return 0;
1071 }
1072
1073 if (new_state == TCP_CONNTRACK_SYN_SENT) {
1074 /* SYN packet */
1075 conntrack->proto.tcp.seen[0].td_end =
1076 segment_seq_plus_len(ntohl(th->seq), skb->len,
1077 dataoff, th);
1078 conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
1079 if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
1080 conntrack->proto.tcp.seen[0].td_maxwin = 1;
1081 conntrack->proto.tcp.seen[0].td_maxend =
1082 conntrack->proto.tcp.seen[0].td_end;
1083
1084 tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);
1085 conntrack->proto.tcp.seen[1].flags = 0;
1086 conntrack->proto.tcp.seen[0].loose =
1087 conntrack->proto.tcp.seen[1].loose = 0;
1088 } else if (nf_ct_tcp_loose == 0) {
1089 /* Don't try to pick up connections. */
1090 return 0;
1091 } else {
1092 /*
1093 * We are in the middle of a connection,
1094 * its history is lost for us.
1095 * Let's try to use the data from the packet.
1096 */
1097 conntrack->proto.tcp.seen[0].td_end =
1098 segment_seq_plus_len(ntohl(th->seq), skb->len,
1099 dataoff, th);
1100 conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
1101 if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
1102 conntrack->proto.tcp.seen[0].td_maxwin = 1;
1103 conntrack->proto.tcp.seen[0].td_maxend =
1104 conntrack->proto.tcp.seen[0].td_end +
1105 conntrack->proto.tcp.seen[0].td_maxwin;
1106 conntrack->proto.tcp.seen[0].td_scale = 0;
1107
1108 /* We assume SACK. Should we assume window scaling too? */
1109 conntrack->proto.tcp.seen[0].flags =
1110 conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
1111 conntrack->proto.tcp.seen[0].loose =
1112 conntrack->proto.tcp.seen[1].loose = nf_ct_tcp_loose;
1113 }
1114
1115 conntrack->proto.tcp.seen[1].td_end = 0;
1116 conntrack->proto.tcp.seen[1].td_maxend = 0;
1117 conntrack->proto.tcp.seen[1].td_maxwin = 1;
1118 conntrack->proto.tcp.seen[1].td_scale = 0;
1119
1120 /* tcp_packet will set them */
1121 conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
1122 conntrack->proto.tcp.last_index = TCP_NONE_SET;
1123
1124 DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
1125 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
1126 sender->td_end, sender->td_maxend, sender->td_maxwin,
1127 sender->td_scale,
1128 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
1129 receiver->td_scale);
1130 return 1;
1131}
1132
1133struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
1134{
1135 .l3proto = PF_INET,
1136 .proto = IPPROTO_TCP,
1137 .name = "tcp",
1138 .pkt_to_tuple = tcp_pkt_to_tuple,
1139 .invert_tuple = tcp_invert_tuple,
1140 .print_tuple = tcp_print_tuple,
1141 .print_conntrack = tcp_print_conntrack,
1142 .packet = tcp_packet,
1143 .new = tcp_new,
1144 .error = tcp_error4,
1145};
1146
1147struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
1148{
1149 .l3proto = PF_INET6,
1150 .proto = IPPROTO_TCP,
1151 .name = "tcp",
1152 .pkt_to_tuple = tcp_pkt_to_tuple,
1153 .invert_tuple = tcp_invert_tuple,
1154 .print_tuple = tcp_print_tuple,
1155 .print_conntrack = tcp_print_conntrack,
1156 .packet = tcp_packet,
1157 .new = tcp_new,
1158 .error = tcp_error6,
1159};
1160
1161EXPORT_SYMBOL(nf_conntrack_protocol_tcp4);
1162EXPORT_SYMBOL(nf_conntrack_protocol_tcp6);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
new file mode 100644
index 000000000000..3cae7ce420dd
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -0,0 +1,216 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - enable working with Layer 3 protocol independent connection tracking.
10 *
11 * Derived from net/ipv4/netfilter/ip_conntrack_proto_udp.c
12 */
13
14#include <linux/types.h>
15#include <linux/sched.h>
16#include <linux/timer.h>
17#include <linux/module.h>
18#include <linux/netfilter.h>
19#include <linux/udp.h>
20#include <linux/seq_file.h>
21#include <linux/skbuff.h>
22#include <linux/ipv6.h>
23#include <net/ip6_checksum.h>
24#include <net/checksum.h>
25#include <linux/netfilter.h>
26#include <linux/netfilter_ipv4.h>
27#include <linux/netfilter_ipv6.h>
28#include <net/netfilter/nf_conntrack_protocol.h>
29
30unsigned long nf_ct_udp_timeout = 30*HZ;
31unsigned long nf_ct_udp_timeout_stream = 180*HZ;
32
33static int udp_pkt_to_tuple(const struct sk_buff *skb,
34 unsigned int dataoff,
35 struct nf_conntrack_tuple *tuple)
36{
37 struct udphdr _hdr, *hp;
38
39 /* Actually only need first 8 bytes. */
40 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
41 if (hp == NULL)
42 return 0;
43
44 tuple->src.u.udp.port = hp->source;
45 tuple->dst.u.udp.port = hp->dest;
46
47 return 1;
48}
49
50static int udp_invert_tuple(struct nf_conntrack_tuple *tuple,
51 const struct nf_conntrack_tuple *orig)
52{
53 tuple->src.u.udp.port = orig->dst.u.udp.port;
54 tuple->dst.u.udp.port = orig->src.u.udp.port;
55 return 1;
56}
57
58/* Print out the per-protocol part of the tuple. */
59static int udp_print_tuple(struct seq_file *s,
60 const struct nf_conntrack_tuple *tuple)
61{
62 return seq_printf(s, "sport=%hu dport=%hu ",
63 ntohs(tuple->src.u.udp.port),
64 ntohs(tuple->dst.u.udp.port));
65}
66
67/* Print out the private part of the conntrack. */
68static int udp_print_conntrack(struct seq_file *s,
69 const struct nf_conn *conntrack)
70{
71 return 0;
72}
73
74/* Returns verdict for packet, and may modify conntracktype */
75static int udp_packet(struct nf_conn *conntrack,
76 const struct sk_buff *skb,
77 unsigned int dataoff,
78 enum ip_conntrack_info ctinfo,
79 int pf,
80 unsigned int hooknum)
81{
82 /* If we've seen traffic both ways, this is some kind of UDP
83 stream. Extend timeout. */
84 if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
85 nf_ct_refresh_acct(conntrack, ctinfo, skb,
86 nf_ct_udp_timeout_stream);
87 /* Also, more likely to be important, and not a probe */
88 if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
89 nf_conntrack_event_cache(IPCT_STATUS, skb);
90 } else
91 nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout);
92
93 return NF_ACCEPT;
94}
95
96/* Called when a new connection for this protocol found. */
97static int udp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
98 unsigned int dataoff)
99{
100 return 1;
101}
102
103static int udp_error(struct sk_buff *skb, unsigned int dataoff,
104 enum ip_conntrack_info *ctinfo,
105 int pf,
106 unsigned int hooknum,
107 int (*csum)(const struct sk_buff *, unsigned int))
108{
109 unsigned int udplen = skb->len - dataoff;
110 struct udphdr _hdr, *hdr;
111
112 /* Header is too small? */
113 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
114 if (hdr == NULL) {
115 if (LOG_INVALID(IPPROTO_UDP))
116 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
117 "nf_ct_udp: short packet ");
118 return -NF_ACCEPT;
119 }
120
121 /* Truncated/malformed packets */
122 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
123 if (LOG_INVALID(IPPROTO_UDP))
124 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
125 "nf_ct_udp: truncated/malformed packet ");
126 return -NF_ACCEPT;
127 }
128
129 /* Packet with no checksum */
130 if (!hdr->check)
131 return NF_ACCEPT;
132
133 /* Checksum invalid? Ignore.
134 * We skip checking packets on the outgoing path
135 * because the semantic of CHECKSUM_HW is different there
136 * and moreover root might send raw packets.
137 * FIXME: Source route IP option packets --RR */
138 if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
139 (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))
140 && skb->ip_summed != CHECKSUM_UNNECESSARY
141 && csum(skb, dataoff)) {
142 if (LOG_INVALID(IPPROTO_UDP))
143 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
144 "nf_ct_udp: bad UDP checksum ");
145 return -NF_ACCEPT;
146 }
147
148 return NF_ACCEPT;
149}
150
151static int csum4(const struct sk_buff *skb, unsigned int dataoff)
152{
153 return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
154 skb->len - dataoff, IPPROTO_UDP,
155 skb->ip_summed == CHECKSUM_HW ? skb->csum
156 : skb_checksum(skb, dataoff,
157 skb->len - dataoff, 0));
158}
159
160static int csum6(const struct sk_buff *skb, unsigned int dataoff)
161{
162 return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
163 skb->len - dataoff, IPPROTO_UDP,
164 skb->ip_summed == CHECKSUM_HW ? skb->csum
165 : skb_checksum(skb, dataoff, skb->len - dataoff,
166 0));
167}
168
169static int udp_error4(struct sk_buff *skb,
170 unsigned int dataoff,
171 enum ip_conntrack_info *ctinfo,
172 int pf,
173 unsigned int hooknum)
174{
175 return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
176}
177
178static int udp_error6(struct sk_buff *skb,
179 unsigned int dataoff,
180 enum ip_conntrack_info *ctinfo,
181 int pf,
182 unsigned int hooknum)
183{
184 return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
185}
186
187struct nf_conntrack_protocol nf_conntrack_protocol_udp4 =
188{
189 .l3proto = PF_INET,
190 .proto = IPPROTO_UDP,
191 .name = "udp",
192 .pkt_to_tuple = udp_pkt_to_tuple,
193 .invert_tuple = udp_invert_tuple,
194 .print_tuple = udp_print_tuple,
195 .print_conntrack = udp_print_conntrack,
196 .packet = udp_packet,
197 .new = udp_new,
198 .error = udp_error4,
199};
200
201struct nf_conntrack_protocol nf_conntrack_protocol_udp6 =
202{
203 .l3proto = PF_INET6,
204 .proto = IPPROTO_UDP,
205 .name = "udp",
206 .pkt_to_tuple = udp_pkt_to_tuple,
207 .invert_tuple = udp_invert_tuple,
208 .print_tuple = udp_print_tuple,
209 .print_conntrack = udp_print_conntrack,
210 .packet = udp_packet,
211 .new = udp_new,
212 .error = udp_error6,
213};
214
215EXPORT_SYMBOL(nf_conntrack_protocol_udp4);
216EXPORT_SYMBOL(nf_conntrack_protocol_udp6);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
new file mode 100644
index 000000000000..45224db4fe2f
--- /dev/null
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -0,0 +1,869 @@
1/* This file contains all the functions required for the standalone
2 nf_conntrack module.
3
4 These are not required by the compatibility layer.
5*/
6
7/* (C) 1999-2001 Paul `Rusty' Russell
8 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
15 * - generalize L3 protocol dependent part.
16 *
17 * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
18 */
19
20#include <linux/config.h>
21#include <linux/types.h>
22#include <linux/netfilter.h>
23#include <linux/module.h>
24#include <linux/skbuff.h>
25#include <linux/proc_fs.h>
26#include <linux/seq_file.h>
27#include <linux/percpu.h>
28#include <linux/netdevice.h>
29#ifdef CONFIG_SYSCTL
30#include <linux/sysctl.h>
31#endif
32
33#define ASSERT_READ_LOCK(x)
34#define ASSERT_WRITE_LOCK(x)
35
36#include <net/netfilter/nf_conntrack.h>
37#include <net/netfilter/nf_conntrack_l3proto.h>
38#include <net/netfilter/nf_conntrack_protocol.h>
39#include <net/netfilter/nf_conntrack_core.h>
40#include <net/netfilter/nf_conntrack_helper.h>
41#include <linux/netfilter_ipv4/listhelp.h>
42
43#if 0
44#define DEBUGP printk
45#else
46#define DEBUGP(format, args...)
47#endif
48
49MODULE_LICENSE("GPL");
50
51extern atomic_t nf_conntrack_count;
52DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
53
54static int kill_l3proto(struct nf_conn *i, void *data)
55{
56 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
57 ((struct nf_conntrack_l3proto *)data)->l3proto);
58}
59
60static int kill_proto(struct nf_conn *i, void *data)
61{
62 struct nf_conntrack_protocol *proto;
63 proto = (struct nf_conntrack_protocol *)data;
64 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
65 proto->proto) &&
66 (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
67 proto->l3proto);
68}
69
70#ifdef CONFIG_PROC_FS
71static int
72print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
73 struct nf_conntrack_l3proto *l3proto,
74 struct nf_conntrack_protocol *proto)
75{
76 return l3proto->print_tuple(s, tuple) || proto->print_tuple(s, tuple);
77}
78
79#ifdef CONFIG_NF_CT_ACCT
80static unsigned int
81seq_print_counters(struct seq_file *s,
82 const struct ip_conntrack_counter *counter)
83{
84 return seq_printf(s, "packets=%llu bytes=%llu ",
85 (unsigned long long)counter->packets,
86 (unsigned long long)counter->bytes);
87}
88#else
89#define seq_print_counters(x, y) 0
90#endif
91
92struct ct_iter_state {
93 unsigned int bucket;
94};
95
96static struct list_head *ct_get_first(struct seq_file *seq)
97{
98 struct ct_iter_state *st = seq->private;
99
100 for (st->bucket = 0;
101 st->bucket < nf_conntrack_htable_size;
102 st->bucket++) {
103 if (!list_empty(&nf_conntrack_hash[st->bucket]))
104 return nf_conntrack_hash[st->bucket].next;
105 }
106 return NULL;
107}
108
109static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
110{
111 struct ct_iter_state *st = seq->private;
112
113 head = head->next;
114 while (head == &nf_conntrack_hash[st->bucket]) {
115 if (++st->bucket >= nf_conntrack_htable_size)
116 return NULL;
117 head = nf_conntrack_hash[st->bucket].next;
118 }
119 return head;
120}
121
122static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
123{
124 struct list_head *head = ct_get_first(seq);
125
126 if (head)
127 while (pos && (head = ct_get_next(seq, head)))
128 pos--;
129 return pos ? NULL : head;
130}
131
132static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
133{
134 read_lock_bh(&nf_conntrack_lock);
135 return ct_get_idx(seq, *pos);
136}
137
138static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
139{
140 (*pos)++;
141 return ct_get_next(s, v);
142}
143
144static void ct_seq_stop(struct seq_file *s, void *v)
145{
146 read_unlock_bh(&nf_conntrack_lock);
147}
148
149/* return 0 on success, 1 in case of error */
150static int ct_seq_show(struct seq_file *s, void *v)
151{
152 const struct nf_conntrack_tuple_hash *hash = v;
153 const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
154 struct nf_conntrack_l3proto *l3proto;
155 struct nf_conntrack_protocol *proto;
156
157 ASSERT_READ_LOCK(&nf_conntrack_lock);
158 NF_CT_ASSERT(conntrack);
159
160 /* we only want to print DIR_ORIGINAL */
161 if (NF_CT_DIRECTION(hash))
162 return 0;
163
164 l3proto = nf_ct_find_l3proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
165 .tuple.src.l3num);
166
167 NF_CT_ASSERT(l3proto);
168 proto = nf_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
169 .tuple.src.l3num,
170 conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
171 .tuple.dst.protonum);
172 NF_CT_ASSERT(proto);
173
174 if (seq_printf(s, "%-8s %u %-8s %u %ld ",
175 l3proto->name,
176 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
177 proto->name,
178 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
179 timer_pending(&conntrack->timeout)
180 ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
181 return -ENOSPC;
182
183 if (l3proto->print_conntrack(s, conntrack))
184 return -ENOSPC;
185
186 if (proto->print_conntrack(s, conntrack))
187 return -ENOSPC;
188
189 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
190 l3proto, proto))
191 return -ENOSPC;
192
193 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
194 return -ENOSPC;
195
196 if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
197 if (seq_printf(s, "[UNREPLIED] "))
198 return -ENOSPC;
199
200 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
201 l3proto, proto))
202 return -ENOSPC;
203
204 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
205 return -ENOSPC;
206
207 if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
208 if (seq_printf(s, "[ASSURED] "))
209 return -ENOSPC;
210
211#if defined(CONFIG_NF_CONNTRACK_MARK)
212 if (seq_printf(s, "mark=%u ", conntrack->mark))
213 return -ENOSPC;
214#endif
215
216 if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
217 return -ENOSPC;
218
219 return 0;
220}
221
222static struct seq_operations ct_seq_ops = {
223 .start = ct_seq_start,
224 .next = ct_seq_next,
225 .stop = ct_seq_stop,
226 .show = ct_seq_show
227};
228
229static int ct_open(struct inode *inode, struct file *file)
230{
231 struct seq_file *seq;
232 struct ct_iter_state *st;
233 int ret;
234
235 st = kmalloc(sizeof(struct ct_iter_state), GFP_KERNEL);
236 if (st == NULL)
237 return -ENOMEM;
238 ret = seq_open(file, &ct_seq_ops);
239 if (ret)
240 goto out_free;
241 seq = file->private_data;
242 seq->private = st;
243 memset(st, 0, sizeof(struct ct_iter_state));
244 return ret;
245out_free:
246 kfree(st);
247 return ret;
248}
249
250static struct file_operations ct_file_ops = {
251 .owner = THIS_MODULE,
252 .open = ct_open,
253 .read = seq_read,
254 .llseek = seq_lseek,
255 .release = seq_release_private,
256};
257
258/* expects */
259static void *exp_seq_start(struct seq_file *s, loff_t *pos)
260{
261 struct list_head *e = &nf_conntrack_expect_list;
262 loff_t i;
263
264 /* strange seq_file api calls stop even if we fail,
265 * thus we need to grab lock since stop unlocks */
266 read_lock_bh(&nf_conntrack_lock);
267
268 if (list_empty(e))
269 return NULL;
270
271 for (i = 0; i <= *pos; i++) {
272 e = e->next;
273 if (e == &nf_conntrack_expect_list)
274 return NULL;
275 }
276 return e;
277}
278
279static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
280{
281 struct list_head *e = v;
282
283 ++*pos;
284 e = e->next;
285
286 if (e == &nf_conntrack_expect_list)
287 return NULL;
288
289 return e;
290}
291
292static void exp_seq_stop(struct seq_file *s, void *v)
293{
294 read_unlock_bh(&nf_conntrack_lock);
295}
296
297static int exp_seq_show(struct seq_file *s, void *v)
298{
299 struct nf_conntrack_expect *expect = v;
300
301 if (expect->timeout.function)
302 seq_printf(s, "%ld ", timer_pending(&expect->timeout)
303 ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
304 else
305 seq_printf(s, "- ");
306 seq_printf(s, "l3proto = %u proto=%u ",
307 expect->tuple.src.l3num,
308 expect->tuple.dst.protonum);
309 print_tuple(s, &expect->tuple,
310 nf_ct_find_l3proto(expect->tuple.src.l3num),
311 nf_ct_find_proto(expect->tuple.src.l3num,
312 expect->tuple.dst.protonum));
313 return seq_putc(s, '\n');
314}
315
316static struct seq_operations exp_seq_ops = {
317 .start = exp_seq_start,
318 .next = exp_seq_next,
319 .stop = exp_seq_stop,
320 .show = exp_seq_show
321};
322
323static int exp_open(struct inode *inode, struct file *file)
324{
325 return seq_open(file, &exp_seq_ops);
326}
327
328static struct file_operations exp_file_ops = {
329 .owner = THIS_MODULE,
330 .open = exp_open,
331 .read = seq_read,
332 .llseek = seq_lseek,
333 .release = seq_release
334};
335
336static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
337{
338 int cpu;
339
340 if (*pos == 0)
341 return SEQ_START_TOKEN;
342
343 for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {
344 if (!cpu_possible(cpu))
345 continue;
346 *pos = cpu + 1;
347 return &per_cpu(nf_conntrack_stat, cpu);
348 }
349
350 return NULL;
351}
352
353static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
354{
355 int cpu;
356
357 for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
358 if (!cpu_possible(cpu))
359 continue;
360 *pos = cpu + 1;
361 return &per_cpu(nf_conntrack_stat, cpu);
362 }
363
364 return NULL;
365}
366
367static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
368{
369}
370
371static int ct_cpu_seq_show(struct seq_file *seq, void *v)
372{
373 unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
374 struct ip_conntrack_stat *st = v;
375
376 if (v == SEQ_START_TOKEN) {
377 seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
378 return 0;
379 }
380
381 seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x "
382 "%08x %08x %08x %08x %08x %08x %08x %08x \n",
383 nr_conntracks,
384 st->searched,
385 st->found,
386 st->new,
387 st->invalid,
388 st->ignore,
389 st->delete,
390 st->delete_list,
391 st->insert,
392 st->insert_failed,
393 st->drop,
394 st->early_drop,
395 st->error,
396
397 st->expect_new,
398 st->expect_create,
399 st->expect_delete
400 );
401 return 0;
402}
403
404static struct seq_operations ct_cpu_seq_ops = {
405 .start = ct_cpu_seq_start,
406 .next = ct_cpu_seq_next,
407 .stop = ct_cpu_seq_stop,
408 .show = ct_cpu_seq_show,
409};
410
411static int ct_cpu_seq_open(struct inode *inode, struct file *file)
412{
413 return seq_open(file, &ct_cpu_seq_ops);
414}
415
416static struct file_operations ct_cpu_seq_fops = {
417 .owner = THIS_MODULE,
418 .open = ct_cpu_seq_open,
419 .read = seq_read,
420 .llseek = seq_lseek,
421 .release = seq_release_private,
422};
423#endif /* CONFIG_PROC_FS */
424
425/* Sysctl support */
426
427#ifdef CONFIG_SYSCTL
428
429/* From nf_conntrack_core.c */
430extern int nf_conntrack_max;
431extern unsigned int nf_conntrack_htable_size;
432
433/* From nf_conntrack_proto_tcp.c */
434extern unsigned long nf_ct_tcp_timeout_syn_sent;
435extern unsigned long nf_ct_tcp_timeout_syn_recv;
436extern unsigned long nf_ct_tcp_timeout_established;
437extern unsigned long nf_ct_tcp_timeout_fin_wait;
438extern unsigned long nf_ct_tcp_timeout_close_wait;
439extern unsigned long nf_ct_tcp_timeout_last_ack;
440extern unsigned long nf_ct_tcp_timeout_time_wait;
441extern unsigned long nf_ct_tcp_timeout_close;
442extern unsigned long nf_ct_tcp_timeout_max_retrans;
443extern int nf_ct_tcp_loose;
444extern int nf_ct_tcp_be_liberal;
445extern int nf_ct_tcp_max_retrans;
446
447/* From nf_conntrack_proto_udp.c */
448extern unsigned long nf_ct_udp_timeout;
449extern unsigned long nf_ct_udp_timeout_stream;
450
451/* From nf_conntrack_proto_generic.c */
452extern unsigned long nf_ct_generic_timeout;
453
454/* Log invalid packets of a given protocol */
455static int log_invalid_proto_min = 0;
456static int log_invalid_proto_max = 255;
457
458static struct ctl_table_header *nf_ct_sysctl_header;
459
460static ctl_table nf_ct_sysctl_table[] = {
461 {
462 .ctl_name = NET_NF_CONNTRACK_MAX,
463 .procname = "nf_conntrack_max",
464 .data = &nf_conntrack_max,
465 .maxlen = sizeof(int),
466 .mode = 0644,
467 .proc_handler = &proc_dointvec,
468 },
469 {
470 .ctl_name = NET_NF_CONNTRACK_COUNT,
471 .procname = "nf_conntrack_count",
472 .data = &nf_conntrack_count,
473 .maxlen = sizeof(int),
474 .mode = 0444,
475 .proc_handler = &proc_dointvec,
476 },
477 {
478 .ctl_name = NET_NF_CONNTRACK_BUCKETS,
479 .procname = "nf_conntrack_buckets",
480 .data = &nf_conntrack_htable_size,
481 .maxlen = sizeof(unsigned int),
482 .mode = 0444,
483 .proc_handler = &proc_dointvec,
484 },
485 {
486 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
487 .procname = "nf_conntrack_tcp_timeout_syn_sent",
488 .data = &nf_ct_tcp_timeout_syn_sent,
489 .maxlen = sizeof(unsigned int),
490 .mode = 0644,
491 .proc_handler = &proc_dointvec_jiffies,
492 },
493 {
494 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
495 .procname = "nf_conntrack_tcp_timeout_syn_recv",
496 .data = &nf_ct_tcp_timeout_syn_recv,
497 .maxlen = sizeof(unsigned int),
498 .mode = 0644,
499 .proc_handler = &proc_dointvec_jiffies,
500 },
501 {
502 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
503 .procname = "nf_conntrack_tcp_timeout_established",
504 .data = &nf_ct_tcp_timeout_established,
505 .maxlen = sizeof(unsigned int),
506 .mode = 0644,
507 .proc_handler = &proc_dointvec_jiffies,
508 },
509 {
510 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
511 .procname = "nf_conntrack_tcp_timeout_fin_wait",
512 .data = &nf_ct_tcp_timeout_fin_wait,
513 .maxlen = sizeof(unsigned int),
514 .mode = 0644,
515 .proc_handler = &proc_dointvec_jiffies,
516 },
517 {
518 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
519 .procname = "nf_conntrack_tcp_timeout_close_wait",
520 .data = &nf_ct_tcp_timeout_close_wait,
521 .maxlen = sizeof(unsigned int),
522 .mode = 0644,
523 .proc_handler = &proc_dointvec_jiffies,
524 },
525 {
526 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
527 .procname = "nf_conntrack_tcp_timeout_last_ack",
528 .data = &nf_ct_tcp_timeout_last_ack,
529 .maxlen = sizeof(unsigned int),
530 .mode = 0644,
531 .proc_handler = &proc_dointvec_jiffies,
532 },
533 {
534 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
535 .procname = "nf_conntrack_tcp_timeout_time_wait",
536 .data = &nf_ct_tcp_timeout_time_wait,
537 .maxlen = sizeof(unsigned int),
538 .mode = 0644,
539 .proc_handler = &proc_dointvec_jiffies,
540 },
541 {
542 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
543 .procname = "nf_conntrack_tcp_timeout_close",
544 .data = &nf_ct_tcp_timeout_close,
545 .maxlen = sizeof(unsigned int),
546 .mode = 0644,
547 .proc_handler = &proc_dointvec_jiffies,
548 },
549 {
550 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT,
551 .procname = "nf_conntrack_udp_timeout",
552 .data = &nf_ct_udp_timeout,
553 .maxlen = sizeof(unsigned int),
554 .mode = 0644,
555 .proc_handler = &proc_dointvec_jiffies,
556 },
557 {
558 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
559 .procname = "nf_conntrack_udp_timeout_stream",
560 .data = &nf_ct_udp_timeout_stream,
561 .maxlen = sizeof(unsigned int),
562 .mode = 0644,
563 .proc_handler = &proc_dointvec_jiffies,
564 },
565 {
566 .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
567 .procname = "nf_conntrack_generic_timeout",
568 .data = &nf_ct_generic_timeout,
569 .maxlen = sizeof(unsigned int),
570 .mode = 0644,
571 .proc_handler = &proc_dointvec_jiffies,
572 },
573 {
574 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID,
575 .procname = "nf_conntrack_log_invalid",
576 .data = &nf_ct_log_invalid,
577 .maxlen = sizeof(unsigned int),
578 .mode = 0644,
579 .proc_handler = &proc_dointvec_minmax,
580 .strategy = &sysctl_intvec,
581 .extra1 = &log_invalid_proto_min,
582 .extra2 = &log_invalid_proto_max,
583 },
584 {
585 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
586 .procname = "nf_conntrack_tcp_timeout_max_retrans",
587 .data = &nf_ct_tcp_timeout_max_retrans,
588 .maxlen = sizeof(unsigned int),
589 .mode = 0644,
590 .proc_handler = &proc_dointvec_jiffies,
591 },
592 {
593 .ctl_name = NET_NF_CONNTRACK_TCP_LOOSE,
594 .procname = "nf_conntrack_tcp_loose",
595 .data = &nf_ct_tcp_loose,
596 .maxlen = sizeof(unsigned int),
597 .mode = 0644,
598 .proc_handler = &proc_dointvec,
599 },
600 {
601 .ctl_name = NET_NF_CONNTRACK_TCP_BE_LIBERAL,
602 .procname = "nf_conntrack_tcp_be_liberal",
603 .data = &nf_ct_tcp_be_liberal,
604 .maxlen = sizeof(unsigned int),
605 .mode = 0644,
606 .proc_handler = &proc_dointvec,
607 },
608 {
609 .ctl_name = NET_NF_CONNTRACK_TCP_MAX_RETRANS,
610 .procname = "nf_conntrack_tcp_max_retrans",
611 .data = &nf_ct_tcp_max_retrans,
612 .maxlen = sizeof(unsigned int),
613 .mode = 0644,
614 .proc_handler = &proc_dointvec,
615 },
616
617 { .ctl_name = 0 }
618};
619
620#define NET_NF_CONNTRACK_MAX 2089
621
622static ctl_table nf_ct_netfilter_table[] = {
623 {
624 .ctl_name = NET_NETFILTER,
625 .procname = "netfilter",
626 .mode = 0555,
627 .child = nf_ct_sysctl_table,
628 },
629 {
630 .ctl_name = NET_NF_CONNTRACK_MAX,
631 .procname = "nf_conntrack_max",
632 .data = &nf_conntrack_max,
633 .maxlen = sizeof(int),
634 .mode = 0644,
635 .proc_handler = &proc_dointvec,
636 },
637 { .ctl_name = 0 }
638};
639
640static ctl_table nf_ct_net_table[] = {
641 {
642 .ctl_name = CTL_NET,
643 .procname = "net",
644 .mode = 0555,
645 .child = nf_ct_netfilter_table,
646 },
647 { .ctl_name = 0 }
648};
649EXPORT_SYMBOL(nf_ct_log_invalid);
650#endif /* CONFIG_SYSCTL */
651
652static int init_or_cleanup(int init)
653{
654#ifdef CONFIG_PROC_FS
655 struct proc_dir_entry *proc, *proc_exp, *proc_stat;
656#endif
657 int ret = 0;
658
659 if (!init) goto cleanup;
660
661 ret = nf_conntrack_init();
662 if (ret < 0)
663 goto cleanup_nothing;
664
665#ifdef CONFIG_PROC_FS
666 proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
667 if (!proc) goto cleanup_init;
668
669 proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
670 &exp_file_ops);
671 if (!proc_exp) goto cleanup_proc;
672
673 proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
674 if (!proc_stat)
675 goto cleanup_proc_exp;
676
677 proc_stat->proc_fops = &ct_cpu_seq_fops;
678 proc_stat->owner = THIS_MODULE;
679#endif
680#ifdef CONFIG_SYSCTL
681 nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
682 if (nf_ct_sysctl_header == NULL) {
683 printk("nf_conntrack: can't register to sysctl.\n");
684 ret = -ENOMEM;
685 goto cleanup_proc_stat;
686 }
687#endif
688
689 return ret;
690
691 cleanup:
692#ifdef CONFIG_SYSCTL
693 unregister_sysctl_table(nf_ct_sysctl_header);
694 cleanup_proc_stat:
695#endif
696#ifdef CONFIG_PROC_FS
697 proc_net_remove("nf_conntrack_stat");
698 cleanup_proc_exp:
699 proc_net_remove("nf_conntrack_expect");
700 cleanup_proc:
701 proc_net_remove("nf_conntrack");
702 cleanup_init:
703#endif /* CNFIG_PROC_FS */
704 nf_conntrack_cleanup();
705 cleanup_nothing:
706 return ret;
707}
708
709int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
710{
711 int ret = 0;
712
713 write_lock_bh(&nf_conntrack_lock);
714 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_generic_l3proto) {
715 ret = -EBUSY;
716 goto out;
717 }
718 nf_ct_l3protos[proto->l3proto] = proto;
719out:
720 write_unlock_bh(&nf_conntrack_lock);
721
722 return ret;
723}
724
725void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
726{
727 write_lock_bh(&nf_conntrack_lock);
728 nf_ct_l3protos[proto->l3proto] = &nf_conntrack_generic_l3proto;
729 write_unlock_bh(&nf_conntrack_lock);
730
731 /* Somebody could be still looking at the proto in bh. */
732 synchronize_net();
733
734 /* Remove all contrack entries for this protocol */
735 nf_ct_iterate_cleanup(kill_l3proto, proto);
736}
737
738/* FIXME: Allow NULL functions and sub in pointers to generic for
739 them. --RR */
740int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto)
741{
742 int ret = 0;
743
744retry:
745 write_lock_bh(&nf_conntrack_lock);
746 if (nf_ct_protos[proto->l3proto]) {
747 if (nf_ct_protos[proto->l3proto][proto->proto]
748 != &nf_conntrack_generic_protocol) {
749 ret = -EBUSY;
750 goto out_unlock;
751 }
752 } else {
753 /* l3proto may be loaded latter. */
754 struct nf_conntrack_protocol **proto_array;
755 int i;
756
757 write_unlock_bh(&nf_conntrack_lock);
758
759 proto_array = (struct nf_conntrack_protocol **)
760 kmalloc(MAX_NF_CT_PROTO *
761 sizeof(struct nf_conntrack_protocol *),
762 GFP_KERNEL);
763 if (proto_array == NULL) {
764 ret = -ENOMEM;
765 goto out;
766 }
767 for (i = 0; i < MAX_NF_CT_PROTO; i++)
768 proto_array[i] = &nf_conntrack_generic_protocol;
769
770 write_lock_bh(&nf_conntrack_lock);
771 if (nf_ct_protos[proto->l3proto]) {
772 /* bad timing, but no problem */
773 write_unlock_bh(&nf_conntrack_lock);
774 kfree(proto_array);
775 } else {
776 nf_ct_protos[proto->l3proto] = proto_array;
777 write_unlock_bh(&nf_conntrack_lock);
778 }
779
780 /*
781 * Just once because array is never freed until unloading
782 * nf_conntrack.ko
783 */
784 goto retry;
785 }
786
787 nf_ct_protos[proto->l3proto][proto->proto] = proto;
788
789out_unlock:
790 write_unlock_bh(&nf_conntrack_lock);
791out:
792 return ret;
793}
794
795void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto)
796{
797 write_lock_bh(&nf_conntrack_lock);
798 nf_ct_protos[proto->l3proto][proto->proto]
799 = &nf_conntrack_generic_protocol;
800 write_unlock_bh(&nf_conntrack_lock);
801
802 /* Somebody could be still looking at the proto in bh. */
803 synchronize_net();
804
805 /* Remove all contrack entries for this protocol */
806 nf_ct_iterate_cleanup(kill_proto, proto);
807}
808
809static int __init init(void)
810{
811 return init_or_cleanup(1);
812}
813
814static void __exit fini(void)
815{
816 init_or_cleanup(0);
817}
818
819module_init(init);
820module_exit(fini);
821
822/* Some modules need us, but don't depend directly on any symbol.
823 They should call this. */
824void need_nf_conntrack(void)
825{
826}
827
828#ifdef CONFIG_NF_CONNTRACK_EVENTS
829EXPORT_SYMBOL_GPL(nf_conntrack_chain);
830EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
831EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
832EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
833EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
834EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
835EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
836#endif
837EXPORT_SYMBOL(nf_conntrack_l3proto_register);
838EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
839EXPORT_SYMBOL(nf_conntrack_protocol_register);
840EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
841EXPORT_SYMBOL(nf_ct_invert_tuplepr);
842EXPORT_SYMBOL(nf_conntrack_alter_reply);
843EXPORT_SYMBOL(nf_conntrack_destroyed);
844EXPORT_SYMBOL(need_nf_conntrack);
845EXPORT_SYMBOL(nf_conntrack_helper_register);
846EXPORT_SYMBOL(nf_conntrack_helper_unregister);
847EXPORT_SYMBOL(nf_ct_iterate_cleanup);
848EXPORT_SYMBOL(__nf_ct_refresh_acct);
849EXPORT_SYMBOL(nf_ct_protos);
850EXPORT_SYMBOL(nf_ct_find_proto);
851EXPORT_SYMBOL(nf_ct_l3protos);
852EXPORT_SYMBOL(nf_conntrack_expect_alloc);
853EXPORT_SYMBOL(nf_conntrack_expect_put);
854EXPORT_SYMBOL(nf_conntrack_expect_related);
855EXPORT_SYMBOL(nf_conntrack_unexpect_related);
856EXPORT_SYMBOL(nf_conntrack_tuple_taken);
857EXPORT_SYMBOL(nf_conntrack_htable_size);
858EXPORT_SYMBOL(nf_conntrack_lock);
859EXPORT_SYMBOL(nf_conntrack_hash);
860EXPORT_SYMBOL(nf_conntrack_untracked);
861EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
862#ifdef CONFIG_IP_NF_NAT_NEEDED
863EXPORT_SYMBOL(nf_conntrack_tcp_update);
864#endif
865EXPORT_SYMBOL(__nf_conntrack_confirm);
866EXPORT_SYMBOL(nf_ct_get_tuple);
867EXPORT_SYMBOL(nf_ct_invert_tuple);
868EXPORT_SYMBOL(nf_conntrack_in);
869EXPORT_SYMBOL(__nf_conntrack_attach);
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 4bc27a6334c1..83f4c53030fc 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -128,7 +128,7 @@ void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen,
128 memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size); 128 memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
129} 129}
130 130
131int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len) 131void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
132{ 132{
133 memset(tb, 0, sizeof(struct nfattr *) * maxattr); 133 memset(tb, 0, sizeof(struct nfattr *) * maxattr);
134 134
@@ -138,8 +138,6 @@ int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
138 tb[flavor-1] = nfa; 138 tb[flavor-1] = nfa;
139 nfa = NFA_NEXT(nfa, len); 139 nfa = NFA_NEXT(nfa, len);
140 } 140 }
141
142 return 0;
143} 141}
144 142
145/** 143/**
@@ -242,15 +240,18 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
242 ss = nfnetlink_get_subsys(type); 240 ss = nfnetlink_get_subsys(type);
243 if (!ss) { 241 if (!ss) {
244#ifdef CONFIG_KMOD 242#ifdef CONFIG_KMOD
245 /* don't call nfnl_shunlock, since it would reenter 243 if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
246 * with further packet processing */ 244 /* don't call nfnl_shunlock, since it would reenter
247 up(&nfnl_sem); 245 * with further packet processing */
248 request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type)); 246 up(&nfnl_sem);
249 nfnl_shlock(); 247 request_module("nfnetlink-subsys-%d",
250 ss = nfnetlink_get_subsys(type); 248 NFNL_SUBSYS_ID(type));
249 nfnl_shlock();
250 ss = nfnetlink_get_subsys(type);
251 }
251 if (!ss) 252 if (!ss)
252#endif 253#endif
253 goto err_inval; 254 goto err_inval;
254 } 255 }
255 256
256 nc = nfnetlink_find_client(type, ss); 257 nc = nfnetlink_find_client(type, ss);
diff --git a/net/netlink/Makefile b/net/netlink/Makefile
index 39d9c2dcd03c..e3589c2de49e 100644
--- a/net/netlink/Makefile
+++ b/net/netlink/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the netlink driver. 2# Makefile for the netlink driver.
3# 3#
4 4
5obj-y := af_netlink.o 5obj-y := af_netlink.o attr.o genetlink.o
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 5ca283537bc6..8c38ee6d255e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -58,6 +58,7 @@
58 58
59#include <net/sock.h> 59#include <net/sock.h>
60#include <net/scm.h> 60#include <net/scm.h>
61#include <net/netlink.h>
61 62
62#define Nprintk(a...) 63#define Nprintk(a...)
63#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) 64#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8)
@@ -427,7 +428,8 @@ static int netlink_release(struct socket *sock)
427 428
428 spin_lock(&nlk->cb_lock); 429 spin_lock(&nlk->cb_lock);
429 if (nlk->cb) { 430 if (nlk->cb) {
430 nlk->cb->done(nlk->cb); 431 if (nlk->cb->done)
432 nlk->cb->done(nlk->cb);
431 netlink_destroy_callback(nlk->cb); 433 netlink_destroy_callback(nlk->cb);
432 nlk->cb = NULL; 434 nlk->cb = NULL;
433 } 435 }
@@ -1322,7 +1324,8 @@ static int netlink_dump(struct sock *sk)
1322 skb_queue_tail(&sk->sk_receive_queue, skb); 1324 skb_queue_tail(&sk->sk_receive_queue, skb);
1323 sk->sk_data_ready(sk, skb->len); 1325 sk->sk_data_ready(sk, skb->len);
1324 1326
1325 cb->done(cb); 1327 if (cb->done)
1328 cb->done(cb);
1326 nlk->cb = NULL; 1329 nlk->cb = NULL;
1327 spin_unlock(&nlk->cb_lock); 1330 spin_unlock(&nlk->cb_lock);
1328 1331
@@ -1409,6 +1412,94 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1409 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); 1412 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
1410} 1413}
1411 1414
1415static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
1416 struct nlmsghdr *, int *))
1417{
1418 unsigned int total_len;
1419 struct nlmsghdr *nlh;
1420 int err;
1421
1422 while (skb->len >= nlmsg_total_size(0)) {
1423 nlh = (struct nlmsghdr *) skb->data;
1424
1425 if (skb->len < nlh->nlmsg_len)
1426 return 0;
1427
1428 total_len = min(NLMSG_ALIGN(nlh->nlmsg_len), skb->len);
1429
1430 if (cb(skb, nlh, &err) < 0) {
1431 /* Not an error, but we have to interrupt processing
1432 * here. Note: that in this case we do not pull
1433 * message from skb, it will be processed later.
1434 */
1435 if (err == 0)
1436 return -1;
1437 netlink_ack(skb, nlh, err);
1438 } else if (nlh->nlmsg_flags & NLM_F_ACK)
1439 netlink_ack(skb, nlh, 0);
1440
1441 skb_pull(skb, total_len);
1442 }
1443
1444 return 0;
1445}
1446
1447/**
1448 * nelink_run_queue - Process netlink receive queue.
1449 * @sk: Netlink socket containing the queue
1450 * @qlen: Place to store queue length upon entry
1451 * @cb: Callback function invoked for each netlink message found
1452 *
1453 * Processes as much as there was in the queue upon entry and invokes
1454 * a callback function for each netlink message found. The callback
1455 * function may refuse a message by returning a negative error code
1456 * but setting the error pointer to 0 in which case this function
1457 * returns with a qlen != 0.
1458 *
1459 * qlen must be initialized to 0 before the initial entry, afterwards
1460 * the function may be called repeatedly until qlen reaches 0.
1461 */
1462void netlink_run_queue(struct sock *sk, unsigned int *qlen,
1463 int (*cb)(struct sk_buff *, struct nlmsghdr *, int *))
1464{
1465 struct sk_buff *skb;
1466
1467 if (!*qlen || *qlen > skb_queue_len(&sk->sk_receive_queue))
1468 *qlen = skb_queue_len(&sk->sk_receive_queue);
1469
1470 for (; *qlen; (*qlen)--) {
1471 skb = skb_dequeue(&sk->sk_receive_queue);
1472 if (netlink_rcv_skb(skb, cb)) {
1473 if (skb->len)
1474 skb_queue_head(&sk->sk_receive_queue, skb);
1475 else {
1476 kfree_skb(skb);
1477 (*qlen)--;
1478 }
1479 break;
1480 }
1481
1482 kfree_skb(skb);
1483 }
1484}
1485
1486/**
1487 * netlink_queue_skip - Skip netlink message while processing queue.
1488 * @nlh: Netlink message to be skipped
1489 * @skb: Socket buffer containing the netlink messages.
1490 *
1491 * Pulls the given netlink message off the socket buffer so the next
1492 * call to netlink_queue_run() will not reconsider the message.
1493 */
1494void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
1495{
1496 int msglen = NLMSG_ALIGN(nlh->nlmsg_len);
1497
1498 if (msglen > skb->len)
1499 msglen = skb->len;
1500
1501 skb_pull(skb, msglen);
1502}
1412 1503
1413#ifdef CONFIG_PROC_FS 1504#ifdef CONFIG_PROC_FS
1414struct nl_seq_iter { 1505struct nl_seq_iter {
@@ -1657,6 +1748,8 @@ out:
1657core_initcall(netlink_proto_init); 1748core_initcall(netlink_proto_init);
1658 1749
1659EXPORT_SYMBOL(netlink_ack); 1750EXPORT_SYMBOL(netlink_ack);
1751EXPORT_SYMBOL(netlink_run_queue);
1752EXPORT_SYMBOL(netlink_queue_skip);
1660EXPORT_SYMBOL(netlink_broadcast); 1753EXPORT_SYMBOL(netlink_broadcast);
1661EXPORT_SYMBOL(netlink_dump_start); 1754EXPORT_SYMBOL(netlink_dump_start);
1662EXPORT_SYMBOL(netlink_kernel_create); 1755EXPORT_SYMBOL(netlink_kernel_create);
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
new file mode 100644
index 000000000000..fffef4ab276f
--- /dev/null
+++ b/net/netlink/attr.c
@@ -0,0 +1,328 @@
1/*
2 * NETLINK Netlink attributes
3 *
4 * Authors: Thomas Graf <tgraf@suug.ch>
5 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
6 */
7
8#include <linux/config.h>
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/errno.h>
12#include <linux/jiffies.h>
13#include <linux/netdevice.h>
14#include <linux/skbuff.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <net/netlink.h>
18
19static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
20 [NLA_U8] = sizeof(u8),
21 [NLA_U16] = sizeof(u16),
22 [NLA_U32] = sizeof(u32),
23 [NLA_U64] = sizeof(u64),
24 [NLA_STRING] = 1,
25 [NLA_NESTED] = NLA_HDRLEN,
26};
27
28static int validate_nla(struct nlattr *nla, int maxtype,
29 struct nla_policy *policy)
30{
31 struct nla_policy *pt;
32 int minlen = 0;
33
34 if (nla->nla_type <= 0 || nla->nla_type > maxtype)
35 return 0;
36
37 pt = &policy[nla->nla_type];
38
39 BUG_ON(pt->type > NLA_TYPE_MAX);
40
41 if (pt->minlen)
42 minlen = pt->minlen;
43 else if (pt->type != NLA_UNSPEC)
44 minlen = nla_attr_minlen[pt->type];
45
46 if (pt->type == NLA_FLAG && nla_len(nla) > 0)
47 return -ERANGE;
48
49 if (nla_len(nla) < minlen)
50 return -ERANGE;
51
52 return 0;
53}
54
55/**
56 * nla_validate - Validate a stream of attributes
57 * @head: head of attribute stream
58 * @len: length of attribute stream
59 * @maxtype: maximum attribute type to be expected
60 * @policy: validation policy
61 *
62 * Validates all attributes in the specified attribute stream against the
63 * specified policy. Attributes with a type exceeding maxtype will be
64 * ignored. See documenation of struct nla_policy for more details.
65 *
66 * Returns 0 on success or a negative error code.
67 */
68int nla_validate(struct nlattr *head, int len, int maxtype,
69 struct nla_policy *policy)
70{
71 struct nlattr *nla;
72 int rem, err;
73
74 nla_for_each_attr(nla, head, len, rem) {
75 err = validate_nla(nla, maxtype, policy);
76 if (err < 0)
77 goto errout;
78 }
79
80 err = 0;
81errout:
82 return err;
83}
84
85/**
86 * nla_parse - Parse a stream of attributes into a tb buffer
87 * @tb: destination array with maxtype+1 elements
88 * @maxtype: maximum attribute type to be expected
89 * @head: head of attribute stream
90 * @len: length of attribute stream
91 *
92 * Parses a stream of attributes and stores a pointer to each attribute in
93 * the tb array accessable via the attribute type. Attributes with a type
94 * exceeding maxtype will be silently ignored for backwards compatibility
95 * reasons. policy may be set to NULL if no validation is required.
96 *
97 * Returns 0 on success or a negative error code.
98 */
99int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
100 struct nla_policy *policy)
101{
102 struct nlattr *nla;
103 int rem, err;
104
105 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
106
107 nla_for_each_attr(nla, head, len, rem) {
108 u16 type = nla->nla_type;
109
110 if (type > 0 && type <= maxtype) {
111 if (policy) {
112 err = validate_nla(nla, maxtype, policy);
113 if (err < 0)
114 goto errout;
115 }
116
117 tb[type] = nla;
118 }
119 }
120
121 if (unlikely(rem > 0))
122 printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
123 "attributes.\n", rem);
124
125 err = 0;
126errout:
127 return err;
128}
129
130/**
131 * nla_find - Find a specific attribute in a stream of attributes
132 * @head: head of attribute stream
133 * @len: length of attribute stream
134 * @attrtype: type of attribute to look for
135 *
136 * Returns the first attribute in the stream matching the specified type.
137 */
138struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
139{
140 struct nlattr *nla;
141 int rem;
142
143 nla_for_each_attr(nla, head, len, rem)
144 if (nla->nla_type == attrtype)
145 return nla;
146
147 return NULL;
148}
149
150/**
151 * nla_strlcpy - Copy string attribute payload into a sized buffer
152 * @dst: where to copy the string to
153 * @src: attribute to copy the string from
154 * @dstsize: size of destination buffer
155 *
156 * Copies at most dstsize - 1 bytes into the destination buffer.
157 * The result is always a valid NUL-terminated string. Unlike
158 * strlcpy the destination buffer is always padded out.
159 *
160 * Returns the length of the source buffer.
161 */
162size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
163{
164 size_t srclen = nla_len(nla);
165 char *src = nla_data(nla);
166
167 if (srclen > 0 && src[srclen - 1] == '\0')
168 srclen--;
169
170 if (dstsize > 0) {
171 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
172
173 memset(dst, 0, dstsize);
174 memcpy(dst, src, len);
175 }
176
177 return srclen;
178}
179
180/**
181 * nla_memcpy - Copy a netlink attribute into another memory area
182 * @dest: where to copy to memcpy
183 * @src: netlink attribute to copy from
184 * @count: size of the destination area
185 *
186 * Note: The number of bytes copied is limited by the length of
187 * attribute's payload. memcpy
188 *
189 * Returns the number of bytes copied.
190 */
191int nla_memcpy(void *dest, struct nlattr *src, int count)
192{
193 int minlen = min_t(int, count, nla_len(src));
194
195 memcpy(dest, nla_data(src), minlen);
196
197 return minlen;
198}
199
200/**
201 * nla_memcmp - Compare an attribute with sized memory area
202 * @nla: netlink attribute
203 * @data: memory area
204 * @size: size of memory area
205 */
206int nla_memcmp(const struct nlattr *nla, const void *data,
207 size_t size)
208{
209 int d = nla_len(nla) - size;
210
211 if (d == 0)
212 d = memcmp(nla_data(nla), data, size);
213
214 return d;
215}
216
217/**
218 * nla_strcmp - Compare a string attribute against a string
219 * @nla: netlink string attribute
220 * @str: another string
221 */
222int nla_strcmp(const struct nlattr *nla, const char *str)
223{
224 int len = strlen(str) + 1;
225 int d = nla_len(nla) - len;
226
227 if (d == 0)
228 d = memcmp(nla_data(nla), str, len);
229
230 return d;
231}
232
233/**
234 * __nla_reserve - reserve room for attribute on the skb
235 * @skb: socket buffer to reserve room on
236 * @attrtype: attribute type
237 * @attrlen: length of attribute payload
238 *
239 * Adds a netlink attribute header to a socket buffer and reserves
240 * room for the payload but does not copy it.
241 *
242 * The caller is responsible to ensure that the skb provides enough
243 * tailroom for the attribute header and payload.
244 */
245struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
246{
247 struct nlattr *nla;
248
249 nla = (struct nlattr *) skb_put(skb, nla_total_size(attrlen));
250 nla->nla_type = attrtype;
251 nla->nla_len = nla_attr_size(attrlen);
252
253 memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
254
255 return nla;
256}
257
258/**
259 * nla_reserve - reserve room for attribute on the skb
260 * @skb: socket buffer to reserve room on
261 * @attrtype: attribute type
262 * @attrlen: length of attribute payload
263 *
264 * Adds a netlink attribute header to a socket buffer and reserves
265 * room for the payload but does not copy it.
266 *
267 * Returns NULL if the tailroom of the skb is insufficient to store
268 * the attribute header and payload.
269 */
270struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
271{
272 if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
273 return NULL;
274
275 return __nla_reserve(skb, attrtype, attrlen);
276}
277
278/**
279 * __nla_put - Add a netlink attribute to a socket buffer
280 * @skb: socket buffer to add attribute to
281 * @attrtype: attribute type
282 * @attrlen: length of attribute payload
283 * @data: head of attribute payload
284 *
285 * The caller is responsible to ensure that the skb provides enough
286 * tailroom for the attribute header and payload.
287 */
288void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
289 const void *data)
290{
291 struct nlattr *nla;
292
293 nla = __nla_reserve(skb, attrtype, attrlen);
294 memcpy(nla_data(nla), data, attrlen);
295}
296
297
298/**
299 * nla_put - Add a netlink attribute to a socket buffer
300 * @skb: socket buffer to add attribute to
301 * @attrtype: attribute type
302 * @attrlen: length of attribute payload
303 * @data: head of attribute payload
304 *
305 * Returns -1 if the tailroom of the skb is insufficient to store
306 * the attribute header and payload.
307 */
308int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
309{
310 if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
311 return -1;
312
313 __nla_put(skb, attrtype, attrlen, data);
314 return 0;
315}
316
317
318EXPORT_SYMBOL(nla_validate);
319EXPORT_SYMBOL(nla_parse);
320EXPORT_SYMBOL(nla_find);
321EXPORT_SYMBOL(nla_strlcpy);
322EXPORT_SYMBOL(__nla_reserve);
323EXPORT_SYMBOL(nla_reserve);
324EXPORT_SYMBOL(__nla_put);
325EXPORT_SYMBOL(nla_put);
326EXPORT_SYMBOL(nla_memcpy);
327EXPORT_SYMBOL(nla_memcmp);
328EXPORT_SYMBOL(nla_strcmp);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
new file mode 100644
index 000000000000..287cfcc56951
--- /dev/null
+++ b/net/netlink/genetlink.c
@@ -0,0 +1,579 @@
1/*
2 * NETLINK Generic Netlink Family
3 *
4 * Authors: Jamal Hadi Salim
5 * Thomas Graf <tgraf@suug.ch>
6 */
7
8#include <linux/config.h>
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/errno.h>
12#include <linux/types.h>
13#include <linux/socket.h>
14#include <linux/string.h>
15#include <linux/skbuff.h>
16#include <net/sock.h>
17#include <net/genetlink.h>
18
19struct sock *genl_sock = NULL;
20
21static DECLARE_MUTEX(genl_sem); /* serialization of message processing */
22
23static void genl_lock(void)
24{
25 down(&genl_sem);
26}
27
28static int genl_trylock(void)
29{
30 return down_trylock(&genl_sem);
31}
32
33static void genl_unlock(void)
34{
35 up(&genl_sem);
36
37 if (genl_sock && genl_sock->sk_receive_queue.qlen)
38 genl_sock->sk_data_ready(genl_sock, 0);
39}
40
41#define GENL_FAM_TAB_SIZE 16
42#define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1)
43
44static struct list_head family_ht[GENL_FAM_TAB_SIZE];
45
46static int genl_ctrl_event(int event, void *data);
47
48static inline unsigned int genl_family_hash(unsigned int id)
49{
50 return id & GENL_FAM_TAB_MASK;
51}
52
53static inline struct list_head *genl_family_chain(unsigned int id)
54{
55 return &family_ht[genl_family_hash(id)];
56}
57
58static struct genl_family *genl_family_find_byid(unsigned int id)
59{
60 struct genl_family *f;
61
62 list_for_each_entry(f, genl_family_chain(id), family_list)
63 if (f->id == id)
64 return f;
65
66 return NULL;
67}
68
69static struct genl_family *genl_family_find_byname(char *name)
70{
71 struct genl_family *f;
72 int i;
73
74 for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
75 list_for_each_entry(f, genl_family_chain(i), family_list)
76 if (strcmp(f->name, name) == 0)
77 return f;
78
79 return NULL;
80}
81
82static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
83{
84 struct genl_ops *ops;
85
86 list_for_each_entry(ops, &family->ops_list, ops_list)
87 if (ops->cmd == cmd)
88 return ops;
89
90 return NULL;
91}
92
93/* Of course we are going to have problems once we hit
94 * 2^16 alive types, but that can only happen by year 2K
95*/
96static inline u16 genl_generate_id(void)
97{
98 static u16 id_gen_idx;
99 int overflowed = 0;
100
101 do {
102 if (id_gen_idx == 0)
103 id_gen_idx = GENL_MIN_ID;
104
105 if (++id_gen_idx > GENL_MAX_ID) {
106 if (!overflowed) {
107 overflowed = 1;
108 id_gen_idx = 0;
109 continue;
110 } else
111 return 0;
112 }
113
114 } while (genl_family_find_byid(id_gen_idx));
115
116 return id_gen_idx;
117}
118
119/**
120 * genl_register_ops - register generic netlink operations
121 * @family: generic netlink family
122 * @ops: operations to be registered
123 *
124 * Registers the specified operations and assigns them to the specified
125 * family. Either a doit or dumpit callback must be specified or the
126 * operation will fail. Only one operation structure per command
127 * identifier may be registered.
128 *
129 * See include/net/genetlink.h for more documenation on the operations
130 * structure.
131 *
132 * Returns 0 on success or a negative error code.
133 */
134int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
135{
136 int err = -EINVAL;
137
138 if (ops->dumpit == NULL && ops->doit == NULL)
139 goto errout;
140
141 if (genl_get_cmd(ops->cmd, family)) {
142 err = -EEXIST;
143 goto errout;
144 }
145
146 genl_lock();
147 list_add_tail(&ops->ops_list, &family->ops_list);
148 genl_unlock();
149
150 genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
151 err = 0;
152errout:
153 return err;
154}
155
156/**
157 * genl_unregister_ops - unregister generic netlink operations
158 * @family: generic netlink family
159 * @ops: operations to be unregistered
160 *
161 * Unregisters the specified operations and unassigns them from the
162 * specified family. The operation blocks until the current message
163 * processing has finished and doesn't start again until the
164 * unregister process has finished.
165 *
166 * Note: It is not necessary to unregister all operations before
167 * unregistering the family, unregistering the family will cause
168 * all assigned operations to be unregistered automatically.
169 *
170 * Returns 0 on success or a negative error code.
171 */
172int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
173{
174 struct genl_ops *rc;
175
176 genl_lock();
177 list_for_each_entry(rc, &family->ops_list, ops_list) {
178 if (rc == ops) {
179 list_del(&ops->ops_list);
180 genl_unlock();
181 genl_ctrl_event(CTRL_CMD_DELOPS, ops);
182 return 0;
183 }
184 }
185 genl_unlock();
186
187 return -ENOENT;
188}
189
190/**
191 * genl_register_family - register a generic netlink family
192 * @family: generic netlink family
193 *
194 * Registers the specified family after validating it first. Only one
195 * family may be registered with the same family name or identifier.
196 * The family id may equal GENL_ID_GENERATE causing an unique id to
197 * be automatically generated and assigned.
198 *
199 * Return 0 on success or a negative error code.
200 */
201int genl_register_family(struct genl_family *family)
202{
203 int err = -EINVAL;
204
205 if (family->id && family->id < GENL_MIN_ID)
206 goto errout;
207
208 if (family->id > GENL_MAX_ID)
209 goto errout;
210
211 INIT_LIST_HEAD(&family->ops_list);
212
213 genl_lock();
214
215 if (genl_family_find_byname(family->name)) {
216 err = -EEXIST;
217 goto errout_locked;
218 }
219
220 if (genl_family_find_byid(family->id)) {
221 err = -EEXIST;
222 goto errout_locked;
223 }
224
225 if (!try_module_get(family->owner)) {
226 err = -EBUSY;
227 goto errout_locked;
228 }
229
230 if (family->id == GENL_ID_GENERATE) {
231 u16 newid = genl_generate_id();
232
233 if (!newid) {
234 err = -ENOMEM;
235 goto errout_locked;
236 }
237
238 family->id = newid;
239 }
240
241 if (family->maxattr) {
242 family->attrbuf = kmalloc((family->maxattr+1) *
243 sizeof(struct nlattr *), GFP_KERNEL);
244 if (family->attrbuf == NULL) {
245 err = -ENOMEM;
246 goto errout;
247 }
248 } else
249 family->attrbuf = NULL;
250
251 list_add_tail(&family->family_list, genl_family_chain(family->id));
252 genl_unlock();
253
254 genl_ctrl_event(CTRL_CMD_NEWFAMILY, family);
255
256 return 0;
257
258errout_locked:
259 genl_unlock();
260errout:
261 return err;
262}
263
264/**
265 * genl_unregister_family - unregister generic netlink family
266 * @family: generic netlink family
267 *
268 * Unregisters the specified family.
269 *
270 * Returns 0 on success or a negative error code.
271 */
272int genl_unregister_family(struct genl_family *family)
273{
274 struct genl_family *rc;
275
276 genl_lock();
277
278 list_for_each_entry(rc, genl_family_chain(family->id), family_list) {
279 if (family->id != rc->id || strcmp(rc->name, family->name))
280 continue;
281
282 list_del(&rc->family_list);
283 INIT_LIST_HEAD(&family->ops_list);
284 genl_unlock();
285
286 module_put(family->owner);
287 kfree(family->attrbuf);
288 genl_ctrl_event(CTRL_CMD_DELFAMILY, family);
289 return 0;
290 }
291
292 genl_unlock();
293
294 return -ENOENT;
295}
296
297static inline int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
298 int *errp)
299{
300 struct genl_ops *ops;
301 struct genl_family *family;
302 struct genl_info info;
303 struct genlmsghdr *hdr = nlmsg_data(nlh);
304 int hdrlen, err = -EINVAL;
305
306 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
307 goto ignore;
308
309 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
310 goto ignore;
311
312 family = genl_family_find_byid(nlh->nlmsg_type);
313 if (family == NULL) {
314 err = -ENOENT;
315 goto errout;
316 }
317
318 hdrlen = GENL_HDRLEN + family->hdrsize;
319 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
320 goto errout;
321
322 ops = genl_get_cmd(hdr->cmd, family);
323 if (ops == NULL) {
324 err = -EOPNOTSUPP;
325 goto errout;
326 }
327
328 if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb)) {
329 err = -EPERM;
330 goto errout;
331 }
332
333 if (nlh->nlmsg_flags & NLM_F_DUMP) {
334 if (ops->dumpit == NULL) {
335 err = -EOPNOTSUPP;
336 goto errout;
337 }
338
339 *errp = err = netlink_dump_start(genl_sock, skb, nlh,
340 ops->dumpit, NULL);
341 if (err == 0)
342 skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len),
343 skb->len));
344 return -1;
345 }
346
347 if (ops->doit == NULL) {
348 err = -EOPNOTSUPP;
349 goto errout;
350 }
351
352 if (family->attrbuf) {
353 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
354 ops->policy);
355 if (err < 0)
356 goto errout;
357 }
358
359 info.snd_seq = nlh->nlmsg_seq;
360 info.snd_pid = NETLINK_CB(skb).pid;
361 info.nlhdr = nlh;
362 info.genlhdr = nlmsg_data(nlh);
363 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
364 info.attrs = family->attrbuf;
365
366 *errp = err = ops->doit(skb, &info);
367 return err;
368
369ignore:
370 return 0;
371
372errout:
373 *errp = err;
374 return -1;
375}
376
377static void genl_rcv(struct sock *sk, int len)
378{
379 unsigned int qlen = 0;
380
381 do {
382 if (genl_trylock())
383 return;
384 netlink_run_queue(sk, &qlen, &genl_rcv_msg);
385 genl_unlock();
386 } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen);
387}
388
389/**************************************************************************
390 * Controller
391 **************************************************************************/
392
393static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
394 u32 flags, struct sk_buff *skb, u8 cmd)
395{
396 void *hdr;
397
398 hdr = genlmsg_put(skb, pid, seq, GENL_ID_CTRL, 0, flags, cmd,
399 family->version);
400 if (hdr == NULL)
401 return -1;
402
403 NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
404 NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
405
406 return genlmsg_end(skb, hdr);
407
408nla_put_failure:
409 return genlmsg_cancel(skb, hdr);
410}
411
412static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
413{
414
415 int i, n = 0;
416 struct genl_family *rt;
417 int chains_to_skip = cb->args[0];
418 int fams_to_skip = cb->args[1];
419
420 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
421 if (i < chains_to_skip)
422 continue;
423 n = 0;
424 list_for_each_entry(rt, genl_family_chain(i), family_list) {
425 if (++n < fams_to_skip)
426 continue;
427 if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
428 cb->nlh->nlmsg_seq, NLM_F_MULTI,
429 skb, CTRL_CMD_NEWFAMILY) < 0)
430 goto errout;
431 }
432
433 fams_to_skip = 0;
434 }
435
436errout:
437 cb->args[0] = i;
438 cb->args[1] = n;
439
440 return skb->len;
441}
442
443static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
444 int seq, int cmd)
445{
446 struct sk_buff *skb;
447 int err;
448
449 skb = nlmsg_new(NLMSG_GOODSIZE);
450 if (skb == NULL)
451 return ERR_PTR(-ENOBUFS);
452
453 err = ctrl_fill_info(family, pid, seq, 0, skb, cmd);
454 if (err < 0) {
455 nlmsg_free(skb);
456 return ERR_PTR(err);
457 }
458
459 return skb;
460}
461
462static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = {
463 [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
464 [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING },
465};
466
467static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
468{
469 struct sk_buff *msg;
470 struct genl_family *res = NULL;
471 int err = -EINVAL;
472
473 if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
474 u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
475 res = genl_family_find_byid(id);
476 }
477
478 if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
479 char name[GENL_NAMSIZ];
480
481 if (nla_strlcpy(name, info->attrs[CTRL_ATTR_FAMILY_NAME],
482 GENL_NAMSIZ) >= GENL_NAMSIZ)
483 goto errout;
484
485 res = genl_family_find_byname(name);
486 }
487
488 if (res == NULL) {
489 err = -ENOENT;
490 goto errout;
491 }
492
493 msg = ctrl_build_msg(res, info->snd_pid, info->snd_seq,
494 CTRL_CMD_NEWFAMILY);
495 if (IS_ERR(msg)) {
496 err = PTR_ERR(msg);
497 goto errout;
498 }
499
500 err = genlmsg_unicast(msg, info->snd_pid);
501errout:
502 return err;
503}
504
505static int genl_ctrl_event(int event, void *data)
506{
507 struct sk_buff *msg;
508
509 if (genl_sock == NULL)
510 return 0;
511
512 switch (event) {
513 case CTRL_CMD_NEWFAMILY:
514 case CTRL_CMD_DELFAMILY:
515 msg = ctrl_build_msg(data, 0, 0, event);
516 if (IS_ERR(msg))
517 return PTR_ERR(msg);
518
519 genlmsg_multicast(msg, 0, GENL_ID_CTRL);
520 break;
521 }
522
523 return 0;
524}
525
526static struct genl_ops genl_ctrl_ops = {
527 .cmd = CTRL_CMD_GETFAMILY,
528 .doit = ctrl_getfamily,
529 .dumpit = ctrl_dumpfamily,
530 .policy = ctrl_policy,
531};
532
533static struct genl_family genl_ctrl = {
534 .id = GENL_ID_CTRL,
535 .name = "nlctrl",
536 .version = 0x1,
537 .maxattr = CTRL_ATTR_MAX,
538 .owner = THIS_MODULE,
539};
540
541static int __init genl_init(void)
542{
543 int i, err;
544
545 for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
546 INIT_LIST_HEAD(&family_ht[i]);
547
548 err = genl_register_family(&genl_ctrl);
549 if (err < 0)
550 goto errout;
551
552 err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
553 if (err < 0)
554 goto errout_register;
555
556 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
557 genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID,
558 genl_rcv, THIS_MODULE);
559 if (genl_sock == NULL) {
560 panic("GENL: Cannot initialize generic netlink\n");
561 return -ENOMEM;
562 }
563
564 return 0;
565
566errout_register:
567 genl_unregister_family(&genl_ctrl);
568errout:
569 panic("GENL: Cannot register controller: %d\n", err);
570 return err;
571}
572
573subsys_initcall(genl_init);
574
575EXPORT_SYMBOL(genl_sock);
576EXPORT_SYMBOL(genl_register_ops);
577EXPORT_SYMBOL(genl_unregister_ops);
578EXPORT_SYMBOL(genl_register_family);
579EXPORT_SYMBOL(genl_unregister_family);
diff --git a/net/rxrpc/transport.c b/net/rxrpc/transport.c
index 122c086ee2db..dbe6105e83a5 100644
--- a/net/rxrpc/transport.c
+++ b/net/rxrpc/transport.c
@@ -23,6 +23,7 @@
23#include <linux/in.h> 23#include <linux/in.h>
24#include <linux/in6.h> 24#include <linux/in6.h>
25#include <linux/icmp.h> 25#include <linux/icmp.h>
26#include <linux/skbuff.h>
26#include <net/sock.h> 27#include <net/sock.h>
27#include <net/ip.h> 28#include <net/ip.h>
28#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 29#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
@@ -475,15 +476,11 @@ void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
475 476
476 /* we'll probably need to checksum it (didn't call 477 /* we'll probably need to checksum it (didn't call
477 * sock_recvmsg) */ 478 * sock_recvmsg) */
478 if (pkt->ip_summed != CHECKSUM_UNNECESSARY) { 479 if (skb_checksum_complete(pkt)) {
479 if ((unsigned short) 480 kfree_skb(pkt);
480 csum_fold(skb_checksum(pkt, 0, pkt->len, 481 rxrpc_krxiod_queue_transport(trans);
481 pkt->csum))) { 482 _leave(" CSUM failed");
482 kfree_skb(pkt); 483 return;
483 rxrpc_krxiod_queue_transport(trans);
484 _leave(" CSUM failed");
485 return;
486 }
487 } 484 }
488 485
489 addr = pkt->nh.iph->saddr; 486 addr = pkt->nh.iph->saddr;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 702ede309b06..61c3abeaccae 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -55,6 +55,7 @@ static void call_bind(struct rpc_task *task);
55static void call_bind_status(struct rpc_task *task); 55static void call_bind_status(struct rpc_task *task);
56static void call_transmit(struct rpc_task *task); 56static void call_transmit(struct rpc_task *task);
57static void call_status(struct rpc_task *task); 57static void call_status(struct rpc_task *task);
58static void call_transmit_status(struct rpc_task *task);
58static void call_refresh(struct rpc_task *task); 59static void call_refresh(struct rpc_task *task);
59static void call_refreshresult(struct rpc_task *task); 60static void call_refreshresult(struct rpc_task *task);
60static void call_timeout(struct rpc_task *task); 61static void call_timeout(struct rpc_task *task);
@@ -672,6 +673,18 @@ call_allocate(struct rpc_task *task)
672 rpc_exit(task, -ERESTARTSYS); 673 rpc_exit(task, -ERESTARTSYS);
673} 674}
674 675
676static inline int
677rpc_task_need_encode(struct rpc_task *task)
678{
679 return task->tk_rqstp->rq_snd_buf.len == 0;
680}
681
682static inline void
683rpc_task_force_reencode(struct rpc_task *task)
684{
685 task->tk_rqstp->rq_snd_buf.len = 0;
686}
687
675/* 688/*
676 * 3. Encode arguments of an RPC call 689 * 3. Encode arguments of an RPC call
677 */ 690 */
@@ -867,12 +880,14 @@ call_transmit(struct rpc_task *task)
867 if (task->tk_status != 0) 880 if (task->tk_status != 0)
868 return; 881 return;
869 /* Encode here so that rpcsec_gss can use correct sequence number. */ 882 /* Encode here so that rpcsec_gss can use correct sequence number. */
870 if (task->tk_rqstp->rq_bytes_sent == 0) { 883 if (rpc_task_need_encode(task)) {
884 task->tk_rqstp->rq_bytes_sent = 0;
871 call_encode(task); 885 call_encode(task);
872 /* Did the encode result in an error condition? */ 886 /* Did the encode result in an error condition? */
873 if (task->tk_status != 0) 887 if (task->tk_status != 0)
874 goto out_nosend; 888 goto out_nosend;
875 } 889 }
890 task->tk_action = call_transmit_status;
876 xprt_transmit(task); 891 xprt_transmit(task);
877 if (task->tk_status < 0) 892 if (task->tk_status < 0)
878 return; 893 return;
@@ -884,6 +899,7 @@ call_transmit(struct rpc_task *task)
884out_nosend: 899out_nosend:
885 /* release socket write lock before attempting to handle error */ 900 /* release socket write lock before attempting to handle error */
886 xprt_abort_transmit(task); 901 xprt_abort_transmit(task);
902 rpc_task_force_reencode(task);
887} 903}
888 904
889/* 905/*
@@ -915,7 +931,6 @@ call_status(struct rpc_task *task)
915 break; 931 break;
916 case -ECONNREFUSED: 932 case -ECONNREFUSED:
917 case -ENOTCONN: 933 case -ENOTCONN:
918 req->rq_bytes_sent = 0;
919 if (clnt->cl_autobind) 934 if (clnt->cl_autobind)
920 clnt->cl_port = 0; 935 clnt->cl_port = 0;
921 task->tk_action = call_bind; 936 task->tk_action = call_bind;
@@ -937,7 +952,18 @@ call_status(struct rpc_task *task)
937} 952}
938 953
939/* 954/*
940 * 6a. Handle RPC timeout 955 * 6a. Handle transmission errors.
956 */
957static void
958call_transmit_status(struct rpc_task *task)
959{
960 if (task->tk_status != -EAGAIN)
961 rpc_task_force_reencode(task);
962 call_status(task);
963}
964
965/*
966 * 6b. Handle RPC timeout
941 * We do not release the request slot, so we keep using the 967 * We do not release the request slot, so we keep using the
942 * same XID for all retransmits. 968 * same XID for all retransmits.
943 */ 969 */
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 4f188d0a5d11..81e00a6c19de 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -603,7 +603,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
603 return ERR_PTR(error); 603 return ERR_PTR(error);
604 dir = nd->dentry->d_inode; 604 dir = nd->dentry->d_inode;
605 down(&dir->i_sem); 605 down(&dir->i_sem);
606 dentry = lookup_hash(&nd->last, nd->dentry); 606 dentry = lookup_hash(nd);
607 if (IS_ERR(dentry)) 607 if (IS_ERR(dentry))
608 goto out_err; 608 goto out_err;
609 if (dentry->d_inode) { 609 if (dentry->d_inode) {
@@ -665,7 +665,7 @@ rpc_rmdir(char *path)
665 return error; 665 return error;
666 dir = nd.dentry->d_inode; 666 dir = nd.dentry->d_inode;
667 down(&dir->i_sem); 667 down(&dir->i_sem);
668 dentry = lookup_hash(&nd.last, nd.dentry); 668 dentry = lookup_hash(&nd);
669 if (IS_ERR(dentry)) { 669 if (IS_ERR(dentry)) {
670 error = PTR_ERR(dentry); 670 error = PTR_ERR(dentry);
671 goto out_release; 671 goto out_release;
@@ -726,7 +726,7 @@ rpc_unlink(char *path)
726 return error; 726 return error;
727 dir = nd.dentry->d_inode; 727 dir = nd.dentry->d_inode;
728 down(&dir->i_sem); 728 down(&dir->i_sem);
729 dentry = lookup_hash(&nd.last, nd.dentry); 729 dentry = lookup_hash(&nd);
730 if (IS_ERR(dentry)) { 730 if (IS_ERR(dentry)) {
731 error = PTR_ERR(dentry); 731 error = PTR_ERR(dentry);
732 goto out_release; 732 goto out_release;
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index 8f97e90f36c8..eb330d4f66d6 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -6,6 +6,9 @@
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9#include <linux/compiler.h>
10#include <linux/netdevice.h>
11#include <linux/skbuff.h>
9#include <linux/types.h> 12#include <linux/types.h>
10#include <linux/pagemap.h> 13#include <linux/pagemap.h>
11#include <linux/udp.h> 14#include <linux/udp.h>
@@ -165,6 +168,8 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
165 return -1; 168 return -1;
166 if ((unsigned short)csum_fold(desc.csum)) 169 if ((unsigned short)csum_fold(desc.csum))
167 return -1; 170 return -1;
171 if (unlikely(skb->ip_summed == CHECKSUM_HW))
172 netdev_rx_csum_fault(skb->dev);
168 return 0; 173 return 0;
169no_checksum: 174no_checksum:
170 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0) 175 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index f16e7cdd6150..e50e7cf43737 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -623,12 +623,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
623 /* we can use it in-place */ 623 /* we can use it in-place */
624 rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); 624 rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr);
625 rqstp->rq_arg.head[0].iov_len = len; 625 rqstp->rq_arg.head[0].iov_len = len;
626 if (skb->ip_summed != CHECKSUM_UNNECESSARY) { 626 if (skb_checksum_complete(skb)) {
627 if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { 627 skb_free_datagram(svsk->sk_sk, skb);
628 skb_free_datagram(svsk->sk_sk, skb); 628 return 0;
629 return 0;
630 }
631 skb->ip_summed = CHECKSUM_UNNECESSARY;
632 } 629 }
633 rqstp->rq_skbuff = skb; 630 rqstp->rq_skbuff = skb;
634 } 631 }
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 41feca3bef86..acc73ba8bade 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -676,7 +676,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
676 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd); 676 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
677 if (err) 677 if (err)
678 goto fail; 678 goto fail;
679 err = permission(nd.dentry->d_inode,MAY_WRITE, &nd); 679 err = vfs_permission(&nd, MAY_WRITE);
680 if (err) 680 if (err)
681 goto put_fail; 681 goto put_fail;
682 682
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c35336a0f71b..0cdd9a07e043 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -18,7 +18,6 @@
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/net.h> 19#include <linux/net.h>
20#include <linux/skbuff.h> 20#include <linux/skbuff.h>
21#include <linux/netlink.h>
22#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
23#include <linux/pfkeyv2.h> 22#include <linux/pfkeyv2.h>
24#include <linux/ipsec.h> 23#include <linux/ipsec.h>
@@ -26,6 +25,7 @@
26#include <linux/security.h> 25#include <linux/security.h>
27#include <net/sock.h> 26#include <net/sock.h>
28#include <net/xfrm.h> 27#include <net/xfrm.h>
28#include <net/netlink.h>
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30 30
31static struct sock *xfrm_nl; 31static struct sock *xfrm_nl;
@@ -948,11 +948,6 @@ static struct xfrm_link {
948 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, 948 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy },
949}; 949};
950 950
951static int xfrm_done(struct netlink_callback *cb)
952{
953 return 0;
954}
955
956static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 951static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
957{ 952{
958 struct rtattr *xfrma[XFRMA_MAX]; 953 struct rtattr *xfrma[XFRMA_MAX];
@@ -984,20 +979,15 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err
984 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || 979 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
985 type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && 980 type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) &&
986 (nlh->nlmsg_flags & NLM_F_DUMP)) { 981 (nlh->nlmsg_flags & NLM_F_DUMP)) {
987 u32 rlen;
988
989 if (link->dump == NULL) 982 if (link->dump == NULL)
990 goto err_einval; 983 goto err_einval;
991 984
992 if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh, 985 if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh,
993 link->dump, 986 link->dump, NULL)) != 0) {
994 xfrm_done)) != 0) {
995 return -1; 987 return -1;
996 } 988 }
997 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 989
998 if (rlen > skb->len) 990 netlink_queue_skip(nlh, skb);
999 rlen = skb->len;
1000 skb_pull(skb, rlen);
1001 return -1; 991 return -1;
1002 } 992 }
1003 993
@@ -1032,60 +1022,13 @@ err_einval:
1032 return -1; 1022 return -1;
1033} 1023}
1034 1024
1035static int xfrm_user_rcv_skb(struct sk_buff *skb)
1036{
1037 int err;
1038 struct nlmsghdr *nlh;
1039
1040 while (skb->len >= NLMSG_SPACE(0)) {
1041 u32 rlen;
1042
1043 nlh = (struct nlmsghdr *) skb->data;
1044 if (nlh->nlmsg_len < sizeof(*nlh) ||
1045 skb->len < nlh->nlmsg_len)
1046 return 0;
1047 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
1048 if (rlen > skb->len)
1049 rlen = skb->len;
1050 if (xfrm_user_rcv_msg(skb, nlh, &err) < 0) {
1051 if (err == 0)
1052 return -1;
1053 netlink_ack(skb, nlh, err);
1054 } else if (nlh->nlmsg_flags & NLM_F_ACK)
1055 netlink_ack(skb, nlh, 0);
1056 skb_pull(skb, rlen);
1057 }
1058
1059 return 0;
1060}
1061
1062static void xfrm_netlink_rcv(struct sock *sk, int len) 1025static void xfrm_netlink_rcv(struct sock *sk, int len)
1063{ 1026{
1064 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); 1027 unsigned int qlen = 0;
1065 1028
1066 do { 1029 do {
1067 struct sk_buff *skb;
1068
1069 down(&xfrm_cfg_sem); 1030 down(&xfrm_cfg_sem);
1070 1031 netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg);
1071 if (qlen > skb_queue_len(&sk->sk_receive_queue))
1072 qlen = skb_queue_len(&sk->sk_receive_queue);
1073
1074 for (; qlen; qlen--) {
1075 skb = skb_dequeue(&sk->sk_receive_queue);
1076 if (xfrm_user_rcv_skb(skb)) {
1077 if (skb->len)
1078 skb_queue_head(&sk->sk_receive_queue,
1079 skb);
1080 else {
1081 kfree_skb(skb);
1082 qlen--;
1083 }
1084 break;
1085 }
1086 kfree_skb(skb);
1087 }
1088
1089 up(&xfrm_cfg_sem); 1032 up(&xfrm_cfg_sem);
1090 1033
1091 } while (qlen); 1034 } while (qlen);
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index c65c435c4923..9d67782b812f 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -114,7 +114,7 @@ gconf-objs := gconf.o kconfig_load.o zconf.tab.o
114endif 114endif
115 115
116clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ 116clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
117 .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c 117 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
118 118
119# Needed for systems without gettext 119# Needed for systems without gettext
120KBUILD_HAVE_NLS := $(shell \ 120KBUILD_HAVE_NLS := $(shell \
@@ -136,12 +136,6 @@ HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
136HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \ 136HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
137 -D LKC_DIRECT_LINK 137 -D LKC_DIRECT_LINK
138 138
139$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o $(obj)/kxgettext: $(obj)/zconf.tab.h
140
141$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
142$(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped
143$(obj)/lex.zconf.c: $(src)/lex.zconf.c_shipped
144
145$(obj)/qconf.o: $(obj)/.tmp_qtcheck 139$(obj)/qconf.o: $(obj)/.tmp_qtcheck
146 140
147ifeq ($(qconf-target),1) 141ifeq ($(qconf-target),1)
@@ -207,7 +201,7 @@ $(obj)/.tmp_gtkcheck:
207 fi 201 fi
208endif 202endif
209 203
210$(obj)/zconf.tab.o: $(obj)/lex.zconf.c 204$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c
211 205
212$(obj)/kconfig_load.o: $(obj)/lkc_defs.h 206$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
213 207
@@ -223,20 +217,27 @@ $(obj)/lkc_defs.h: $(src)/lkc_proto.h
223 217
224 218
225### 219###
226# The following requires flex/bison 220# The following requires flex/bison/gperf
227# By default we use the _shipped versions, uncomment the following line if 221# By default we use the _shipped versions, uncomment the following line if
228# you are modifying the flex/bison src. 222# you are modifying the flex/bison src.
229# LKC_GENPARSER := 1 223# LKC_GENPARSER := 1
230 224
231ifdef LKC_GENPARSER 225ifdef LKC_GENPARSER
232 226
233$(obj)/zconf.tab.c: $(obj)/zconf.y 227$(obj)/zconf.tab.c: $(src)/zconf.y
234$(obj)/zconf.tab.h: $(obj)/zconf.tab.c 228$(obj)/lex.zconf.c: $(src)/zconf.l
229$(obj)/zconf.hash.c: $(src)/zconf.gperf
235 230
236%.tab.c: %.y 231%.tab.c: %.y
237 bison -t -d -v -b $* -p $(notdir $*) $< 232 bison -l -b $* -p $(notdir $*) $<
233 cp $@ $@_shipped
238 234
239lex.%.c: %.l 235lex.%.c: %.l
240 flex -P$(notdir $*) -o$@ $< 236 flex -L -P$(notdir $*) -o$@ $<
237 cp $@ $@_shipped
238
239%.hash.c: %.gperf
240 gperf < $< > $@
241 cp $@ $@_shipped
241 242
242endif 243endif
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index bc20cab9d0d6..8ba5d29d3d42 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -82,6 +82,15 @@ static void conf_askvalue(struct symbol *sym, const char *def)
82 } 82 }
83 83
84 switch (input_mode) { 84 switch (input_mode) {
85 case set_no:
86 case set_mod:
87 case set_yes:
88 case set_random:
89 if (sym_has_value(sym)) {
90 printf("%s\n", def);
91 return;
92 }
93 break;
85 case ask_new: 94 case ask_new:
86 case ask_silent: 95 case ask_silent:
87 if (sym_has_value(sym)) { 96 if (sym_has_value(sym)) {
@@ -467,15 +476,14 @@ static void check_conf(struct menu *menu)
467 return; 476 return;
468 477
469 sym = menu->sym; 478 sym = menu->sym;
470 if (sym) { 479 if (sym && !sym_has_value(sym)) {
471 if (sym_is_changable(sym) && !sym_has_value(sym)) { 480 if (sym_is_changable(sym) ||
481 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
472 if (!conf_cnt++) 482 if (!conf_cnt++)
473 printf(_("*\n* Restart config...\n*\n")); 483 printf(_("*\n* Restart config...\n*\n"));
474 rootEntry = menu_get_parent_menu(menu); 484 rootEntry = menu_get_parent_menu(menu);
475 conf(rootEntry); 485 conf(rootEntry);
476 } 486 }
477 if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
478 return;
479 } 487 }
480 488
481 for (child = menu->list; child; child = child->next) 489 for (child = menu->list; child; child = child->next)
@@ -559,6 +567,27 @@ int main(int ac, char **av)
559 case ask_new: 567 case ask_new:
560 conf_read(NULL); 568 conf_read(NULL);
561 break; 569 break;
570 case set_no:
571 case set_mod:
572 case set_yes:
573 case set_random:
574 name = getenv("KCONFIG_ALLCONFIG");
575 if (name && !stat(name, &tmpstat)) {
576 conf_read_simple(name);
577 break;
578 }
579 switch (input_mode) {
580 case set_no: name = "allno.config"; break;
581 case set_mod: name = "allmod.config"; break;
582 case set_yes: name = "allyes.config"; break;
583 case set_random: name = "allrandom.config"; break;
584 default: break;
585 }
586 if (!stat(name, &tmpstat))
587 conf_read_simple(name);
588 else if (!stat("all.config", &tmpstat))
589 conf_read_simple("all.config");
590 break;
562 default: 591 default:
563 break; 592 break;
564 } 593 }
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 02f670cc6bb9..ccd45130c482 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -14,6 +14,12 @@
14#define LKC_DIRECT_LINK 14#define LKC_DIRECT_LINK
15#include "lkc.h" 15#include "lkc.h"
16 16
17static void conf_warning(const char *fmt, ...)
18 __attribute__ ((format (printf, 1, 2)));
19
20static const char *conf_filename;
21static int conf_lineno, conf_warnings, conf_unsaved;
22
17const char conf_def_filename[] = ".config"; 23const char conf_def_filename[] = ".config";
18 24
19const char conf_defname[] = "arch/$ARCH/defconfig"; 25const char conf_defname[] = "arch/$ARCH/defconfig";
@@ -27,6 +33,17 @@ const char *conf_confnames[] = {
27 NULL, 33 NULL,
28}; 34};
29 35
36static void conf_warning(const char *fmt, ...)
37{
38 va_list ap;
39 va_start(ap, fmt);
40 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
41 vfprintf(stderr, fmt, ap);
42 fprintf(stderr, "\n");
43 va_end(ap);
44 conf_warnings++;
45}
46
30static char *conf_expand_value(const char *in) 47static char *conf_expand_value(const char *in)
31{ 48{
32 struct symbol *sym; 49 struct symbol *sym;
@@ -69,15 +86,12 @@ char *conf_get_default_confname(void)
69 return name; 86 return name;
70} 87}
71 88
72int conf_read(const char *name) 89int conf_read_simple(const char *name)
73{ 90{
74 FILE *in = NULL; 91 FILE *in = NULL;
75 char line[1024]; 92 char line[1024];
76 char *p, *p2; 93 char *p, *p2;
77 int lineno = 0;
78 struct symbol *sym; 94 struct symbol *sym;
79 struct property *prop;
80 struct expr *e;
81 int i; 95 int i;
82 96
83 if (name) { 97 if (name) {
@@ -95,12 +109,18 @@ int conf_read(const char *name)
95 } 109 }
96 } 110 }
97 } 111 }
98
99 if (!in) 112 if (!in)
100 return 1; 113 return 1;
101 114
115 conf_filename = name;
116 conf_lineno = 0;
117 conf_warnings = 0;
118 conf_unsaved = 0;
119
102 for_all_symbols(i, sym) { 120 for_all_symbols(i, sym) {
103 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; 121 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
122 if (sym_is_choice(sym))
123 sym->flags &= ~SYMBOL_NEW;
104 sym->flags &= ~SYMBOL_VALID; 124 sym->flags &= ~SYMBOL_VALID;
105 switch (sym->type) { 125 switch (sym->type) {
106 case S_INT: 126 case S_INT:
@@ -115,7 +135,7 @@ int conf_read(const char *name)
115 } 135 }
116 136
117 while (fgets(line, sizeof(line), in)) { 137 while (fgets(line, sizeof(line), in)) {
118 lineno++; 138 conf_lineno++;
119 sym = NULL; 139 sym = NULL;
120 switch (line[0]) { 140 switch (line[0]) {
121 case '#': 141 case '#':
@@ -129,7 +149,10 @@ int conf_read(const char *name)
129 continue; 149 continue;
130 sym = sym_find(line + 9); 150 sym = sym_find(line + 9);
131 if (!sym) { 151 if (!sym) {
132 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9); 152 conf_warning("trying to assign nonexistent symbol %s", line + 9);
153 break;
154 } else if (!(sym->flags & SYMBOL_NEW)) {
155 conf_warning("trying to reassign symbol %s", sym->name);
133 break; 156 break;
134 } 157 }
135 switch (sym->type) { 158 switch (sym->type) {
@@ -143,8 +166,10 @@ int conf_read(const char *name)
143 } 166 }
144 break; 167 break;
145 case 'C': 168 case 'C':
146 if (memcmp(line, "CONFIG_", 7)) 169 if (memcmp(line, "CONFIG_", 7)) {
170 conf_warning("unexpected data");
147 continue; 171 continue;
172 }
148 p = strchr(line + 7, '='); 173 p = strchr(line + 7, '=');
149 if (!p) 174 if (!p)
150 continue; 175 continue;
@@ -154,7 +179,10 @@ int conf_read(const char *name)
154 *p2 = 0; 179 *p2 = 0;
155 sym = sym_find(line + 7); 180 sym = sym_find(line + 7);
156 if (!sym) { 181 if (!sym) {
157 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); 182 conf_warning("trying to assign nonexistent symbol %s", line + 7);
183 break;
184 } else if (!(sym->flags & SYMBOL_NEW)) {
185 conf_warning("trying to reassign symbol %s", sym->name);
158 break; 186 break;
159 } 187 }
160 switch (sym->type) { 188 switch (sym->type) {
@@ -175,6 +203,7 @@ int conf_read(const char *name)
175 sym->flags &= ~SYMBOL_NEW; 203 sym->flags &= ~SYMBOL_NEW;
176 break; 204 break;
177 } 205 }
206 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
178 break; 207 break;
179 case S_STRING: 208 case S_STRING:
180 if (*p++ != '"') 209 if (*p++ != '"')
@@ -187,8 +216,8 @@ int conf_read(const char *name)
187 memmove(p2, p2 + 1, strlen(p2)); 216 memmove(p2, p2 + 1, strlen(p2));
188 } 217 }
189 if (!p2) { 218 if (!p2) {
190 fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); 219 conf_warning("invalid string found");
191 exit(1); 220 continue;
192 } 221 }
193 case S_INT: 222 case S_INT:
194 case S_HEX: 223 case S_HEX:
@@ -196,8 +225,8 @@ int conf_read(const char *name)
196 sym->user.val = strdup(p); 225 sym->user.val = strdup(p);
197 sym->flags &= ~SYMBOL_NEW; 226 sym->flags &= ~SYMBOL_NEW;
198 } else { 227 } else {
199 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); 228 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
200 exit(1); 229 continue;
201 } 230 }
202 break; 231 break;
203 default: 232 default:
@@ -207,6 +236,7 @@ int conf_read(const char *name)
207 case '\n': 236 case '\n':
208 break; 237 break;
209 default: 238 default:
239 conf_warning("unexpected data");
210 continue; 240 continue;
211 } 241 }
212 if (sym && sym_is_choice_value(sym)) { 242 if (sym && sym_is_choice_value(sym)) {
@@ -215,25 +245,63 @@ int conf_read(const char *name)
215 case no: 245 case no:
216 break; 246 break;
217 case mod: 247 case mod:
218 if (cs->user.tri == yes) 248 if (cs->user.tri == yes) {
219 /* warn? */; 249 conf_warning("%s creates inconsistent choice state", sym->name);
250 cs->flags |= SYMBOL_NEW;
251 }
220 break; 252 break;
221 case yes: 253 case yes:
222 if (cs->user.tri != no) 254 if (cs->user.tri != no) {
223 /* warn? */; 255 conf_warning("%s creates inconsistent choice state", sym->name);
224 cs->user.val = sym; 256 cs->flags |= SYMBOL_NEW;
257 } else
258 cs->user.val = sym;
225 break; 259 break;
226 } 260 }
227 cs->user.tri = E_OR(cs->user.tri, sym->user.tri); 261 cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
228 cs->flags &= ~SYMBOL_NEW;
229 } 262 }
230 } 263 }
231 fclose(in); 264 fclose(in);
232 265
233 if (modules_sym) 266 if (modules_sym)
234 sym_calc_value(modules_sym); 267 sym_calc_value(modules_sym);
268 return 0;
269}
270
271int conf_read(const char *name)
272{
273 struct symbol *sym;
274 struct property *prop;
275 struct expr *e;
276 int i;
277
278 if (conf_read_simple(name))
279 return 1;
280
235 for_all_symbols(i, sym) { 281 for_all_symbols(i, sym) {
236 sym_calc_value(sym); 282 sym_calc_value(sym);
283 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
284 goto sym_ok;
285 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
286 /* check that calculated value agrees with saved value */
287 switch (sym->type) {
288 case S_BOOLEAN:
289 case S_TRISTATE:
290 if (sym->user.tri != sym_get_tristate_value(sym))
291 break;
292 if (!sym_is_choice(sym))
293 goto sym_ok;
294 default:
295 if (!strcmp(sym->curr.val, sym->user.val))
296 goto sym_ok;
297 break;
298 }
299 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
300 /* no previous value and not saved */
301 goto sym_ok;
302 conf_unsaved++;
303 /* maybe print value in verbose mode... */
304 sym_ok:
237 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 305 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
238 if (sym->visible == no) 306 if (sym->visible == no)
239 sym->flags |= SYMBOL_NEW; 307 sym->flags |= SYMBOL_NEW;
@@ -241,8 +309,10 @@ int conf_read(const char *name)
241 case S_STRING: 309 case S_STRING:
242 case S_INT: 310 case S_INT:
243 case S_HEX: 311 case S_HEX:
244 if (!sym_string_within_range(sym, sym->user.val)) 312 if (!sym_string_within_range(sym, sym->user.val)) {
245 sym->flags |= SYMBOL_NEW; 313 sym->flags |= SYMBOL_NEW;
314 sym->flags &= ~SYMBOL_VALID;
315 }
246 default: 316 default:
247 break; 317 break;
248 } 318 }
@@ -255,7 +325,7 @@ int conf_read(const char *name)
255 sym->flags |= e->right.sym->flags & SYMBOL_NEW; 325 sym->flags |= e->right.sym->flags & SYMBOL_NEW;
256 } 326 }
257 327
258 sym_change_count = 1; 328 sym_change_count = conf_warnings && conf_unsaved;
259 329
260 return 0; 330 return 0;
261} 331}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 7d39ff43e6e1..1b36ef18c48d 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -93,7 +93,6 @@ struct symbol {
93#define SYMBOL_NEW 0x0800 93#define SYMBOL_NEW 0x0800
94#define SYMBOL_AUTO 0x1000 94#define SYMBOL_AUTO 0x1000
95#define SYMBOL_CHECKED 0x2000 95#define SYMBOL_CHECKED 0x2000
96#define SYMBOL_CHECK_DONE 0x4000
97#define SYMBOL_WARNED 0x8000 96#define SYMBOL_WARNED 0x8000
98 97
99#define SYMBOL_MAXLENGTH 256 98#define SYMBOL_MAXLENGTH 256
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index 22dda11f758b..24e3c8cbb7ac 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -1,5 +1,5 @@
1 1
2#line 3 "lex.zconf.c" 2#line 3 "scripts/kconfig/lex.zconf.c"
3 3
4#define YY_INT_ALIGNED short int 4#define YY_INT_ALIGNED short int
5 5
@@ -323,7 +323,7 @@ void zconffree (void * );
323 323
324/* Begin user sect3 */ 324/* Begin user sect3 */
325 325
326#define zconfwrap(n) 1 326#define zconfwrap() 1
327#define YY_SKIP_YYWRAP 327#define YY_SKIP_YYWRAP
328 328
329typedef unsigned char YY_CHAR; 329typedef unsigned char YY_CHAR;
@@ -338,1567 +338,323 @@ int zconflineno = 1;
338 338
339extern char *zconftext; 339extern char *zconftext;
340#define yytext_ptr zconftext 340#define yytext_ptr zconftext
341static yyconst flex_int16_t yy_nxt[][38] = 341static yyconst flex_int16_t yy_nxt[][17] =
342 { 342 {
343 { 343 {
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
345 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345 0, 0, 0, 0, 0, 0, 0
346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0
348 }, 346 },
349 347
350 { 348 {
351 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, 349 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
352 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 350 12, 12, 12, 12, 12, 12, 12
353 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
354 12, 12, 12, 12, 12, 12, 12, 12
355 }, 351 },
356 352
357 { 353 {
358 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, 354 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
359 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 355 12, 12, 12, 12, 12, 12, 12
360
361 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
362 12, 12, 12, 12, 12, 12, 12, 12
363 }, 356 },
364 357
365 { 358 {
366 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, 359 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
367 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, 360 16, 16, 16, 18, 16, 16, 16
368 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
369 27, 18, 28, 29, 30, 18, 18, 16
370 }, 361 },
371 362
372 { 363 {
373 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, 364 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
374 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, 365 16, 16, 16, 18, 16, 16, 16
375 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
376 27, 18, 28, 29, 30, 18, 18, 16
377 366
378 }, 367 },
379 368
380 { 369 {
381 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, 370 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
382 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 371 19, 19, 19, 19, 19, 19, 19
383 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
384 31, 31, 31, 31, 31, 31, 31, 31
385 }, 372 },
386 373
387 { 374 {
388 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, 375 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
389 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 376 19, 19, 19, 19, 19, 19, 19
390 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
391 31, 31, 31, 31, 31, 31, 31, 31
392 }, 377 },
393 378
394 { 379 {
395 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, 380 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
396 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, 381 22, 22, 22, 22, 22, 25, 22
397
398 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
399 34, 34, 34, 34, 34, 34, 34, 34
400 }, 382 },
401 383
402 { 384 {
403 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, 385 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
404 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, 386 22, 22, 22, 22, 22, 25, 22
405 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
406 34, 34, 34, 34, 34, 34, 34, 34
407 }, 387 },
408 388
409 { 389 {
410 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, 390 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
411 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, 391 33, 34, 35, 35, 36, 37, 38
412 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
413 47, 47, 47, 47, 47, 47, 47, 52
414 392
415 }, 393 },
416 394
417 { 395 {
418 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, 396 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
419 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, 397 33, 34, 35, 35, 36, 37, 38
420 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
421 47, 47, 47, 47, 47, 47, 47, 52
422 }, 398 },
423 399
424 { 400 {
425 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, 401 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
426 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, 402 -11, -11, -11, -11, -11, -11, -11
427 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
428 -11, -11, -11, -11, -11, -11, -11, -11
429 }, 403 },
430 404
431 { 405 {
432 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, 406 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
433 -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, 407 -12, -12, -12, -12, -12, -12, -12
434
435 -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
436 -12, -12, -12, -12, -12, -12, -12, -12
437 }, 408 },
438 409
439 { 410 {
440 11, -13, 53, 54, -13, -13, 55, -13, -13, -13, 411 11, -13, 39, 40, -13, -13, 41, -13, -13, -13,
441 -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, 412 -13, -13, -13, -13, -13, -13, -13
442 -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
443 -13, -13, -13, -13, -13, -13, -13, -13
444 }, 413 },
445 414
446 { 415 {
447 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, 416 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
448 -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, 417 -14, -14, -14, -14, -14, -14, -14
449 -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
450 -14, -14, -14, -14, -14, -14, -14, -14
451 418
452 }, 419 },
453 420
454 { 421 {
455 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, 422 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
456 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 423 42, 42, 42, 42, 42, 42, 42
457 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
458 56, 56, 56, 56, 56, 56, 56, 56
459 }, 424 },
460 425
461 { 426 {
462 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, 427 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
463 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, 428 -16, -16, -16, -16, -16, -16, -16
464 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
465 -16, -16, -16, -16, -16, -16, -16, -16
466 }, 429 },
467 430
468 { 431 {
469 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, 432 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
470 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, 433 -17, -17, -17, -17, -17, -17, -17
471
472 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
473 -17, -17, -17, -17, -17, -17, -17, -17
474 }, 434 },
475 435
476 { 436 {
477 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, 437 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
478 -18, -18, -18, 58, -18, -18, 58, 58, 58, 58, 438 -18, -18, -18, 44, -18, -18, -18
479 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
480 58, 58, 58, 58, 58, 58, 58, -18
481 }, 439 },
482 440
483 { 441 {
484 11, -19, -19, -19, -19, -19, -19, -19, -19, -19, 442 11, 45, 45, -19, 45, 45, 45, 45, 45, 45,
485 -19, -19, -19, 58, -19, -19, 58, 58, 58, 58, 443 45, 45, 45, 45, 45, 45, 45
486 58, 58, 58, 58, 58, 58, 58, 58, 58, 59,
487 58, 58, 58, 58, 58, 58, 58, -19
488 444
489 }, 445 },
490 446
491 { 447 {
492 11, -20, -20, -20, -20, -20, -20, -20, -20, -20, 448 11, -20, 46, 47, -20, -20, -20, -20, -20, -20,
493 -20, -20, -20, 58, -20, -20, 58, 58, 58, 58, 449 -20, -20, -20, -20, -20, -20, -20
494 58, 58, 58, 58, 60, 58, 58, 58, 58, 61,
495 58, 58, 58, 58, 58, 58, 58, -20
496 }, 450 },
497 451
498 { 452 {
499 11, -21, -21, -21, -21, -21, -21, -21, -21, -21, 453 11, 48, -21, -21, 48, 48, 48, 48, 48, 48,
500 -21, -21, -21, 58, -21, -21, 58, 58, 58, 58, 454 48, 48, 48, 48, 48, 48, 48
501 58, 62, 58, 58, 58, 58, 58, 58, 58, 58,
502 58, 58, 58, 58, 58, 58, 58, -21
503 }, 455 },
504 456
505 { 457 {
506 11, -22, -22, -22, -22, -22, -22, -22, -22, -22, 458 11, 49, 49, 50, 49, -22, 49, 49, -22, 49,
507 -22, -22, -22, 58, -22, -22, 58, 58, 58, 58, 459 49, 49, 49, 49, 49, -22, 49
508
509 58, 58, 58, 58, 58, 58, 58, 58, 63, 58,
510 58, 58, 58, 58, 58, 58, 58, -22
511 }, 460 },
512 461
513 { 462 {
514 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, 463 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
515 -23, -23, -23, 58, -23, -23, 58, 58, 58, 58, 464 -23, -23, -23, -23, -23, -23, -23
516 58, 64, 58, 58, 58, 58, 58, 58, 58, 58,
517 58, 58, 58, 58, 58, 58, 58, -23
518 }, 465 },
519 466
520 { 467 {
521 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, 468 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
522 -24, -24, -24, 58, -24, -24, 58, 58, 58, 58, 469 -24, -24, -24, -24, -24, -24, -24
523 58, 58, 65, 58, 58, 58, 58, 58, 66, 58,
524 58, 58, 58, 58, 58, 58, 58, -24
525 470
526 }, 471 },
527 472
528 { 473 {
529 11, -25, -25, -25, -25, -25, -25, -25, -25, -25, 474 11, 51, 51, 52, 51, 51, 51, 51, 51, 51,
530 -25, -25, -25, 58, -25, -25, 58, 67, 58, 58, 475 51, 51, 51, 51, 51, 51, 51
531 58, 68, 58, 58, 58, 58, 58, 58, 58, 58,
532 58, 58, 58, 58, 58, 58, 58, -25
533 }, 476 },
534 477
535 { 478 {
536 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, 479 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
537 -26, -26, -26, 58, -26, -26, 58, 58, 58, 58, 480 -26, -26, -26, -26, -26, -26, -26
538 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
539 69, 58, 58, 58, 58, 58, 58, -26
540 }, 481 },
541 482
542 { 483 {
543 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, 484 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
544 -27, -27, -27, 58, -27, -27, 58, 58, 58, 58, 485 -27, -27, -27, -27, -27, -27, -27
545
546 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
547 58, 58, 70, 58, 58, 58, 58, -27
548 }, 486 },
549 487
550 { 488 {
551 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, 489 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
552 -28, -28, -28, 58, -28, -28, 58, 71, 58, 58, 490 -28, -28, -28, -28, 53, -28, -28
553 58, 72, 58, 58, 58, 58, 58, 58, 58, 58,
554 58, 58, 58, 58, 58, 58, 58, -28
555 }, 491 },
556 492
557 { 493 {
558 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, 494 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
559 -29, -29, -29, 58, -29, -29, 58, 58, 58, 58, 495 -29, -29, -29, -29, -29, -29, -29
560 58, 73, 58, 58, 58, 58, 58, 58, 58, 74,
561 58, 58, 58, 58, 75, 58, 58, -29
562 496
563 }, 497 },
564 498
565 { 499 {
566 11, -30, -30, -30, -30, -30, -30, -30, -30, -30, 500 11, 54, 54, -30, 54, 54, 54, 54, 54, 54,
567 -30, -30, -30, 58, -30, -30, 58, 58, 58, 58, 501 54, 54, 54, 54, 54, 54, 54
568 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
569 58, 58, 76, 58, 58, 58, 58, -30
570 }, 502 },
571 503
572 { 504 {
573 11, 77, 77, -31, 77, 77, 77, 77, 77, 77, 505 11, -31, -31, -31, -31, -31, -31, 55, -31, -31,
574 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 506 -31, -31, -31, -31, -31, -31, -31
575 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
576 77, 77, 77, 77, 77, 77, 77, 77
577 }, 507 },
578 508
579 { 509 {
580 11, -32, 78, 79, -32, -32, -32, -32, -32, -32, 510 11, -32, -32, -32, -32, -32, -32, -32, -32, -32,
581 -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 511 -32, -32, -32, -32, -32, -32, -32
582
583 -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
584 -32, -32, -32, -32, -32, -32, -32, -32
585 }, 512 },
586 513
587 { 514 {
588 11, 80, -33, -33, 80, 80, 80, 80, 80, 80, 515 11, -33, -33, -33, -33, -33, -33, -33, -33, -33,
589 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 516 -33, -33, -33, -33, -33, -33, -33
590 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
591 80, 80, 80, 80, 80, 80, 80, 80
592 }, 517 },
593 518
594 { 519 {
595 11, 81, 81, 82, 81, -34, 81, 81, -34, 81, 520 11, -34, -34, -34, -34, -34, -34, -34, -34, -34,
596 81, 81, 81, 81, 81, -34, 81, 81, 81, 81, 521 -34, 56, 57, 57, -34, -34, -34
597 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
598 81, 81, 81, 81, 81, 81, 81, 81
599 522
600 }, 523 },
601 524
602 { 525 {
603 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, 526 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
604 -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, 527 -35, 57, 57, 57, -35, -35, -35
605 -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
606 -35, -35, -35, -35, -35, -35, -35, -35
607 }, 528 },
608 529
609 { 530 {
610 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, 531 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
611 -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, 532 -36, -36, -36, -36, -36, -36, -36
612 -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
613 -36, -36, -36, -36, -36, -36, -36, -36
614 }, 533 },
615 534
616 { 535 {
617 11, 83, 83, 84, 83, 83, 83, 83, 83, 83, 536 11, -37, -37, 58, -37, -37, -37, -37, -37, -37,
618 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 537 -37, -37, -37, -37, -37, -37, -37
619
620 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
621 83, 83, 83, 83, 83, 83, 83, 83
622 }, 538 },
623 539
624 { 540 {
625 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, 541 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
626 -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, 542 -38, -38, -38, -38, -38, -38, 59
627 -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
628 -38, -38, -38, -38, -38, -38, -38, -38
629 }, 543 },
630 544
631 { 545 {
632 11, -39, -39, -39, -39, -39, -39, -39, -39, -39, 546 11, -39, 39, 40, -39, -39, 41, -39, -39, -39,
633 -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, 547 -39, -39, -39, -39, -39, -39, -39
634 -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
635 -39, -39, -39, -39, -39, -39, -39, -39
636 548
637 }, 549 },
638 550
639 { 551 {
640 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, 552 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
641 -40, -40, -40, -40, 85, -40, -40, -40, -40, -40, 553 -40, -40, -40, -40, -40, -40, -40
642 -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
643 -40, -40, -40, -40, -40, -40, -40, -40
644 }, 554 },
645 555
646 { 556 {
647 11, -41, -41, -41, -41, -41, -41, -41, -41, -41, 557 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
648 -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, 558 42, 42, 42, 42, 42, 42, 42
649 -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
650 -41, -41, -41, -41, -41, -41, -41, -41
651 }, 559 },
652 560
653 { 561 {
654 11, 86, 86, -42, 86, 86, 86, 86, 86, 86, 562 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
655 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 563 42, 42, 42, 42, 42, 42, 42
656
657 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
658 86, 86, 86, 86, 86, 86, 86, 86
659 }, 564 },
660 565
661 { 566 {
662 11, -43, -43, -43, -43, -43, -43, 87, -43, -43, 567 11, -43, -43, -43, -43, -43, -43, -43, -43, -43,
663 -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, 568 -43, -43, -43, -43, -43, -43, -43
664 -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
665 -43, -43, -43, -43, -43, -43, -43, -43
666 }, 569 },
667 570
668 { 571 {
669 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, 572 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
670 -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, 573 -44, -44, -44, 44, -44, -44, -44
671 -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
672 -44, -44, -44, -44, -44, -44, -44, -44
673 574
674 }, 575 },
675 576
676 { 577 {
677 11, -45, -45, -45, -45, -45, -45, -45, -45, -45, 578 11, 45, 45, -45, 45, 45, 45, 45, 45, 45,
678 -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, 579 45, 45, 45, 45, 45, 45, 45
679 -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
680 -45, -45, -45, -45, -45, -45, -45, -45
681 }, 580 },
682 581
683 { 582 {
684 11, -46, -46, -46, -46, -46, -46, -46, -46, -46, 583 11, -46, 46, 47, -46, -46, -46, -46, -46, -46,
685 -46, 88, 89, 89, -46, -46, 89, 89, 89, 89, 584 -46, -46, -46, -46, -46, -46, -46
686 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
687 89, 89, 89, 89, 89, 89, 89, -46
688 }, 585 },
689 586
690 { 587 {
691 11, -47, -47, -47, -47, -47, -47, -47, -47, -47, 588 11, 48, -47, -47, 48, 48, 48, 48, 48, 48,
692 -47, 89, 89, 89, -47, -47, 89, 89, 89, 89, 589 48, 48, 48, 48, 48, 48, 48
693
694 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
695 89, 89, 89, 89, 89, 89, 89, -47
696 }, 590 },
697 591
698 { 592 {
699 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, 593 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
700 -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, 594 -48, -48, -48, -48, -48, -48, -48
701 -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
702 -48, -48, -48, -48, -48, -48, -48, -48
703 }, 595 },
704 596
705 { 597 {
706 11, -49, -49, 90, -49, -49, -49, -49, -49, -49, 598 11, 49, 49, 50, 49, -49, 49, 49, -49, 49,
707 -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, 599 49, 49, 49, 49, 49, -49, 49
708 -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
709 -49, -49, -49, -49, -49, -49, -49, -49
710 600
711 }, 601 },
712 602
713 { 603 {
714 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, 604 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
715 -50, 89, 89, 89, -50, -50, 89, 89, 89, 89, 605 -50, -50, -50, -50, -50, -50, -50
716 89, 89, 91, 89, 89, 89, 89, 89, 89, 89,
717 89, 89, 89, 89, 89, 89, 89, -50
718 }, 606 },
719 607
720 { 608 {
721 11, -51, -51, -51, -51, -51, -51, -51, -51, -51, 609 11, -51, -51, 52, -51, -51, -51, -51, -51, -51,
722 -51, 89, 89, 89, -51, -51, 89, 89, 89, 89, 610 -51, -51, -51, -51, -51, -51, -51
723 89, 89, 89, 89, 89, 89, 89, 89, 92, 89,
724 89, 89, 89, 89, 89, 89, 89, -51
725 }, 611 },
726 612
727 { 613 {
728 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, 614 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
729 -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, 615 -52, -52, -52, -52, -52, -52, -52
730
731 -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
732 -52, -52, -52, -52, -52, -52, -52, 93
733 }, 616 },
734 617
735 { 618 {
736 11, -53, 53, 54, -53, -53, 55, -53, -53, -53, 619 11, -53, -53, -53, -53, -53, -53, -53, -53, -53,
737 -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, 620 -53, -53, -53, -53, -53, -53, -53
738 -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
739 -53, -53, -53, -53, -53, -53, -53, -53
740 }, 621 },
741 622
742 { 623 {
743 11, -54, -54, -54, -54, -54, -54, -54, -54, -54, 624 11, 54, 54, -54, 54, 54, 54, 54, 54, 54,
744 -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, 625 54, 54, 54, 54, 54, 54, 54
745 -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
746 -54, -54, -54, -54, -54, -54, -54, -54
747 626
748 }, 627 },
749 628
750 { 629 {
751 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, 630 11, -55, -55, -55, -55, -55, -55, -55, -55, -55,
752 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 631 -55, -55, -55, -55, -55, -55, -55
753 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
754 56, 56, 56, 56, 56, 56, 56, 56
755 }, 632 },
756 633
757 { 634 {
758 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, 635 11, -56, -56, -56, -56, -56, -56, -56, -56, -56,
759 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 636 -56, 60, 57, 57, -56, -56, -56
760 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
761 56, 56, 56, 56, 56, 56, 56, 56
762 }, 637 },
763 638
764 { 639 {
765 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, 640 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
766 -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 641 -57, 57, 57, 57, -57, -57, -57
767
768 -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
769 -57, -57, -57, -57, -57, -57, -57, -57
770 }, 642 },
771 643
772 { 644 {
773 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, 645 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
774 -58, -58, -58, 58, -58, -58, 58, 58, 58, 58, 646 -58, -58, -58, -58, -58, -58, -58
775 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
776 58, 58, 58, 58, 58, 58, 58, -58
777 }, 647 },
778 648
779 { 649 {
780 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, 650 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
781 -59, -59, -59, 58, -59, -59, 58, 58, 58, 58, 651 -59, -59, -59, -59, -59, -59, -59
782 58, 58, 58, 58, 58, 58, 58, 58, 58, 94,
783 58, 58, 58, 58, 58, 58, 58, -59
784 652
785 }, 653 },
786 654
787 { 655 {
788 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, 656 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
789 -60, -60, -60, 58, -60, -60, 58, 58, 58, 58, 657 -60, 57, 57, 57, -60, -60, -60
790 58, 58, 58, 58, 58, 58, 58, 58, 58, 95,
791 58, 58, 58, 58, 58, 58, 58, -60
792 },
793
794 {
795 11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
796 -61, -61, -61, 58, -61, -61, 58, 58, 58, 58,
797 58, 58, 58, 58, 58, 58, 58, 96, 97, 58,
798 58, 58, 58, 58, 58, 58, 58, -61
799 },
800
801 {
802 11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
803 -62, -62, -62, 58, -62, -62, 58, 58, 58, 58,
804
805 58, 58, 98, 58, 58, 58, 58, 58, 58, 58,
806 99, 58, 58, 58, 58, 58, 58, -62
807 },
808
809 {
810 11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
811 -63, -63, -63, 58, -63, -63, 58, 100, 58, 58,
812 101, 58, 58, 58, 58, 58, 58, 58, 58, 58,
813 58, 58, 58, 58, 58, 58, 58, -63
814 },
815
816 {
817 11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
818 -64, -64, -64, 58, -64, -64, 58, 58, 58, 58,
819 58, 58, 58, 58, 58, 58, 102, 58, 58, 58,
820 58, 58, 58, 58, 58, 58, 103, -64
821
822 },
823
824 {
825 11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
826 -65, -65, -65, 58, -65, -65, 58, 58, 58, 58,
827 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
828 58, 58, 58, 58, 58, 58, 58, -65
829 },
830
831 {
832 11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
833 -66, -66, -66, 58, -66, -66, 58, 58, 58, 58,
834 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
835 58, 58, 58, 58, 104, 58, 58, -66
836 },
837
838 {
839 11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
840 -67, -67, -67, 58, -67, -67, 58, 58, 58, 58,
841
842 58, 58, 58, 58, 58, 105, 58, 58, 58, 58,
843 58, 58, 58, 58, 58, 58, 58, -67
844 },
845
846 {
847 11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
848 -68, -68, -68, 58, -68, -68, 58, 58, 58, 58,
849 58, 58, 58, 58, 58, 58, 58, 58, 106, 58,
850 58, 58, 58, 58, 58, 58, 58, -68
851 },
852
853 {
854 11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
855 -69, -69, -69, 58, -69, -69, 58, 58, 58, 58,
856 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
857 58, 58, 58, 58, 107, 58, 58, -69
858
859 },
860
861 {
862 11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
863 -70, -70, -70, 58, -70, -70, 58, 58, 58, 58,
864 58, 58, 58, 58, 58, 58, 58, 58, 58, 108,
865 58, 58, 58, 58, 58, 58, 58, -70
866 },
867
868 {
869 11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
870 -71, -71, -71, 58, -71, -71, 58, 58, 58, 58,
871 58, 58, 58, 58, 58, 58, 58, 58, 109, 58,
872 58, 58, 58, 58, 58, 58, 58, -71
873 },
874
875 {
876 11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
877 -72, -72, -72, 58, -72, -72, 58, 58, 58, 58,
878
879 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
880 58, 110, 58, 58, 58, 58, 58, -72
881 },
882
883 {
884 11, -73, -73, -73, -73, -73, -73, -73, -73, -73,
885 -73, -73, -73, 58, -73, -73, 58, 58, 58, 58,
886 58, 58, 58, 58, 58, 58, 111, 58, 58, 58,
887 58, 58, 58, 58, 58, 58, 58, -73
888 },
889
890 {
891 11, -74, -74, -74, -74, -74, -74, -74, -74, -74,
892 -74, -74, -74, 58, -74, -74, 58, 58, 58, 58,
893 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
894 58, 58, 58, 58, 58, 112, 58, -74
895
896 },
897
898 {
899 11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
900 -75, -75, -75, 58, -75, -75, 58, 58, 58, 58,
901 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
902 58, 58, 113, 58, 58, 58, 58, -75
903 },
904
905 {
906 11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
907 -76, -76, -76, 58, -76, -76, 58, 58, 58, 58,
908 58, 58, 58, 58, 58, 114, 58, 58, 58, 58,
909 58, 58, 58, 58, 58, 58, 58, -76
910 },
911
912 {
913 11, 77, 77, -77, 77, 77, 77, 77, 77, 77,
914 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
915
916 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
917 77, 77, 77, 77, 77, 77, 77, 77
918 },
919
920 {
921 11, -78, 78, 79, -78, -78, -78, -78, -78, -78,
922 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
923 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
924 -78, -78, -78, -78, -78, -78, -78, -78
925 },
926
927 {
928 11, 80, -79, -79, 80, 80, 80, 80, 80, 80,
929 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
930 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
931 80, 80, 80, 80, 80, 80, 80, 80
932
933 },
934
935 {
936 11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
937 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
938 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
939 -80, -80, -80, -80, -80, -80, -80, -80
940 },
941
942 {
943 11, 81, 81, 82, 81, -81, 81, 81, -81, 81,
944 81, 81, 81, 81, 81, -81, 81, 81, 81, 81,
945 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
946 81, 81, 81, 81, 81, 81, 81, 81
947 },
948
949 {
950 11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
951 -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
952
953 -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
954 -82, -82, -82, -82, -82, -82, -82, -82
955 },
956
957 {
958 11, -83, -83, 84, -83, -83, -83, -83, -83, -83,
959 -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
960 -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
961 -83, -83, -83, -83, -83, -83, -83, -83
962 },
963
964 {
965 11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
966 -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
967 -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
968 -84, -84, -84, -84, -84, -84, -84, -84
969
970 },
971
972 {
973 11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
974 -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
975 -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
976 -85, -85, -85, -85, -85, -85, -85, -85
977 },
978
979 {
980 11, 86, 86, -86, 86, 86, 86, 86, 86, 86,
981 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
982 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
983 86, 86, 86, 86, 86, 86, 86, 86
984 },
985
986 {
987 11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
988 -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
989
990 -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
991 -87, -87, -87, -87, -87, -87, -87, -87
992 },
993
994 {
995 11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
996 -88, 115, 89, 89, -88, -88, 89, 89, 89, 89,
997 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
998 89, 89, 89, 89, 89, 89, 89, -88
999 },
1000
1001 {
1002 11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
1003 -89, 89, 89, 89, -89, -89, 89, 89, 89, 89,
1004 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1005 89, 89, 89, 89, 89, 89, 89, -89
1006
1007 },
1008
1009 {
1010 11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1011 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1012 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1013 -90, -90, -90, -90, -90, -90, -90, -90
1014 },
1015
1016 {
1017 11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
1018 -91, 89, 89, 89, -91, -91, 89, 89, 89, 89,
1019 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1020 89, 89, 89, 89, 89, 89, 89, -91
1021 },
1022
1023 {
1024 11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
1025 -92, 89, 89, 89, -92, -92, 89, 89, 89, 89,
1026
1027 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1028 89, 89, 89, 89, 89, 89, 89, -92
1029 },
1030
1031 {
1032 11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1033 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1034 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1035 -93, -93, -93, -93, -93, -93, -93, -93
1036 },
1037
1038 {
1039 11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
1040 -94, -94, -94, 58, -94, -94, 58, 58, 58, 58,
1041 58, 58, 58, 58, 58, 58, 116, 58, 58, 58,
1042 58, 58, 58, 58, 58, 58, 58, -94
1043
1044 },
1045
1046 {
1047 11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
1048 -95, -95, -95, 58, -95, -95, 58, 58, 58, 58,
1049 58, 58, 58, 58, 58, 117, 58, 58, 58, 58,
1050 58, 58, 58, 58, 58, 58, 58, -95
1051 },
1052
1053 {
1054 11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
1055 -96, -96, -96, 58, -96, -96, 58, 58, 58, 58,
1056 58, 58, 58, 58, 58, 58, 58, 118, 58, 58,
1057 58, 58, 58, 58, 58, 58, 58, -96
1058 },
1059
1060 {
1061 11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
1062 -97, -97, -97, 58, -97, -97, 58, 58, 58, 58,
1063
1064 58, 58, 119, 58, 58, 58, 58, 58, 58, 58,
1065 58, 58, 58, 58, 58, 58, 58, -97
1066 },
1067
1068 {
1069 11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
1070 -98, -98, -98, 58, -98, -98, 120, 121, 58, 58,
1071 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1072 58, 58, 58, 58, 58, 58, 58, -98
1073 },
1074
1075 {
1076 11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
1077 -99, -99, -99, 58, -99, -99, 58, 58, 58, 58,
1078 58, 122, 58, 58, 58, 58, 58, 58, 58, 58,
1079 58, 58, 58, 58, 58, 58, 58, -99
1080
1081 },
1082
1083 {
1084 11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
1085 -100, -100, -100, 58, -100, -100, 58, 58, 123, 58,
1086 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1087 58, 58, 58, 58, 58, 58, 58, -100
1088 },
1089
1090 {
1091 11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
1092 -101, -101, -101, 58, -101, -101, 58, 58, 58, 124,
1093 58, 58, 58, 58, 58, 125, 58, 126, 58, 58,
1094 58, 58, 58, 58, 58, 58, 58, -101
1095 },
1096
1097 {
1098 11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
1099 -102, -102, -102, 58, -102, -102, 58, 58, 58, 58,
1100
1101 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1102 127, 58, 58, 58, 58, 58, 58, -102
1103 },
1104
1105 {
1106 11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
1107 -103, -103, -103, 58, -103, -103, 58, 58, 58, 58,
1108 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1109 58, 58, 58, 58, 58, 58, 58, -103
1110 },
1111
1112 {
1113 11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
1114 -104, -104, -104, 58, -104, -104, 58, 58, 58, 58,
1115 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1116 58, 58, 58, 58, 58, 58, 58, -104
1117
1118 },
1119
1120 {
1121 11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
1122 -105, -105, -105, 58, -105, -105, 58, 58, 58, 58,
1123 58, 58, 58, 58, 58, 58, 58, 58, 128, 58,
1124 58, 58, 58, 58, 58, 58, 58, -105
1125 },
1126
1127 {
1128 11, -106, -106, -106, -106, -106, -106, -106, -106, -106,
1129 -106, -106, -106, 58, -106, -106, 58, 58, 58, 58,
1130 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1131 58, 58, 58, 58, 58, 129, 58, -106
1132 },
1133
1134 {
1135 11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
1136 -107, -107, -107, 58, -107, -107, 58, 58, 58, 58,
1137
1138 58, 58, 58, 58, 58, 130, 58, 58, 58, 58,
1139 58, 58, 58, 58, 58, 58, 58, -107
1140 },
1141
1142 {
1143 11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
1144 -108, -108, -108, 58, -108, -108, 58, 58, 58, 58,
1145 58, 58, 58, 58, 58, 58, 58, 131, 58, 58,
1146 58, 58, 58, 58, 58, 58, 58, -108
1147 },
1148
1149 {
1150 11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
1151 -109, -109, -109, 58, -109, -109, 58, 58, 58, 58,
1152 58, 58, 58, 132, 58, 58, 58, 58, 58, 58,
1153 58, 58, 58, 58, 58, 58, 58, -109
1154
1155 },
1156
1157 {
1158 11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
1159 -110, -110, -110, 58, -110, -110, 58, 58, 58, 58,
1160 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1161 58, 58, 58, 58, 58, 133, 58, -110
1162 },
1163
1164 {
1165 11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
1166 -111, -111, -111, 58, -111, -111, 58, 58, 58, 58,
1167 58, 134, 58, 58, 58, 58, 58, 58, 58, 58,
1168 58, 58, 58, 58, 58, 58, 58, -111
1169 },
1170
1171 {
1172 11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
1173 -112, -112, -112, 58, -112, -112, 58, 58, 58, 58,
1174
1175 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1176 58, 58, 135, 58, 58, 58, 58, -112
1177 },
1178
1179 {
1180 11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
1181 -113, -113, -113, 58, -113, -113, 58, 58, 58, 58,
1182 58, 58, 58, 58, 58, 136, 58, 58, 58, 58,
1183 58, 58, 58, 58, 58, 58, 58, -113
1184 },
1185
1186 {
1187 11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
1188 -114, -114, -114, 58, -114, -114, 58, 58, 58, 58,
1189 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1190 58, 58, 58, 137, 58, 58, 58, -114
1191
1192 },
1193
1194 {
1195 11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
1196 -115, 89, 89, 89, -115, -115, 89, 89, 89, 89,
1197 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1198 89, 89, 89, 89, 89, 89, 89, -115
1199 },
1200
1201 {
1202 11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
1203 -116, -116, -116, 58, -116, -116, 58, 58, 58, 58,
1204 58, 138, 58, 58, 58, 58, 58, 58, 58, 58,
1205 58, 58, 58, 58, 58, 58, 58, -116
1206 },
1207
1208 {
1209 11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
1210 -117, -117, -117, 58, -117, -117, 58, 58, 58, 139,
1211
1212 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1213 58, 58, 58, 58, 58, 58, 58, -117
1214 },
1215
1216 {
1217 11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
1218 -118, -118, -118, 58, -118, -118, 58, 58, 58, 58,
1219 58, 140, 58, 58, 58, 58, 58, 58, 58, 58,
1220 58, 58, 58, 58, 58, 58, 58, -118
1221 },
1222
1223 {
1224 11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
1225 -119, -119, -119, 58, -119, -119, 58, 58, 58, 58,
1226 58, 58, 58, 58, 58, 141, 58, 58, 58, 58,
1227 58, 58, 58, 58, 58, 58, 58, -119
1228
1229 },
1230
1231 {
1232 11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
1233 -120, -120, -120, 58, -120, -120, 58, 58, 142, 58,
1234 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1235 58, 58, 58, 58, 143, 58, 58, -120
1236 },
1237
1238 {
1239 11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
1240 -121, -121, -121, 58, -121, -121, 58, 58, 58, 58,
1241 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1242 58, 58, 58, 58, 58, 144, 58, -121
1243 },
1244
1245 {
1246 11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
1247 -122, -122, -122, 58, -122, -122, 58, 58, 58, 58,
1248
1249 58, 58, 58, 58, 58, 58, 58, 58, 145, 58,
1250 58, 58, 58, 58, 58, 58, 58, -122
1251 },
1252
1253 {
1254 11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
1255 -123, -123, -123, 58, -123, -123, 58, 58, 58, 58,
1256 58, 58, 58, 58, 58, 58, 146, 58, 58, 58,
1257 58, 58, 58, 58, 58, 58, 58, -123
1258 },
1259
1260 {
1261 11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
1262 -124, -124, -124, 58, -124, -124, 58, 58, 58, 58,
1263 58, 58, 58, 58, 147, 58, 58, 58, 58, 58,
1264 58, 58, 58, 58, 58, 58, 58, -124
1265
1266 },
1267
1268 {
1269 11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
1270 -125, -125, -125, 58, -125, -125, 58, 58, 58, 58,
1271 58, 58, 148, 58, 58, 58, 58, 58, 58, 58,
1272 58, 58, 58, 58, 58, 58, 58, -125
1273 },
1274
1275 {
1276 11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
1277 -126, -126, -126, 58, -126, -126, 58, 58, 58, 58,
1278 58, 149, 58, 58, 58, 58, 58, 58, 58, 58,
1279 58, 58, 58, 58, 58, 58, 58, -126
1280 },
1281
1282 {
1283 11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
1284 -127, -127, -127, 58, -127, -127, 58, 58, 58, 58,
1285
1286 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1287 58, 58, 58, 58, 58, 58, 58, -127
1288 },
1289
1290 {
1291 11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
1292 -128, -128, -128, 58, -128, -128, 58, 58, 58, 58,
1293 58, 58, 58, 58, 58, 58, 58, 150, 58, 58,
1294 58, 58, 58, 58, 58, 58, 58, -128
1295 },
1296
1297 {
1298 11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
1299 -129, -129, -129, 58, -129, -129, 58, 58, 58, 151,
1300 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1301 58, 58, 58, 58, 58, 58, 58, -129
1302
1303 },
1304
1305 {
1306 11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
1307 -130, -130, -130, 58, -130, -130, 58, 58, 58, 58,
1308 58, 58, 58, 58, 58, 58, 58, 58, 58, 152,
1309 58, 58, 58, 58, 58, 58, 58, -130
1310 },
1311
1312 {
1313 11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
1314 -131, -131, -131, 58, -131, -131, 58, 58, 58, 58,
1315 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1316 153, 58, 58, 58, 58, 58, 58, -131
1317 },
1318
1319 {
1320 11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
1321 -132, -132, -132, 58, -132, -132, 58, 58, 58, 58,
1322
1323 58, 154, 58, 58, 58, 58, 58, 58, 58, 58,
1324 58, 58, 58, 58, 58, 58, 58, -132
1325 },
1326
1327 {
1328 11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
1329 -133, -133, -133, 58, -133, -133, 58, 58, 58, 58,
1330 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
1331 58, 58, 58, 58, 58, 58, 58, -133
1332 },
1333
1334 {
1335 11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
1336 -134, -134, -134, 58, -134, -134, 58, 58, 58, 156,
1337 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1338 58, 58, 58, 58, 58, 58, 58, -134
1339
1340 },
1341
1342 {
1343 11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
1344 -135, -135, -135, 58, -135, -135, 58, 58, 58, 157,
1345 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1346 58, 58, 58, 58, 58, 58, 58, -135
1347 },
1348
1349 {
1350 11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
1351 -136, -136, -136, 58, -136, -136, 58, 58, 58, 58,
1352 58, 58, 58, 58, 58, 58, 58, 58, 158, 58,
1353 58, 58, 58, 58, 58, 58, 58, -136
1354 },
1355
1356 {
1357 11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
1358 -137, -137, -137, 58, -137, -137, 58, 58, 58, 58,
1359
1360 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1361 58, 58, 58, 58, 159, 58, 58, -137
1362 },
1363
1364 {
1365 11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
1366 -138, -138, -138, 58, -138, -138, 58, 160, 58, 58,
1367 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1368 58, 58, 58, 58, 58, 58, 58, -138
1369 },
1370
1371 {
1372 11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
1373 -139, -139, -139, 58, -139, -139, 58, 58, 58, 58,
1374 58, 161, 58, 58, 58, 58, 58, 58, 58, 58,
1375 58, 58, 58, 58, 58, 58, 58, -139
1376
1377 },
1378
1379 {
1380 11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
1381 -140, -140, -140, 58, -140, -140, 58, 58, 58, 58,
1382 58, 58, 58, 58, 58, 58, 58, 58, 162, 58,
1383 58, 58, 58, 58, 58, 58, 58, -140
1384 },
1385
1386 {
1387 11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
1388 -141, -141, -141, 58, -141, -141, 58, 58, 58, 58,
1389 58, 58, 58, 163, 58, 58, 58, 58, 58, 58,
1390 58, 58, 58, 58, 58, 58, 58, -141
1391 },
1392
1393 {
1394 11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
1395 -142, -142, -142, 58, -142, -142, 58, 58, 58, 58,
1396
1397 58, 58, 58, 58, 58, 58, 58, 58, 58, 164,
1398 58, 58, 58, 58, 58, 58, 58, -142
1399 },
1400
1401 {
1402 11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
1403 -143, -143, -143, 58, -143, -143, 58, 58, 58, 58,
1404 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1405 58, 58, 165, 58, 58, 58, 58, -143
1406 },
1407
1408 {
1409 11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
1410 -144, -144, -144, 58, -144, -144, 58, 58, 58, 58,
1411 58, 58, 58, 58, 58, 58, 166, 58, 58, 58,
1412 58, 58, 58, 58, 58, 58, 58, -144
1413
1414 },
1415
1416 {
1417 11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
1418 -145, -145, -145, 58, -145, -145, 58, 58, 58, 58,
1419 167, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1420 58, 58, 58, 58, 58, 58, 58, -145
1421 },
1422
1423 {
1424 11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
1425 -146, -146, -146, 58, -146, -146, 58, 58, 58, 58,
1426 58, 168, 58, 58, 58, 58, 58, 58, 58, 58,
1427 58, 58, 58, 58, 58, 58, 58, -146
1428 },
1429
1430 {
1431 11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
1432 -147, -147, -147, 58, -147, -147, 58, 58, 58, 58,
1433
1434 58, 58, 58, 58, 58, 58, 58, 58, 58, 169,
1435 58, 58, 58, 58, 58, 58, 58, -147
1436 },
1437
1438 {
1439 11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
1440 -148, -148, -148, 58, -148, -148, 58, 58, 58, 58,
1441 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1442 58, 58, 58, 58, 58, 58, 58, -148
1443 },
1444
1445 {
1446 11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
1447 -149, -149, -149, 58, -149, -149, 58, 58, 58, 58,
1448 58, 58, 58, 58, 58, 58, 58, 58, 170, 58,
1449 58, 58, 58, 58, 58, 58, 58, -149
1450
1451 },
1452
1453 {
1454 11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
1455 -150, -150, -150, 58, -150, -150, 58, 58, 58, 58,
1456 58, 171, 58, 58, 58, 58, 58, 58, 58, 58,
1457 58, 58, 58, 58, 58, 58, 58, -150
1458 },
1459
1460 {
1461 11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
1462 -151, -151, -151, 58, -151, -151, 58, 58, 58, 58,
1463 58, 58, 58, 58, 58, 58, 58, 58, 58, 172,
1464 58, 58, 58, 58, 58, 58, 58, -151
1465 },
1466
1467 {
1468 11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
1469 -152, -152, -152, 58, -152, -152, 58, 58, 58, 58,
1470
1471 58, 58, 58, 58, 58, 58, 58, 58, 173, 58,
1472 58, 58, 58, 58, 58, 58, 58, -152
1473 },
1474
1475 {
1476 11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
1477 -153, -153, -153, 58, -153, -153, 58, 58, 58, 58,
1478 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1479 58, 58, 58, 58, 174, 58, 58, -153
1480 },
1481
1482 {
1483 11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
1484 -154, -154, -154, 58, -154, -154, 58, 58, 58, 58,
1485 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1486 58, 58, 58, 58, 58, 58, 58, -154
1487
1488 },
1489
1490 {
1491 11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
1492 -155, -155, -155, 58, -155, -155, 58, 58, 58, 58,
1493 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1494 58, 58, 175, 58, 58, 58, 58, -155
1495 },
1496
1497 {
1498 11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
1499 -156, -156, -156, 58, -156, -156, 58, 58, 58, 58,
1500 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1501 58, 58, 58, 58, 176, 58, 58, -156
1502 },
1503
1504 {
1505 11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
1506 -157, -157, -157, 58, -157, -157, 58, 58, 58, 58,
1507
1508 58, 177, 58, 58, 58, 58, 58, 58, 58, 58,
1509 58, 58, 58, 58, 58, 58, 58, -157
1510 },
1511
1512 {
1513 11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
1514 -158, -158, -158, 58, -158, -158, 58, 58, 58, 58,
1515 58, 58, 58, 178, 58, 58, 58, 58, 58, 58,
1516 58, 58, 58, 58, 58, 58, 58, -158
1517 },
1518
1519 {
1520 11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
1521 -159, -159, -159, 58, -159, -159, 58, 179, 58, 58,
1522 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1523 58, 58, 58, 58, 58, 58, 58, -159
1524
1525 },
1526
1527 {
1528 11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
1529 -160, -160, -160, 58, -160, -160, 58, 58, 58, 58,
1530 58, 58, 58, 58, 58, 58, 58, 58, 180, 58,
1531 58, 58, 58, 58, 58, 58, 58, -160
1532 },
1533
1534 {
1535 11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
1536 -161, -161, -161, 58, -161, -161, 58, 58, 58, 58,
1537 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1538 58, 58, 58, 58, 58, 58, 58, -161
1539 },
1540
1541 {
1542 11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
1543 -162, -162, -162, 58, -162, -162, 58, 58, 58, 58,
1544
1545 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1546 58, 58, 58, 58, 181, 58, 58, -162
1547 },
1548
1549 {
1550 11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
1551 -163, -163, -163, 58, -163, -163, 58, 58, 58, 58,
1552 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1553 58, 58, 58, 58, 58, 58, 58, -163
1554 },
1555
1556 {
1557 11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
1558 -164, -164, -164, 58, -164, -164, 58, 58, 58, 58,
1559 58, 58, 58, 58, 58, 58, 58, 58, 58, 182,
1560 58, 58, 58, 58, 58, 58, 58, -164
1561
1562 },
1563
1564 {
1565 11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
1566 -165, -165, -165, 58, -165, -165, 58, 58, 58, 58,
1567 58, 58, 58, 58, 58, 183, 58, 58, 58, 58,
1568 58, 58, 58, 58, 58, 58, 58, -165
1569 },
1570
1571 {
1572 11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
1573 -166, -166, -166, 58, -166, -166, 58, 58, 58, 58,
1574 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1575 58, 58, 58, 58, 184, 58, 58, -166
1576 },
1577
1578 {
1579 11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
1580 -167, -167, -167, 58, -167, -167, 58, 58, 58, 58,
1581
1582 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1583 58, 58, 58, 185, 58, 58, 58, -167
1584 },
1585
1586 {
1587 11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
1588 -168, -168, -168, 58, -168, -168, 58, 58, 58, 58,
1589 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1590 58, 58, 58, 58, 58, 58, 58, -168
1591 },
1592
1593 {
1594 11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
1595 -169, -169, -169, 58, -169, -169, 58, 58, 58, 58,
1596 58, 58, 58, 58, 58, 186, 58, 58, 58, 58,
1597 58, 58, 58, 58, 58, 58, 58, -169
1598
1599 },
1600
1601 {
1602 11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
1603 -170, -170, -170, 58, -170, -170, 58, 58, 58, 58,
1604 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1605 58, 58, 58, 58, 58, 187, 58, -170
1606 },
1607
1608 {
1609 11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
1610 -171, -171, -171, 58, -171, -171, 58, 58, 58, 58,
1611 58, 58, 58, 58, 58, 58, 58, 58, 188, 58,
1612 58, 58, 58, 58, 58, 58, 58, -171
1613 },
1614
1615 {
1616 11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
1617 -172, -172, -172, 58, -172, -172, 58, 58, 58, 58,
1618
1619 58, 58, 58, 58, 58, 58, 58, 58, 189, 58,
1620 58, 58, 58, 58, 58, 58, 58, -172
1621 },
1622
1623 {
1624 11, -173, -173, -173, -173, -173, -173, -173, -173, -173,
1625 -173, -173, -173, 58, -173, -173, 58, 190, 58, 58,
1626 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1627 58, 58, 58, 58, 58, 58, 58, -173
1628 },
1629
1630 {
1631 11, -174, -174, -174, -174, -174, -174, -174, -174, -174,
1632 -174, -174, -174, 58, -174, -174, 58, 58, 58, 58,
1633 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1634 58, 58, 58, 58, 58, 58, 58, -174
1635
1636 },
1637
1638 {
1639 11, -175, -175, -175, -175, -175, -175, -175, -175, -175,
1640 -175, -175, -175, 58, -175, -175, 58, 58, 58, 58,
1641 58, 191, 58, 58, 58, 58, 58, 58, 58, 58,
1642 58, 58, 58, 58, 58, 58, 58, -175
1643 },
1644
1645 {
1646 11, -176, -176, -176, -176, -176, -176, -176, -176, -176,
1647 -176, -176, -176, 58, -176, -176, 58, 58, 58, 58,
1648 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1649 58, 58, 58, 58, 58, 58, 58, -176
1650 },
1651
1652 {
1653 11, -177, -177, -177, -177, -177, -177, -177, -177, -177,
1654 -177, -177, -177, 58, -177, -177, 58, 58, 58, 58,
1655
1656 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1657 58, 58, 58, 58, 58, 58, 58, -177
1658 },
1659
1660 {
1661 11, -178, -178, -178, -178, -178, -178, -178, -178, -178,
1662 -178, -178, -178, 58, -178, -178, 58, 58, 58, 58,
1663 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1664 58, 58, 58, 58, 58, 58, 58, -178
1665 },
1666
1667 {
1668 11, -179, -179, -179, -179, -179, -179, -179, -179, -179,
1669 -179, -179, -179, 58, -179, -179, 58, 58, 58, 58,
1670 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1671 58, 58, 58, 58, 192, 58, 58, -179
1672
1673 },
1674
1675 {
1676 11, -180, -180, -180, -180, -180, -180, -180, -180, -180,
1677 -180, -180, -180, 58, -180, -180, 58, 58, 58, 58,
1678 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1679 58, 58, 58, 58, 58, 58, 58, -180
1680 },
1681
1682 {
1683 11, -181, -181, -181, -181, -181, -181, -181, -181, -181,
1684 -181, -181, -181, 58, -181, -181, 58, 58, 58, 58,
1685 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1686 58, 58, 58, 58, 58, 58, 58, -181
1687 },
1688
1689 {
1690 11, -182, -182, -182, -182, -182, -182, -182, -182, -182,
1691 -182, -182, -182, 58, -182, -182, 58, 58, 58, 58,
1692
1693 58, 58, 58, 58, 58, 58, 193, 58, 58, 58,
1694 58, 58, 58, 58, 58, 58, 58, -182
1695 },
1696
1697 {
1698 11, -183, -183, -183, -183, -183, -183, -183, -183, -183,
1699 -183, -183, -183, 58, -183, -183, 58, 58, 58, 58,
1700 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1701 58, 58, 58, 194, 58, 58, 58, -183
1702 },
1703
1704 {
1705 11, -184, -184, -184, -184, -184, -184, -184, -184, -184,
1706 -184, -184, -184, 58, -184, -184, 58, 58, 58, 58,
1707 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1708 58, 58, 58, 58, 58, 58, 58, -184
1709
1710 },
1711
1712 {
1713 11, -185, -185, -185, -185, -185, -185, -185, -185, -185,
1714 -185, -185, -185, 58, -185, -185, 58, 58, 58, 58,
1715 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1716 58, 58, 58, 58, 58, 58, 58, -185
1717 },
1718
1719 {
1720 11, -186, -186, -186, -186, -186, -186, -186, -186, -186,
1721 -186, -186, -186, 58, -186, -186, 58, 58, 58, 195,
1722 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1723 58, 58, 58, 58, 58, 58, 58, -186
1724 },
1725
1726 {
1727 11, -187, -187, -187, -187, -187, -187, -187, -187, -187,
1728 -187, -187, -187, 58, -187, -187, 58, 58, 58, 58,
1729
1730 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1731 58, 58, 58, 58, 58, 58, 58, -187
1732 },
1733
1734 {
1735 11, -188, -188, -188, -188, -188, -188, -188, -188, -188,
1736 -188, -188, -188, 58, -188, -188, 58, 58, 58, 58,
1737 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1738 58, 58, 58, 58, 58, 196, 58, -188
1739 },
1740
1741 {
1742 11, -189, -189, -189, -189, -189, -189, -189, -189, -189,
1743 -189, -189, -189, 58, -189, -189, 58, 58, 58, 58,
1744 58, 58, 197, 58, 58, 58, 58, 58, 58, 58,
1745 58, 58, 58, 58, 58, 58, 58, -189
1746
1747 },
1748
1749 {
1750 11, -190, -190, -190, -190, -190, -190, -190, -190, -190,
1751 -190, -190, -190, 58, -190, -190, 58, 58, 58, 58,
1752 58, 58, 58, 58, 58, 58, 198, 58, 58, 58,
1753 58, 58, 58, 58, 58, 58, 58, -190
1754 },
1755
1756 {
1757 11, -191, -191, -191, -191, -191, -191, -191, -191, -191,
1758 -191, -191, -191, 58, -191, -191, 58, 58, 58, 58,
1759 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1760 58, 58, 58, 199, 58, 58, 58, -191
1761 },
1762
1763 {
1764 11, -192, -192, -192, -192, -192, -192, -192, -192, -192,
1765 -192, -192, -192, 58, -192, -192, 58, 58, 58, 58,
1766
1767 58, 200, 58, 58, 58, 58, 58, 58, 58, 58,
1768 58, 58, 58, 58, 58, 58, 58, -192
1769 },
1770
1771 {
1772 11, -193, -193, -193, -193, -193, -193, -193, -193, -193,
1773 -193, -193, -193, 58, -193, -193, 58, 58, 58, 58,
1774 58, 201, 58, 58, 58, 58, 58, 58, 58, 58,
1775 58, 58, 58, 58, 58, 58, 58, -193
1776 },
1777
1778 {
1779 11, -194, -194, -194, -194, -194, -194, -194, -194, -194,
1780 -194, -194, -194, 58, -194, -194, 58, 58, 58, 58,
1781 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1782 58, 58, 58, 58, 202, 58, 58, -194
1783
1784 },
1785
1786 {
1787 11, -195, -195, -195, -195, -195, -195, -195, -195, -195,
1788 -195, -195, -195, 58, -195, -195, 58, 58, 58, 58,
1789 58, 203, 58, 58, 58, 58, 58, 58, 58, 58,
1790 58, 58, 58, 58, 58, 58, 58, -195
1791 },
1792
1793 {
1794 11, -196, -196, -196, -196, -196, -196, -196, -196, -196,
1795 -196, -196, -196, 58, -196, -196, 58, 58, 58, 58,
1796 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1797 58, 58, 58, 58, 58, 58, 58, -196
1798 },
1799
1800 {
1801 11, -197, -197, -197, -197, -197, -197, -197, -197, -197,
1802 -197, -197, -197, 58, -197, -197, 58, 58, 58, 58,
1803
1804 58, 58, 58, 58, 58, 204, 58, 58, 58, 58,
1805 58, 58, 58, 58, 58, 58, 58, -197
1806 },
1807
1808 {
1809 11, -198, -198, -198, -198, -198, -198, -198, -198, -198,
1810 -198, -198, -198, 58, -198, -198, 58, 58, 58, 58,
1811 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1812 58, 58, 58, 58, 58, 58, 58, -198
1813 },
1814
1815 {
1816 11, -199, -199, -199, -199, -199, -199, -199, -199, -199,
1817 -199, -199, -199, 58, -199, -199, 58, 58, 58, 58,
1818 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1819 58, 58, 58, 58, 58, 58, 58, -199
1820
1821 },
1822
1823 {
1824 11, -200, -200, -200, -200, -200, -200, -200, -200, -200,
1825 -200, -200, -200, 58, -200, -200, 58, 58, 58, 58,
1826 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1827 58, 58, 58, 58, 58, 58, 58, -200
1828 },
1829
1830 {
1831 11, -201, -201, -201, -201, -201, -201, -201, -201, -201,
1832 -201, -201, -201, 58, -201, -201, 58, 205, 58, 58,
1833 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1834 58, 58, 58, 58, 58, 58, 58, -201
1835 },
1836
1837 {
1838 11, -202, -202, -202, -202, -202, -202, -202, -202, -202,
1839 -202, -202, -202, 58, -202, -202, 58, 206, 58, 58,
1840
1841 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1842 58, 58, 58, 58, 58, 58, 58, -202
1843 },
1844
1845 {
1846 11, -203, -203, -203, -203, -203, -203, -203, -203, -203,
1847 -203, -203, -203, 58, -203, -203, 58, 58, 58, 58,
1848 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1849 58, 58, 58, 58, 58, 58, 58, -203
1850 },
1851
1852 {
1853 11, -204, -204, -204, -204, -204, -204, -204, -204, -204,
1854 -204, -204, -204, 58, -204, -204, 58, 58, 58, 58,
1855 58, 58, 58, 207, 58, 58, 58, 58, 58, 58,
1856 58, 58, 58, 58, 58, 58, 58, -204
1857
1858 },
1859
1860 {
1861 11, -205, -205, -205, -205, -205, -205, -205, -205, -205,
1862 -205, -205, -205, 58, -205, -205, 58, 58, 58, 58,
1863 58, 58, 58, 58, 58, 58, 58, 58, 208, 58,
1864 58, 58, 58, 58, 58, 58, 58, -205
1865 },
1866
1867 {
1868 11, -206, -206, -206, -206, -206, -206, -206, -206, -206,
1869 -206, -206, -206, 58, -206, -206, 58, 58, 58, 58,
1870 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1871 58, 58, 58, 58, 209, 58, 58, -206
1872 },
1873
1874 {
1875 11, -207, -207, -207, -207, -207, -207, -207, -207, -207,
1876 -207, -207, -207, 58, -207, -207, 58, 58, 58, 58,
1877
1878 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1879 58, 58, 58, 58, 58, 58, 58, -207
1880 },
1881
1882 {
1883 11, -208, -208, -208, -208, -208, -208, -208, -208, -208,
1884 -208, -208, -208, 58, -208, -208, 58, 58, 58, 58,
1885 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1886 58, 58, 58, 58, 58, 58, 58, -208
1887 },
1888
1889 {
1890 11, -209, -209, -209, -209, -209, -209, -209, -209, -209,
1891 -209, -209, -209, 58, -209, -209, 58, 58, 58, 58,
1892 58, 210, 58, 58, 58, 58, 58, 58, 58, 58,
1893 58, 58, 58, 58, 58, 58, 58, -209
1894
1895 },
1896
1897 {
1898 11, -210, -210, -210, -210, -210, -210, -210, -210, -210,
1899 -210, -210, -210, 58, -210, -210, 58, 58, 58, 58,
1900 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1901 58, 58, 58, 58, 58, 58, 58, -210
1902 }, 658 },
1903 659
1904 } ; 660 } ;
@@ -1918,8 +674,8 @@ static void yy_fatal_error (yyconst char msg[] );
1918 *yy_cp = '\0'; \ 674 *yy_cp = '\0'; \
1919 (yy_c_buf_p) = yy_cp; 675 (yy_c_buf_p) = yy_cp;
1920 676
1921#define YY_NUM_RULES 64 677#define YY_NUM_RULES 33
1922#define YY_END_OF_BUFFER 65 678#define YY_END_OF_BUFFER 34
1923/* This struct is not used in this scanner, 679/* This struct is not used in this scanner,
1924 but its presence is necessary. */ 680 but its presence is necessary. */
1925struct yy_trans_info 681struct yy_trans_info
@@ -1927,31 +683,14 @@ struct yy_trans_info
1927 flex_int32_t yy_verify; 683 flex_int32_t yy_verify;
1928 flex_int32_t yy_nxt; 684 flex_int32_t yy_nxt;
1929 }; 685 };
1930static yyconst flex_int16_t yy_accept[211] = 686static yyconst flex_int16_t yy_accept[61] =
1931 { 0, 687 { 0,
1932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 688 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1933 65, 5, 4, 3, 2, 36, 37, 35, 35, 35, 689 34, 5, 4, 2, 3, 7, 8, 6, 32, 29,
1934 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 690 31, 24, 28, 27, 26, 22, 17, 13, 16, 20,
1935 63, 60, 62, 55, 59, 58, 57, 53, 48, 42, 691 22, 11, 12, 19, 19, 14, 22, 22, 4, 2,
1936 47, 51, 53, 40, 41, 50, 50, 43, 53, 50, 692 3, 3, 1, 6, 32, 29, 31, 30, 24, 23,
1937 50, 53, 4, 3, 2, 2, 1, 35, 35, 35, 693 26, 25, 15, 20, 9, 19, 19, 21, 10, 18
1938 35, 35, 35, 35, 16, 35, 35, 35, 35, 35,
1939 35, 35, 35, 35, 35, 35, 63, 60, 62, 61,
1940 55, 54, 57, 56, 44, 51, 38, 50, 50, 52,
1941 45, 46, 39, 35, 35, 35, 35, 35, 35, 35,
1942
1943 35, 35, 30, 29, 35, 35, 35, 35, 35, 35,
1944 35, 35, 35, 35, 49, 25, 35, 35, 35, 35,
1945 35, 35, 35, 35, 35, 35, 15, 35, 7, 35,
1946 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
1947 35, 35, 35, 35, 35, 35, 35, 17, 35, 35,
1948 35, 35, 35, 34, 35, 35, 35, 35, 35, 35,
1949 10, 35, 13, 35, 35, 35, 35, 33, 35, 35,
1950 35, 35, 35, 22, 35, 32, 9, 31, 35, 26,
1951 12, 35, 35, 21, 18, 35, 8, 35, 35, 35,
1952 35, 35, 27, 35, 35, 6, 35, 20, 19, 23,
1953
1954 35, 35, 11, 35, 35, 35, 14, 28, 35, 24
1955 } ; 694 } ;
1956 695
1957static yyconst flex_int32_t yy_ec[256] = 696static yyconst flex_int32_t yy_ec[256] =
@@ -1965,11 +704,11 @@ static yyconst flex_int32_t yy_ec[256] =
1965 14, 1, 1, 1, 13, 13, 13, 13, 13, 13, 704 14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
1966 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 705 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1967 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 706 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1968 1, 15, 1, 1, 16, 1, 17, 18, 19, 20, 707 1, 15, 1, 1, 13, 1, 13, 13, 13, 13,
1969 708
1970 21, 22, 23, 24, 25, 13, 13, 26, 27, 28, 709 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1971 29, 30, 31, 32, 33, 34, 35, 13, 13, 36, 710 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1972 13, 13, 1, 37, 1, 1, 1, 1, 1, 1, 711 13, 13, 1, 16, 1, 1, 1, 1, 1, 1,
1973 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 712 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1974 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 713 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1975 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 714 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -2014,8 +753,12 @@ char *zconftext;
2014 753
2015#define START_STRSIZE 16 754#define START_STRSIZE 16
2016 755
2017char *text; 756static struct {
2018static char *text_ptr; 757 struct file *file;
758 int lineno;
759} current_pos;
760
761static char *text;
2019static int text_size, text_asize; 762static int text_size, text_asize;
2020 763
2021struct buffer { 764struct buffer {
@@ -2028,29 +771,28 @@ struct buffer *current_buf;
2028static int last_ts, first_ts; 771static int last_ts, first_ts;
2029 772
2030static void zconf_endhelp(void); 773static void zconf_endhelp(void);
2031static struct buffer *zconf_endfile(void); 774static void zconf_endfile(void);
2032 775
2033void new_string(void) 776void new_string(void)
2034{ 777{
2035 text = malloc(START_STRSIZE); 778 text = malloc(START_STRSIZE);
2036 text_asize = START_STRSIZE; 779 text_asize = START_STRSIZE;
2037 text_ptr = text;
2038 text_size = 0; 780 text_size = 0;
2039 *text_ptr = 0; 781 *text = 0;
2040} 782}
2041 783
2042void append_string(const char *str, int size) 784void append_string(const char *str, int size)
2043{ 785{
2044 int new_size = text_size + size + 1; 786 int new_size = text_size + size + 1;
2045 if (new_size > text_asize) { 787 if (new_size > text_asize) {
788 new_size += START_STRSIZE - 1;
789 new_size &= -START_STRSIZE;
2046 text = realloc(text, new_size); 790 text = realloc(text, new_size);
2047 text_asize = new_size; 791 text_asize = new_size;
2048 text_ptr = text + text_size;
2049 } 792 }
2050 memcpy(text_ptr, str, size); 793 memcpy(text + text_size, str, size);
2051 text_ptr += size;
2052 text_size += size; 794 text_size += size;
2053 *text_ptr = 0; 795 text[text_size] = 0;
2054} 796}
2055 797
2056void alloc_string(const char *str, int size) 798void alloc_string(const char *str, int size)
@@ -2066,11 +808,13 @@ void alloc_string(const char *str, int size)
2066#define STRING 3 808#define STRING 3
2067#define PARAM 4 809#define PARAM 4
2068 810
811#ifndef YY_NO_UNISTD_H
2069/* Special case for "unistd.h", since it is non-ANSI. We include it way 812/* Special case for "unistd.h", since it is non-ANSI. We include it way
2070 * down here because we want the user's section 1 to have been scanned first. 813 * down here because we want the user's section 1 to have been scanned first.
2071 * The user has a chance to override it with an option. 814 * The user has a chance to override it with an option.
2072 */ 815 */
2073#include <unistd.h> 816#include <unistd.h>
817#endif
2074 818
2075#ifndef YY_EXTRA_TYPE 819#ifndef YY_EXTRA_TYPE
2076#define YY_EXTRA_TYPE void * 820#define YY_EXTRA_TYPE void *
@@ -2254,17 +998,17 @@ do_action: /* This label is used only to access EOF actions. */
2254 { /* beginning of action switch */ 998 { /* beginning of action switch */
2255case 1: 999case 1:
2256/* rule 1 can match eol */ 1000/* rule 1 can match eol */
2257YY_RULE_SETUP
2258current_file->lineno++;
2259 YY_BREAK
2260case 2: 1001case 2:
1002/* rule 2 can match eol */
2261YY_RULE_SETUP 1003YY_RULE_SETUP
2262 1004{
1005 current_file->lineno++;
1006 return T_EOL;
1007}
2263 YY_BREAK 1008 YY_BREAK
2264case 3: 1009case 3:
2265/* rule 3 can match eol */
2266YY_RULE_SETUP 1010YY_RULE_SETUP
2267current_file->lineno++; return T_EOL; 1011
2268 YY_BREAK 1012 YY_BREAK
2269case 4: 1013case 4:
2270YY_RULE_SETUP 1014YY_RULE_SETUP
@@ -2282,175 +1026,63 @@ YY_RULE_SETUP
2282 1026
2283case 6: 1027case 6:
2284YY_RULE_SETUP 1028YY_RULE_SETUP
2285BEGIN(PARAM); return T_MAINMENU;
2286 YY_BREAK
2287case 7:
2288YY_RULE_SETUP
2289BEGIN(PARAM); return T_MENU;
2290 YY_BREAK
2291case 8:
2292YY_RULE_SETUP
2293BEGIN(PARAM); return T_ENDMENU;
2294 YY_BREAK
2295case 9:
2296YY_RULE_SETUP
2297BEGIN(PARAM); return T_SOURCE;
2298 YY_BREAK
2299case 10:
2300YY_RULE_SETUP
2301BEGIN(PARAM); return T_CHOICE;
2302 YY_BREAK
2303case 11:
2304YY_RULE_SETUP
2305BEGIN(PARAM); return T_ENDCHOICE;
2306 YY_BREAK
2307case 12:
2308YY_RULE_SETUP
2309BEGIN(PARAM); return T_COMMENT;
2310 YY_BREAK
2311case 13:
2312YY_RULE_SETUP
2313BEGIN(PARAM); return T_CONFIG;
2314 YY_BREAK
2315case 14:
2316YY_RULE_SETUP
2317BEGIN(PARAM); return T_MENUCONFIG;
2318 YY_BREAK
2319case 15:
2320YY_RULE_SETUP
2321BEGIN(PARAM); return T_HELP;
2322 YY_BREAK
2323case 16:
2324YY_RULE_SETUP
2325BEGIN(PARAM); return T_IF;
2326 YY_BREAK
2327case 17:
2328YY_RULE_SETUP
2329BEGIN(PARAM); return T_ENDIF;
2330 YY_BREAK
2331case 18:
2332YY_RULE_SETUP
2333BEGIN(PARAM); return T_DEPENDS;
2334 YY_BREAK
2335case 19:
2336YY_RULE_SETUP
2337BEGIN(PARAM); return T_REQUIRES;
2338 YY_BREAK
2339case 20:
2340YY_RULE_SETUP
2341BEGIN(PARAM); return T_OPTIONAL;
2342 YY_BREAK
2343case 21:
2344YY_RULE_SETUP
2345BEGIN(PARAM); return T_DEFAULT;
2346 YY_BREAK
2347case 22:
2348YY_RULE_SETUP
2349BEGIN(PARAM); return T_PROMPT;
2350 YY_BREAK
2351case 23:
2352YY_RULE_SETUP
2353BEGIN(PARAM); return T_TRISTATE;
2354 YY_BREAK
2355case 24:
2356YY_RULE_SETUP
2357BEGIN(PARAM); return T_DEF_TRISTATE;
2358 YY_BREAK
2359case 25:
2360YY_RULE_SETUP
2361BEGIN(PARAM); return T_BOOLEAN;
2362 YY_BREAK
2363case 26:
2364YY_RULE_SETUP
2365BEGIN(PARAM); return T_BOOLEAN;
2366 YY_BREAK
2367case 27:
2368YY_RULE_SETUP
2369BEGIN(PARAM); return T_DEF_BOOLEAN;
2370 YY_BREAK
2371case 28:
2372YY_RULE_SETUP
2373BEGIN(PARAM); return T_DEF_BOOLEAN;
2374 YY_BREAK
2375case 29:
2376YY_RULE_SETUP
2377BEGIN(PARAM); return T_INT;
2378 YY_BREAK
2379case 30:
2380YY_RULE_SETUP
2381BEGIN(PARAM); return T_HEX;
2382 YY_BREAK
2383case 31:
2384YY_RULE_SETUP
2385BEGIN(PARAM); return T_STRING;
2386 YY_BREAK
2387case 32:
2388YY_RULE_SETUP
2389BEGIN(PARAM); return T_SELECT;
2390 YY_BREAK
2391case 33:
2392YY_RULE_SETUP
2393BEGIN(PARAM); return T_SELECT;
2394 YY_BREAK
2395case 34:
2396YY_RULE_SETUP
2397BEGIN(PARAM); return T_RANGE;
2398 YY_BREAK
2399case 35:
2400YY_RULE_SETUP
2401{ 1029{
1030 struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
1031 BEGIN(PARAM);
1032 current_pos.file = current_file;
1033 current_pos.lineno = current_file->lineno;
1034 if (id && id->flags & TF_COMMAND) {
1035 zconflval.id = id;
1036 return id->token;
1037 }
2402 alloc_string(zconftext, zconfleng); 1038 alloc_string(zconftext, zconfleng);
2403 zconflval.string = text; 1039 zconflval.string = text;
2404 return T_WORD; 1040 return T_WORD;
2405 } 1041 }
2406 YY_BREAK 1042 YY_BREAK
2407case 36: 1043case 7:
2408YY_RULE_SETUP 1044YY_RULE_SETUP
2409 1045
2410 YY_BREAK 1046 YY_BREAK
2411case 37: 1047case 8:
2412/* rule 37 can match eol */ 1048/* rule 8 can match eol */
2413YY_RULE_SETUP 1049YY_RULE_SETUP
2414current_file->lineno++; BEGIN(INITIAL); 1050{
1051 BEGIN(INITIAL);
1052 current_file->lineno++;
1053 return T_EOL;
1054 }
2415 YY_BREAK 1055 YY_BREAK
2416 1056
2417case 38: 1057case 9:
2418YY_RULE_SETUP 1058YY_RULE_SETUP
2419return T_AND; 1059return T_AND;
2420 YY_BREAK 1060 YY_BREAK
2421case 39: 1061case 10:
2422YY_RULE_SETUP 1062YY_RULE_SETUP
2423return T_OR; 1063return T_OR;
2424 YY_BREAK 1064 YY_BREAK
2425case 40: 1065case 11:
2426YY_RULE_SETUP 1066YY_RULE_SETUP
2427return T_OPEN_PAREN; 1067return T_OPEN_PAREN;
2428 YY_BREAK 1068 YY_BREAK
2429case 41: 1069case 12:
2430YY_RULE_SETUP 1070YY_RULE_SETUP
2431return T_CLOSE_PAREN; 1071return T_CLOSE_PAREN;
2432 YY_BREAK 1072 YY_BREAK
2433case 42: 1073case 13:
2434YY_RULE_SETUP 1074YY_RULE_SETUP
2435return T_NOT; 1075return T_NOT;
2436 YY_BREAK 1076 YY_BREAK
2437case 43: 1077case 14:
2438YY_RULE_SETUP 1078YY_RULE_SETUP
2439return T_EQUAL; 1079return T_EQUAL;
2440 YY_BREAK 1080 YY_BREAK
2441case 44: 1081case 15:
2442YY_RULE_SETUP 1082YY_RULE_SETUP
2443return T_UNEQUAL; 1083return T_UNEQUAL;
2444 YY_BREAK 1084 YY_BREAK
2445case 45: 1085case 16:
2446YY_RULE_SETUP
2447return T_IF;
2448 YY_BREAK
2449case 46:
2450YY_RULE_SETUP
2451return T_ON;
2452 YY_BREAK
2453case 47:
2454YY_RULE_SETUP 1086YY_RULE_SETUP
2455{ 1087{
2456 str = zconftext[0]; 1088 str = zconftext[0];
@@ -2458,33 +1090,38 @@ YY_RULE_SETUP
2458 BEGIN(STRING); 1090 BEGIN(STRING);
2459 } 1091 }
2460 YY_BREAK 1092 YY_BREAK
2461case 48: 1093case 17:
2462/* rule 48 can match eol */ 1094/* rule 17 can match eol */
2463YY_RULE_SETUP 1095YY_RULE_SETUP
2464BEGIN(INITIAL); current_file->lineno++; return T_EOL; 1096BEGIN(INITIAL); current_file->lineno++; return T_EOL;
2465 YY_BREAK 1097 YY_BREAK
2466case 49: 1098case 18:
2467YY_RULE_SETUP 1099YY_RULE_SETUP
2468/* ignore */ 1100/* ignore */
2469 YY_BREAK 1101 YY_BREAK
2470case 50: 1102case 19:
2471YY_RULE_SETUP 1103YY_RULE_SETUP
2472{ 1104{
1105 struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
1106 if (id && id->flags & TF_PARAM) {
1107 zconflval.id = id;
1108 return id->token;
1109 }
2473 alloc_string(zconftext, zconfleng); 1110 alloc_string(zconftext, zconfleng);
2474 zconflval.string = text; 1111 zconflval.string = text;
2475 return T_WORD; 1112 return T_WORD;
2476 } 1113 }
2477 YY_BREAK 1114 YY_BREAK
2478case 51: 1115case 20:
2479YY_RULE_SETUP 1116YY_RULE_SETUP
2480/* comment */ 1117/* comment */
2481 YY_BREAK 1118 YY_BREAK
2482case 52: 1119case 21:
2483/* rule 52 can match eol */ 1120/* rule 21 can match eol */
2484YY_RULE_SETUP 1121YY_RULE_SETUP
2485current_file->lineno++; 1122current_file->lineno++;
2486 YY_BREAK 1123 YY_BREAK
2487case 53: 1124case 22:
2488YY_RULE_SETUP 1125YY_RULE_SETUP
2489 1126
2490 YY_BREAK 1127 YY_BREAK
@@ -2494,8 +1131,8 @@ case YY_STATE_EOF(PARAM):
2494 } 1131 }
2495 YY_BREAK 1132 YY_BREAK
2496 1133
2497case 54: 1134case 23:
2498/* rule 54 can match eol */ 1135/* rule 23 can match eol */
2499*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ 1136*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2500(yy_c_buf_p) = yy_cp -= 1; 1137(yy_c_buf_p) = yy_cp -= 1;
2501YY_DO_BEFORE_ACTION; /* set up zconftext again */ 1138YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2506,14 +1143,14 @@ YY_RULE_SETUP
2506 return T_WORD_QUOTE; 1143 return T_WORD_QUOTE;
2507 } 1144 }
2508 YY_BREAK 1145 YY_BREAK
2509case 55: 1146case 24:
2510YY_RULE_SETUP 1147YY_RULE_SETUP
2511{ 1148{
2512 append_string(zconftext, zconfleng); 1149 append_string(zconftext, zconfleng);
2513 } 1150 }
2514 YY_BREAK 1151 YY_BREAK
2515case 56: 1152case 25:
2516/* rule 56 can match eol */ 1153/* rule 25 can match eol */
2517*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ 1154*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2518(yy_c_buf_p) = yy_cp -= 1; 1155(yy_c_buf_p) = yy_cp -= 1;
2519YY_DO_BEFORE_ACTION; /* set up zconftext again */ 1156YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2524,13 +1161,13 @@ YY_RULE_SETUP
2524 return T_WORD_QUOTE; 1161 return T_WORD_QUOTE;
2525 } 1162 }
2526 YY_BREAK 1163 YY_BREAK
2527case 57: 1164case 26:
2528YY_RULE_SETUP 1165YY_RULE_SETUP
2529{ 1166{
2530 append_string(zconftext + 1, zconfleng - 1); 1167 append_string(zconftext + 1, zconfleng - 1);
2531 } 1168 }
2532 YY_BREAK 1169 YY_BREAK
2533case 58: 1170case 27:
2534YY_RULE_SETUP 1171YY_RULE_SETUP
2535{ 1172{
2536 if (str == zconftext[0]) { 1173 if (str == zconftext[0]) {
@@ -2541,8 +1178,8 @@ YY_RULE_SETUP
2541 append_string(zconftext, 1); 1178 append_string(zconftext, 1);
2542 } 1179 }
2543 YY_BREAK 1180 YY_BREAK
2544case 59: 1181case 28:
2545/* rule 59 can match eol */ 1182/* rule 28 can match eol */
2546YY_RULE_SETUP 1183YY_RULE_SETUP
2547{ 1184{
2548 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); 1185 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
@@ -2557,7 +1194,7 @@ case YY_STATE_EOF(STRING):
2557 } 1194 }
2558 YY_BREAK 1195 YY_BREAK
2559 1196
2560case 60: 1197case 29:
2561YY_RULE_SETUP 1198YY_RULE_SETUP
2562{ 1199{
2563 ts = 0; 1200 ts = 0;
@@ -2582,8 +1219,8 @@ YY_RULE_SETUP
2582 } 1219 }
2583 } 1220 }
2584 YY_BREAK 1221 YY_BREAK
2585case 61: 1222case 30:
2586/* rule 61 can match eol */ 1223/* rule 30 can match eol */
2587*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ 1224*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2588(yy_c_buf_p) = yy_cp -= 1; 1225(yy_c_buf_p) = yy_cp -= 1;
2589YY_DO_BEFORE_ACTION; /* set up zconftext again */ 1226YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2594,15 +1231,15 @@ YY_RULE_SETUP
2594 return T_HELPTEXT; 1231 return T_HELPTEXT;
2595 } 1232 }
2596 YY_BREAK 1233 YY_BREAK
2597case 62: 1234case 31:
2598/* rule 62 can match eol */ 1235/* rule 31 can match eol */
2599YY_RULE_SETUP 1236YY_RULE_SETUP
2600{ 1237{
2601 current_file->lineno++; 1238 current_file->lineno++;
2602 append_string("\n", 1); 1239 append_string("\n", 1);
2603 } 1240 }
2604 YY_BREAK 1241 YY_BREAK
2605case 63: 1242case 32:
2606YY_RULE_SETUP 1243YY_RULE_SETUP
2607{ 1244{
2608 append_string(zconftext, zconfleng); 1245 append_string(zconftext, zconfleng);
@@ -2620,15 +1257,15 @@ case YY_STATE_EOF(HELP):
2620case YY_STATE_EOF(INITIAL): 1257case YY_STATE_EOF(INITIAL):
2621case YY_STATE_EOF(COMMAND): 1258case YY_STATE_EOF(COMMAND):
2622{ 1259{
2623 if (current_buf) { 1260 if (current_file) {
2624 zconf_endfile(); 1261 zconf_endfile();
2625 return T_EOF; 1262 return T_EOL;
2626 } 1263 }
2627 fclose(zconfin); 1264 fclose(zconfin);
2628 yyterminate(); 1265 yyterminate();
2629} 1266}
2630 YY_BREAK 1267 YY_BREAK
2631case 64: 1268case 33:
2632YY_RULE_SETUP 1269YY_RULE_SETUP
2633YY_FATAL_ERROR( "flex scanner jammed" ); 1270YY_FATAL_ERROR( "flex scanner jammed" );
2634 YY_BREAK 1271 YY_BREAK
@@ -3332,16 +1969,16 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
3332 1969
3333/** Setup the input buffer state to scan a string. The next call to zconflex() will 1970/** Setup the input buffer state to scan a string. The next call to zconflex() will
3334 * scan from a @e copy of @a str. 1971 * scan from a @e copy of @a str.
3335 * @param str a NUL-terminated string to scan 1972 * @param yy_str a NUL-terminated string to scan
3336 * 1973 *
3337 * @return the newly allocated buffer state object. 1974 * @return the newly allocated buffer state object.
3338 * @note If you want to scan bytes that may contain NUL values, then use 1975 * @note If you want to scan bytes that may contain NUL values, then use
3339 * zconf_scan_bytes() instead. 1976 * zconf_scan_bytes() instead.
3340 */ 1977 */
3341YY_BUFFER_STATE zconf_scan_string (yyconst char * str ) 1978YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
3342{ 1979{
3343 1980
3344 return zconf_scan_bytes(str,strlen(str) ); 1981 return zconf_scan_bytes(yy_str,strlen(yy_str) );
3345} 1982}
3346 1983
3347/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will 1984/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
@@ -3650,7 +2287,7 @@ void zconf_nextfile(const char *name)
3650 current_file = file; 2287 current_file = file;
3651} 2288}
3652 2289
3653static struct buffer *zconf_endfile(void) 2290static void zconf_endfile(void)
3654{ 2291{
3655 struct buffer *parent; 2292 struct buffer *parent;
3656 2293
@@ -3666,23 +2303,15 @@ static struct buffer *zconf_endfile(void)
3666 } 2303 }
3667 free(current_buf); 2304 free(current_buf);
3668 current_buf = parent; 2305 current_buf = parent;
3669
3670 return parent;
3671} 2306}
3672 2307
3673int zconf_lineno(void) 2308int zconf_lineno(void)
3674{ 2309{
3675 if (current_buf) 2310 return current_pos.lineno;
3676 return current_file->lineno - 1;
3677 else
3678 return 0;
3679} 2311}
3680 2312
3681char *zconf_curname(void) 2313char *zconf_curname(void)
3682{ 2314{
3683 if (current_buf) 2315 return current_pos.file ? current_pos.file->name : "<none>";
3684 return current_file->name;
3685 else
3686 return "<none>";
3687} 2316}
3688 2317
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 5fba1feff2a8..527f60c99c50 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -37,6 +37,17 @@ extern "C" {
37#define _(text) gettext(text) 37#define _(text) gettext(text)
38#define N_(text) (text) 38#define N_(text) (text)
39 39
40
41#define TF_COMMAND 0x0001
42#define TF_PARAM 0x0002
43
44struct kconf_id {
45 int name;
46 int token;
47 unsigned int flags;
48 enum symbol_type stype;
49};
50
40int zconfparse(void); 51int zconfparse(void);
41void zconfdump(FILE *out); 52void zconfdump(FILE *out);
42 53
@@ -50,7 +61,6 @@ char *zconf_curname(void);
50 61
51/* confdata.c */ 62/* confdata.c */
52extern const char conf_def_filename[]; 63extern const char conf_def_filename[];
53extern char conf_filename[];
54 64
55char *conf_get_default_confname(void); 65char *conf_get_default_confname(void);
56 66
@@ -59,7 +69,7 @@ void kconfig_load(void);
59 69
60/* menu.c */ 70/* menu.c */
61void menu_init(void); 71void menu_init(void);
62void menu_add_menu(void); 72struct menu *menu_add_menu(void);
63void menu_end_menu(void); 73void menu_end_menu(void);
64void menu_add_entry(struct symbol *sym); 74void menu_add_entry(struct symbol *sym);
65void menu_end_entry(void); 75void menu_end_entry(void);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 6dc6d0c48e7a..b6a389c5fcbd 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -2,6 +2,7 @@
2/* confdata.c */ 2/* confdata.c */
3P(conf_parse,void,(const char *name)); 3P(conf_parse,void,(const char *name));
4P(conf_read,int,(const char *name)); 4P(conf_read,int,(const char *name));
5P(conf_read_simple,int,(const char *name));
5P(conf_write,int,(const char *name)); 6P(conf_write,int,(const char *name));
6 7
7/* menu.c */ 8/* menu.c */
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 5cfa6c405cf0..0fce20cb7f3c 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -61,10 +61,11 @@ void menu_end_entry(void)
61{ 61{
62} 62}
63 63
64void menu_add_menu(void) 64struct menu *menu_add_menu(void)
65{ 65{
66 current_menu = current_entry; 66 menu_end_entry();
67 last_entry_ptr = &current_entry->list; 67 last_entry_ptr = &current_entry->list;
68 return current_menu = current_entry;
68} 69}
69 70
70void menu_end_menu(void) 71void menu_end_menu(void)
@@ -151,6 +152,12 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
151 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); 152 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
152} 153}
153 154
155static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
156{
157 return sym2->type == S_INT || sym2->type == S_HEX ||
158 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
159}
160
154void sym_check_prop(struct symbol *sym) 161void sym_check_prop(struct symbol *sym)
155{ 162{
156 struct property *prop; 163 struct property *prop;
@@ -185,8 +192,8 @@ void sym_check_prop(struct symbol *sym)
185 if (sym->type != S_INT && sym->type != S_HEX) 192 if (sym->type != S_INT && sym->type != S_HEX)
186 prop_warn(prop, "range is only allowed " 193 prop_warn(prop, "range is only allowed "
187 "for int or hex symbols"); 194 "for int or hex symbols");
188 if (!sym_string_valid(sym, prop->expr->left.sym->name) || 195 if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
189 !sym_string_valid(sym, prop->expr->right.sym->name)) 196 !menu_range_valid_sym(sym, prop->expr->right.sym))
190 prop_warn(prop, "range is invalid"); 197 prop_warn(prop, "range is invalid");
191 break; 198 break;
192 default: 199 default:
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index affa52f5c651..69c2549c0baa 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -141,6 +141,55 @@ struct property *sym_get_range_prop(struct symbol *sym)
141 return NULL; 141 return NULL;
142} 142}
143 143
144static int sym_get_range_val(struct symbol *sym, int base)
145{
146 sym_calc_value(sym);
147 switch (sym->type) {
148 case S_INT:
149 base = 10;
150 break;
151 case S_HEX:
152 base = 16;
153 break;
154 default:
155 break;
156 }
157 return strtol(sym->curr.val, NULL, base);
158}
159
160static void sym_validate_range(struct symbol *sym)
161{
162 struct property *prop;
163 int base, val, val2;
164 char str[64];
165
166 switch (sym->type) {
167 case S_INT:
168 base = 10;
169 break;
170 case S_HEX:
171 base = 16;
172 break;
173 default:
174 return;
175 }
176 prop = sym_get_range_prop(sym);
177 if (!prop)
178 return;
179 val = strtol(sym->curr.val, NULL, base);
180 val2 = sym_get_range_val(prop->expr->left.sym, base);
181 if (val >= val2) {
182 val2 = sym_get_range_val(prop->expr->right.sym, base);
183 if (val <= val2)
184 return;
185 }
186 if (sym->type == S_INT)
187 sprintf(str, "%d", val2);
188 else
189 sprintf(str, "0x%x", val2);
190 sym->curr.val = strdup(str);
191}
192
144static void sym_calc_visibility(struct symbol *sym) 193static void sym_calc_visibility(struct symbol *sym)
145{ 194{
146 struct property *prop; 195 struct property *prop;
@@ -301,6 +350,7 @@ void sym_calc_value(struct symbol *sym)
301 sym->curr = newval; 350 sym->curr = newval;
302 if (sym_is_choice(sym) && newval.tri == yes) 351 if (sym_is_choice(sym) && newval.tri == yes)
303 sym->curr.val = sym_calc_choice(sym); 352 sym->curr.val = sym_calc_choice(sym);
353 sym_validate_range(sym);
304 354
305 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) 355 if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
306 sym_set_changed(sym); 356 sym_set_changed(sym);
@@ -380,11 +430,22 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
380 sym->flags &= ~SYMBOL_NEW; 430 sym->flags &= ~SYMBOL_NEW;
381 sym_set_changed(sym); 431 sym_set_changed(sym);
382 } 432 }
433 /*
434 * setting a choice value also resets the new flag of the choice
435 * symbol and all other choice values.
436 */
383 if (sym_is_choice_value(sym) && val == yes) { 437 if (sym_is_choice_value(sym) && val == yes) {
384 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 438 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
439 struct property *prop;
440 struct expr *e;
385 441
386 cs->user.val = sym; 442 cs->user.val = sym;
387 cs->flags &= ~SYMBOL_NEW; 443 cs->flags &= ~SYMBOL_NEW;
444 prop = sym_get_choice_prop(cs);
445 for (e = prop->expr; e; e = e->left.expr) {
446 if (e->right.sym->visible != no)
447 e->right.sym->flags &= ~SYMBOL_NEW;
448 }
388 } 449 }
389 450
390 sym->user.tri = val; 451 sym->user.tri = val;
@@ -478,8 +539,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
478 if (!prop) 539 if (!prop)
479 return true; 540 return true;
480 val = strtol(str, NULL, 10); 541 val = strtol(str, NULL, 10);
481 return val >= strtol(prop->expr->left.sym->name, NULL, 10) && 542 return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
482 val <= strtol(prop->expr->right.sym->name, NULL, 10); 543 val <= sym_get_range_val(prop->expr->right.sym, 10);
483 case S_HEX: 544 case S_HEX:
484 if (!sym_string_valid(sym, str)) 545 if (!sym_string_valid(sym, str))
485 return false; 546 return false;
@@ -487,8 +548,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
487 if (!prop) 548 if (!prop)
488 return true; 549 return true;
489 val = strtol(str, NULL, 16); 550 val = strtol(str, NULL, 16);
490 return val >= strtol(prop->expr->left.sym->name, NULL, 16) && 551 return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
491 val <= strtol(prop->expr->right.sym->name, NULL, 16); 552 val <= sym_get_range_val(prop->expr->right.sym, 16);
492 case S_BOOLEAN: 553 case S_BOOLEAN:
493 case S_TRISTATE: 554 case S_TRISTATE:
494 switch (str[0]) { 555 switch (str[0]) {
@@ -731,12 +792,12 @@ struct symbol *sym_check_deps(struct symbol *sym)
731 struct symbol *sym2; 792 struct symbol *sym2;
732 struct property *prop; 793 struct property *prop;
733 794
734 if (sym->flags & SYMBOL_CHECK_DONE)
735 return NULL;
736 if (sym->flags & SYMBOL_CHECK) { 795 if (sym->flags & SYMBOL_CHECK) {
737 printf("Warning! Found recursive dependency: %s", sym->name); 796 printf("Warning! Found recursive dependency: %s", sym->name);
738 return sym; 797 return sym;
739 } 798 }
799 if (sym->flags & SYMBOL_CHECKED)
800 return NULL;
740 801
741 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 802 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
742 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 803 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
@@ -756,8 +817,13 @@ struct symbol *sym_check_deps(struct symbol *sym)
756 goto out; 817 goto out;
757 } 818 }
758out: 819out:
759 if (sym2) 820 if (sym2) {
760 printf(" %s", sym->name); 821 printf(" %s", sym->name);
822 if (sym2 == sym) {
823 printf("\n");
824 sym2 = NULL;
825 }
826 }
761 sym->flags &= ~SYMBOL_CHECK; 827 sym->flags &= ~SYMBOL_CHECK;
762 return sym2; 828 return sym2;
763} 829}
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
new file mode 100644
index 000000000000..b03220600b3a
--- /dev/null
+++ b/scripts/kconfig/zconf.gperf
@@ -0,0 +1,43 @@
1%language=ANSI-C
2%define hash-function-name kconf_id_hash
3%define lookup-function-name kconf_id_lookup
4%define string-pool-name kconf_id_strings
5%compare-strncmp
6%enum
7%pic
8%struct-type
9
10struct kconf_id;
11
12%%
13mainmenu, T_MAINMENU, TF_COMMAND
14menu, T_MENU, TF_COMMAND
15endmenu, T_ENDMENU, TF_COMMAND
16source, T_SOURCE, TF_COMMAND
17choice, T_CHOICE, TF_COMMAND
18endchoice, T_ENDCHOICE, TF_COMMAND
19comment, T_COMMENT, TF_COMMAND
20config, T_CONFIG, TF_COMMAND
21menuconfig, T_MENUCONFIG, TF_COMMAND
22help, T_HELP, TF_COMMAND
23if, T_IF, TF_COMMAND|TF_PARAM
24endif, T_ENDIF, TF_COMMAND
25depends, T_DEPENDS, TF_COMMAND
26requires, T_REQUIRES, TF_COMMAND
27optional, T_OPTIONAL, TF_COMMAND
28default, T_DEFAULT, TF_COMMAND, S_UNKNOWN
29prompt, T_PROMPT, TF_COMMAND
30tristate, T_TYPE, TF_COMMAND, S_TRISTATE
31def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE
32bool, T_TYPE, TF_COMMAND, S_BOOLEAN
33boolean, T_TYPE, TF_COMMAND, S_BOOLEAN
34def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN
35def_boolean, T_DEFAULT, TF_COMMAND, S_BOOLEAN
36int, T_TYPE, TF_COMMAND, S_INT
37hex, T_TYPE, TF_COMMAND, S_HEX
38string, T_TYPE, TF_COMMAND, S_STRING
39select, T_SELECT, TF_COMMAND
40enable, T_SELECT, TF_COMMAND
41range, T_RANGE, TF_COMMAND
42on, T_ON, TF_PARAM
43%%
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
new file mode 100644
index 000000000000..345f0fc07ca3
--- /dev/null
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -0,0 +1,231 @@
1/* ANSI-C code produced by gperf version 3.0.1 */
2/* Command-line: gperf */
3/* Computed positions: -k'1,3' */
4
5#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
6 && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
7 && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
8 && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
9 && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
10 && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
11 && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
12 && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
13 && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
14 && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
15 && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
16 && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
17 && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
18 && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
19 && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
20 && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
21 && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
22 && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
23 && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
24 && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
25 && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
26 && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
27 && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
28/* The character set is not based on ISO-646. */
29#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
30#endif
31
32struct kconf_id;
33/* maximum key range = 45, duplicates = 0 */
34
35#ifdef __GNUC__
36__inline
37#else
38#ifdef __cplusplus
39inline
40#endif
41#endif
42static unsigned int
43kconf_id_hash (register const char *str, register unsigned int len)
44{
45 static unsigned char asso_values[] =
46 {
47 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
48 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
49 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
50 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
51 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
52 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
53 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
54 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
55 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
56 47, 47, 47, 47, 47, 47, 47, 25, 10, 15,
57 0, 0, 5, 47, 0, 0, 47, 47, 0, 10,
58 0, 20, 20, 20, 5, 0, 0, 20, 47, 47,
59 20, 47, 47, 47, 47, 47, 47, 47, 47, 47,
60 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
61 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
62 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
63 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
64 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
65 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
66 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
67 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
68 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
69 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
70 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
71 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
72 47, 47, 47, 47, 47, 47
73 };
74 register int hval = len;
75
76 switch (hval)
77 {
78 default:
79 hval += asso_values[(unsigned char)str[2]];
80 /*FALLTHROUGH*/
81 case 2:
82 case 1:
83 hval += asso_values[(unsigned char)str[0]];
84 break;
85 }
86 return hval;
87}
88
89struct kconf_id_strings_t
90 {
91 char kconf_id_strings_str2[sizeof("if")];
92 char kconf_id_strings_str3[sizeof("int")];
93 char kconf_id_strings_str4[sizeof("help")];
94 char kconf_id_strings_str5[sizeof("endif")];
95 char kconf_id_strings_str6[sizeof("select")];
96 char kconf_id_strings_str7[sizeof("endmenu")];
97 char kconf_id_strings_str8[sizeof("tristate")];
98 char kconf_id_strings_str9[sizeof("endchoice")];
99 char kconf_id_strings_str10[sizeof("range")];
100 char kconf_id_strings_str11[sizeof("string")];
101 char kconf_id_strings_str12[sizeof("default")];
102 char kconf_id_strings_str13[sizeof("def_bool")];
103 char kconf_id_strings_str14[sizeof("menu")];
104 char kconf_id_strings_str16[sizeof("def_boolean")];
105 char kconf_id_strings_str17[sizeof("def_tristate")];
106 char kconf_id_strings_str18[sizeof("mainmenu")];
107 char kconf_id_strings_str20[sizeof("menuconfig")];
108 char kconf_id_strings_str21[sizeof("config")];
109 char kconf_id_strings_str22[sizeof("on")];
110 char kconf_id_strings_str23[sizeof("hex")];
111 char kconf_id_strings_str26[sizeof("source")];
112 char kconf_id_strings_str27[sizeof("depends")];
113 char kconf_id_strings_str28[sizeof("optional")];
114 char kconf_id_strings_str31[sizeof("enable")];
115 char kconf_id_strings_str32[sizeof("comment")];
116 char kconf_id_strings_str33[sizeof("requires")];
117 char kconf_id_strings_str34[sizeof("bool")];
118 char kconf_id_strings_str37[sizeof("boolean")];
119 char kconf_id_strings_str41[sizeof("choice")];
120 char kconf_id_strings_str46[sizeof("prompt")];
121 };
122static struct kconf_id_strings_t kconf_id_strings_contents =
123 {
124 "if",
125 "int",
126 "help",
127 "endif",
128 "select",
129 "endmenu",
130 "tristate",
131 "endchoice",
132 "range",
133 "string",
134 "default",
135 "def_bool",
136 "menu",
137 "def_boolean",
138 "def_tristate",
139 "mainmenu",
140 "menuconfig",
141 "config",
142 "on",
143 "hex",
144 "source",
145 "depends",
146 "optional",
147 "enable",
148 "comment",
149 "requires",
150 "bool",
151 "boolean",
152 "choice",
153 "prompt"
154 };
155#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
156#ifdef __GNUC__
157__inline
158#endif
159struct kconf_id *
160kconf_id_lookup (register const char *str, register unsigned int len)
161{
162 enum
163 {
164 TOTAL_KEYWORDS = 30,
165 MIN_WORD_LENGTH = 2,
166 MAX_WORD_LENGTH = 12,
167 MIN_HASH_VALUE = 2,
168 MAX_HASH_VALUE = 46
169 };
170
171 static struct kconf_id wordlist[] =
172 {
173 {-1}, {-1},
174 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM},
175 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
176 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND},
177 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
178 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND},
179 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
180 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
181 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
182 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
183 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_TYPE, TF_COMMAND, S_STRING},
184 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
185 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
186 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND},
187 {-1},
188 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
189 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
190 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND},
191 {-1},
192 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND},
193 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND},
194 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM},
195 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX},
196 {-1}, {-1},
197 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND},
198 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND},
199 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND},
200 {-1}, {-1},
201 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
202 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
203 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND},
204 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
205 {-1}, {-1},
206 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
207 {-1}, {-1}, {-1},
208 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND},
209 {-1}, {-1}, {-1}, {-1},
210 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, TF_COMMAND}
211 };
212
213 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
214 {
215 register int key = kconf_id_hash (str, len);
216
217 if (key <= MAX_HASH_VALUE && key >= 0)
218 {
219 register int o = wordlist[key].name;
220 if (o >= 0)
221 {
222 register const char *s = o + kconf_id_strings;
223
224 if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
225 return &wordlist[key];
226 }
227 }
228 }
229 return 0;
230}
231
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 55517b2877cd..cfa46077c6b4 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -18,8 +18,12 @@
18 18
19#define START_STRSIZE 16 19#define START_STRSIZE 16
20 20
21char *text; 21static struct {
22static char *text_ptr; 22 struct file *file;
23 int lineno;
24} current_pos;
25
26static char *text;
23static int text_size, text_asize; 27static int text_size, text_asize;
24 28
25struct buffer { 29struct buffer {
@@ -32,29 +36,28 @@ struct buffer *current_buf;
32static int last_ts, first_ts; 36static int last_ts, first_ts;
33 37
34static void zconf_endhelp(void); 38static void zconf_endhelp(void);
35static struct buffer *zconf_endfile(void); 39static void zconf_endfile(void);
36 40
37void new_string(void) 41void new_string(void)
38{ 42{
39 text = malloc(START_STRSIZE); 43 text = malloc(START_STRSIZE);
40 text_asize = START_STRSIZE; 44 text_asize = START_STRSIZE;
41 text_ptr = text;
42 text_size = 0; 45 text_size = 0;
43 *text_ptr = 0; 46 *text = 0;
44} 47}
45 48
46void append_string(const char *str, int size) 49void append_string(const char *str, int size)
47{ 50{
48 int new_size = text_size + size + 1; 51 int new_size = text_size + size + 1;
49 if (new_size > text_asize) { 52 if (new_size > text_asize) {
53 new_size += START_STRSIZE - 1;
54 new_size &= -START_STRSIZE;
50 text = realloc(text, new_size); 55 text = realloc(text, new_size);
51 text_asize = new_size; 56 text_asize = new_size;
52 text_ptr = text + text_size;
53 } 57 }
54 memcpy(text_ptr, str, size); 58 memcpy(text + text_size, str, size);
55 text_ptr += size;
56 text_size += size; 59 text_size += size;
57 *text_ptr = 0; 60 text[text_size] = 0;
58} 61}
59 62
60void alloc_string(const char *str, int size) 63void alloc_string(const char *str, int size)
@@ -72,10 +75,13 @@ n [A-Za-z0-9_]
72 int str = 0; 75 int str = 0;
73 int ts, i; 76 int ts, i;
74 77
75[ \t]*#.*\n current_file->lineno++; 78[ \t]*#.*\n |
79[ \t]*\n {
80 current_file->lineno++;
81 return T_EOL;
82}
76[ \t]*#.* 83[ \t]*#.*
77 84
78[ \t]*\n current_file->lineno++; return T_EOL;
79 85
80[ \t]+ { 86[ \t]+ {
81 BEGIN(COMMAND); 87 BEGIN(COMMAND);
@@ -88,42 +94,25 @@ n [A-Za-z0-9_]
88 94
89 95
90<COMMAND>{ 96<COMMAND>{
91 "mainmenu" BEGIN(PARAM); return T_MAINMENU;
92 "menu" BEGIN(PARAM); return T_MENU;
93 "endmenu" BEGIN(PARAM); return T_ENDMENU;
94 "source" BEGIN(PARAM); return T_SOURCE;
95 "choice" BEGIN(PARAM); return T_CHOICE;
96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
97 "comment" BEGIN(PARAM); return T_COMMENT;
98 "config" BEGIN(PARAM); return T_CONFIG;
99 "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
100 "help" BEGIN(PARAM); return T_HELP;
101 "if" BEGIN(PARAM); return T_IF;
102 "endif" BEGIN(PARAM); return T_ENDIF;
103 "depends" BEGIN(PARAM); return T_DEPENDS;
104 "requires" BEGIN(PARAM); return T_REQUIRES;
105 "optional" BEGIN(PARAM); return T_OPTIONAL;
106 "default" BEGIN(PARAM); return T_DEFAULT;
107 "prompt" BEGIN(PARAM); return T_PROMPT;
108 "tristate" BEGIN(PARAM); return T_TRISTATE;
109 "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
110 "bool" BEGIN(PARAM); return T_BOOLEAN;
111 "boolean" BEGIN(PARAM); return T_BOOLEAN;
112 "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
113 "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
114 "int" BEGIN(PARAM); return T_INT;
115 "hex" BEGIN(PARAM); return T_HEX;
116 "string" BEGIN(PARAM); return T_STRING;
117 "select" BEGIN(PARAM); return T_SELECT;
118 "enable" BEGIN(PARAM); return T_SELECT;
119 "range" BEGIN(PARAM); return T_RANGE;
120 {n}+ { 97 {n}+ {
98 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
99 BEGIN(PARAM);
100 current_pos.file = current_file;
101 current_pos.lineno = current_file->lineno;
102 if (id && id->flags & TF_COMMAND) {
103 zconflval.id = id;
104 return id->token;
105 }
121 alloc_string(yytext, yyleng); 106 alloc_string(yytext, yyleng);
122 zconflval.string = text; 107 zconflval.string = text;
123 return T_WORD; 108 return T_WORD;
124 } 109 }
125 . 110 .
126 \n current_file->lineno++; BEGIN(INITIAL); 111 \n {
112 BEGIN(INITIAL);
113 current_file->lineno++;
114 return T_EOL;
115 }
127} 116}
128 117
129<PARAM>{ 118<PARAM>{
@@ -134,8 +123,6 @@ n [A-Za-z0-9_]
134 "!" return T_NOT; 123 "!" return T_NOT;
135 "=" return T_EQUAL; 124 "=" return T_EQUAL;
136 "!=" return T_UNEQUAL; 125 "!=" return T_UNEQUAL;
137 "if" return T_IF;
138 "on" return T_ON;
139 \"|\' { 126 \"|\' {
140 str = yytext[0]; 127 str = yytext[0];
141 new_string(); 128 new_string();
@@ -144,6 +131,11 @@ n [A-Za-z0-9_]
144 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; 131 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
145 --- /* ignore */ 132 --- /* ignore */
146 ({n}|[-/.])+ { 133 ({n}|[-/.])+ {
134 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
135 if (id && id->flags & TF_PARAM) {
136 zconflval.id = id;
137 return id->token;
138 }
147 alloc_string(yytext, yyleng); 139 alloc_string(yytext, yyleng);
148 zconflval.string = text; 140 zconflval.string = text;
149 return T_WORD; 141 return T_WORD;
@@ -236,9 +228,9 @@ n [A-Za-z0-9_]
236} 228}
237 229
238<<EOF>> { 230<<EOF>> {
239 if (current_buf) { 231 if (current_file) {
240 zconf_endfile(); 232 zconf_endfile();
241 return T_EOF; 233 return T_EOL;
242 } 234 }
243 fclose(yyin); 235 fclose(yyin);
244 yyterminate(); 236 yyterminate();
@@ -329,7 +321,7 @@ void zconf_nextfile(const char *name)
329 current_file = file; 321 current_file = file;
330} 322}
331 323
332static struct buffer *zconf_endfile(void) 324static void zconf_endfile(void)
333{ 325{
334 struct buffer *parent; 326 struct buffer *parent;
335 327
@@ -345,22 +337,14 @@ static struct buffer *zconf_endfile(void)
345 } 337 }
346 free(current_buf); 338 free(current_buf);
347 current_buf = parent; 339 current_buf = parent;
348
349 return parent;
350} 340}
351 341
352int zconf_lineno(void) 342int zconf_lineno(void)
353{ 343{
354 if (current_buf) 344 return current_pos.lineno;
355 return current_file->lineno - 1;
356 else
357 return 0;
358} 345}
359 346
360char *zconf_curname(void) 347char *zconf_curname(void)
361{ 348{
362 if (current_buf) 349 return current_pos.file ? current_pos.file->name : "<none>";
363 return current_file->name;
364 else
365 return "<none>";
366} 350}
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index ff4fcc09720e..ea7755da82f5 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -1,7 +1,7 @@
1/* A Bison parser, made by GNU Bison 1.875a. */ 1/* A Bison parser, made by GNU Bison 2.0. */
2 2
3/* Skeleton parser for Yacc-like parsing with Bison, 3/* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -45,8 +45,7 @@
45/* Using locations. */ 45/* Using locations. */
46#define YYLSP_NEEDED 0 46#define YYLSP_NEEDED 0
47 47
48/* If NAME_PREFIX is specified substitute the variables and functions 48/* Substitute the variable and function names. */
49 names. */
50#define yyparse zconfparse 49#define yyparse zconfparse
51#define yylex zconflex 50#define yylex zconflex
52#define yyerror zconferror 51#define yyerror zconferror
@@ -79,28 +78,21 @@
79 T_REQUIRES = 272, 78 T_REQUIRES = 272,
80 T_OPTIONAL = 273, 79 T_OPTIONAL = 273,
81 T_PROMPT = 274, 80 T_PROMPT = 274,
82 T_DEFAULT = 275, 81 T_TYPE = 275,
83 T_TRISTATE = 276, 82 T_DEFAULT = 276,
84 T_DEF_TRISTATE = 277, 83 T_SELECT = 277,
85 T_BOOLEAN = 278, 84 T_RANGE = 278,
86 T_DEF_BOOLEAN = 279, 85 T_ON = 279,
87 T_STRING = 280, 86 T_WORD = 280,
88 T_INT = 281, 87 T_WORD_QUOTE = 281,
89 T_HEX = 282, 88 T_UNEQUAL = 282,
90 T_WORD = 283, 89 T_CLOSE_PAREN = 283,
91 T_WORD_QUOTE = 284, 90 T_OPEN_PAREN = 284,
92 T_UNEQUAL = 285, 91 T_EOL = 285,
93 T_EOF = 286, 92 T_OR = 286,
94 T_EOL = 287, 93 T_AND = 287,
95 T_CLOSE_PAREN = 288, 94 T_EQUAL = 288,
96 T_OPEN_PAREN = 289, 95 T_NOT = 289
97 T_ON = 290,
98 T_SELECT = 291,
99 T_RANGE = 292,
100 T_OR = 293,
101 T_AND = 294,
102 T_EQUAL = 295,
103 T_NOT = 296
104 }; 96 };
105#endif 97#endif
106#define T_MAINMENU 258 98#define T_MAINMENU 258
@@ -120,28 +112,21 @@
120#define T_REQUIRES 272 112#define T_REQUIRES 272
121#define T_OPTIONAL 273 113#define T_OPTIONAL 273
122#define T_PROMPT 274 114#define T_PROMPT 274
123#define T_DEFAULT 275 115#define T_TYPE 275
124#define T_TRISTATE 276 116#define T_DEFAULT 276
125#define T_DEF_TRISTATE 277 117#define T_SELECT 277
126#define T_BOOLEAN 278 118#define T_RANGE 278
127#define T_DEF_BOOLEAN 279 119#define T_ON 279
128#define T_STRING 280 120#define T_WORD 280
129#define T_INT 281 121#define T_WORD_QUOTE 281
130#define T_HEX 282 122#define T_UNEQUAL 282
131#define T_WORD 283 123#define T_CLOSE_PAREN 283
132#define T_WORD_QUOTE 284 124#define T_OPEN_PAREN 284
133#define T_UNEQUAL 285 125#define T_EOL 285
134#define T_EOF 286 126#define T_OR 286
135#define T_EOL 287 127#define T_AND 287
136#define T_CLOSE_PAREN 288 128#define T_EQUAL 288
137#define T_OPEN_PAREN 289 129#define T_NOT 289
138#define T_ON 290
139#define T_SELECT 291
140#define T_RANGE 292
141#define T_OR 293
142#define T_AND 294
143#define T_EQUAL 295
144#define T_NOT 296
145 130
146 131
147 132
@@ -161,6 +146,11 @@
161#include <string.h> 146#include <string.h>
162#include <stdbool.h> 147#include <stdbool.h>
163 148
149#define LKC_DIRECT_LINK
150#include "lkc.h"
151
152#include "zconf.hash.c"
153
164#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 154#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
165 155
166#define PRINTD 0x0001 156#define PRINTD 0x0001
@@ -170,14 +160,18 @@ int cdebug = PRINTD;
170 160
171extern int zconflex(void); 161extern int zconflex(void);
172static void zconfprint(const char *err, ...); 162static void zconfprint(const char *err, ...);
163static void zconf_error(const char *err, ...);
173static void zconferror(const char *err); 164static void zconferror(const char *err);
174static bool zconf_endtoken(int token, int starttoken, int endtoken); 165static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
175 166
176struct symbol *symbol_hash[257]; 167struct symbol *symbol_hash[257];
177 168
178static struct menu *current_menu, *current_entry; 169static struct menu *current_menu, *current_entry;
179 170
171#define YYDEBUG 0
172#if YYDEBUG
180#define YYERROR_VERBOSE 173#define YYERROR_VERBOSE
174#endif
181 175
182 176
183/* Enabling traces. */ 177/* Enabling traces. */
@@ -196,13 +190,14 @@ static struct menu *current_menu, *current_entry;
196#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) 190#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
197 191
198typedef union YYSTYPE { 192typedef union YYSTYPE {
199 int token;
200 char *string; 193 char *string;
194 struct file *file;
201 struct symbol *symbol; 195 struct symbol *symbol;
202 struct expr *expr; 196 struct expr *expr;
203 struct menu *menu; 197 struct menu *menu;
198 struct kconf_id *id;
204} YYSTYPE; 199} YYSTYPE;
205/* Line 191 of yacc.c. */ 200/* Line 190 of yacc.c. */
206 201
207# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 202# define yystype YYSTYPE /* obsolescent; will be withdrawn */
208# define YYSTYPE_IS_DECLARED 1 203# define YYSTYPE_IS_DECLARED 1
@@ -214,27 +209,26 @@ typedef union YYSTYPE {
214/* Copy the second part of user declarations. */ 209/* Copy the second part of user declarations. */
215 210
216 211
217#define LKC_DIRECT_LINK 212/* Line 213 of yacc.c. */
218#include "lkc.h"
219
220
221/* Line 214 of yacc.c. */
222 213
223 214
224#if ! defined (yyoverflow) || YYERROR_VERBOSE 215#if ! defined (yyoverflow) || YYERROR_VERBOSE
225 216
217# ifndef YYFREE
218# define YYFREE free
219# endif
220# ifndef YYMALLOC
221# define YYMALLOC malloc
222# endif
223
226/* The parser invokes alloca or malloc; define the necessary symbols. */ 224/* The parser invokes alloca or malloc; define the necessary symbols. */
227 225
228# if YYSTACK_USE_ALLOCA 226# ifdef YYSTACK_USE_ALLOCA
229# define YYSTACK_ALLOC alloca 227# if YYSTACK_USE_ALLOCA
230# else 228# ifdef __GNUC__
231# ifndef YYSTACK_USE_ALLOCA 229# define YYSTACK_ALLOC __builtin_alloca
232# if defined (alloca) || defined (_ALLOCA_H)
233# define YYSTACK_ALLOC alloca
234# else 230# else
235# ifdef __GNUC__ 231# define YYSTACK_ALLOC alloca
236# define YYSTACK_ALLOC __builtin_alloca
237# endif
238# endif 232# endif
239# endif 233# endif
240# endif 234# endif
@@ -247,20 +241,20 @@ typedef union YYSTYPE {
247# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ 241# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
248# define YYSIZE_T size_t 242# define YYSIZE_T size_t
249# endif 243# endif
250# define YYSTACK_ALLOC malloc 244# define YYSTACK_ALLOC YYMALLOC
251# define YYSTACK_FREE free 245# define YYSTACK_FREE YYFREE
252# endif 246# endif
253#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ 247#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
254 248
255 249
256#if (! defined (yyoverflow) \ 250#if (! defined (yyoverflow) \
257 && (! defined (__cplusplus) \ 251 && (! defined (__cplusplus) \
258 || (YYSTYPE_IS_TRIVIAL))) 252 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
259 253
260/* A type that is properly aligned for any stack member. */ 254/* A type that is properly aligned for any stack member. */
261union yyalloc 255union yyalloc
262{ 256{
263 short yyss; 257 short int yyss;
264 YYSTYPE yyvs; 258 YYSTYPE yyvs;
265 }; 259 };
266 260
@@ -270,13 +264,13 @@ union yyalloc
270/* The size of an array large to enough to hold all stacks, each with 264/* The size of an array large to enough to hold all stacks, each with
271 N elements. */ 265 N elements. */
272# define YYSTACK_BYTES(N) \ 266# define YYSTACK_BYTES(N) \
273 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ 267 ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
274 + YYSTACK_GAP_MAXIMUM) 268 + YYSTACK_GAP_MAXIMUM)
275 269
276/* Copy COUNT objects from FROM to TO. The source and destination do 270/* Copy COUNT objects from FROM to TO. The source and destination do
277 not overlap. */ 271 not overlap. */
278# ifndef YYCOPY 272# ifndef YYCOPY
279# if 1 < __GNUC__ 273# if defined (__GNUC__) && 1 < __GNUC__
280# define YYCOPY(To, From, Count) \ 274# define YYCOPY(To, From, Count) \
281 __builtin_memcpy (To, From, (Count) * sizeof (*(From))) 275 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
282# else 276# else
@@ -312,26 +306,26 @@ union yyalloc
312#if defined (__STDC__) || defined (__cplusplus) 306#if defined (__STDC__) || defined (__cplusplus)
313 typedef signed char yysigned_char; 307 typedef signed char yysigned_char;
314#else 308#else
315 typedef short yysigned_char; 309 typedef short int yysigned_char;
316#endif 310#endif
317 311
318/* YYFINAL -- State number of the termination state. */ 312/* YYFINAL -- State number of the termination state. */
319#define YYFINAL 2 313#define YYFINAL 3
320/* YYLAST -- Last index in YYTABLE. */ 314/* YYLAST -- Last index in YYTABLE. */
321#define YYLAST 201 315#define YYLAST 264
322 316
323/* YYNTOKENS -- Number of terminals. */ 317/* YYNTOKENS -- Number of terminals. */
324#define YYNTOKENS 42 318#define YYNTOKENS 35
325/* YYNNTS -- Number of nonterminals. */ 319/* YYNNTS -- Number of nonterminals. */
326#define YYNNTS 41 320#define YYNNTS 42
327/* YYNRULES -- Number of rules. */ 321/* YYNRULES -- Number of rules. */
328#define YYNRULES 104 322#define YYNRULES 104
329/* YYNRULES -- Number of states. */ 323/* YYNRULES -- Number of states. */
330#define YYNSTATES 182 324#define YYNSTATES 175
331 325
332/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 326/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
333#define YYUNDEFTOK 2 327#define YYUNDEFTOK 2
334#define YYMAXUTOK 296 328#define YYMAXUTOK 289
335 329
336#define YYTRANSLATE(YYX) \ 330#define YYTRANSLATE(YYX) \
337 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 331 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -367,79 +361,78 @@ static const unsigned char yytranslate[] =
367 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 361 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
368 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 362 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
369 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 363 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
370 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 364 25, 26, 27, 28, 29, 30, 31, 32, 33, 34
371 35, 36, 37, 38, 39, 40, 41
372}; 365};
373 366
374#if YYDEBUG 367#if YYDEBUG
375/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in 368/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
376 YYRHS. */ 369 YYRHS. */
377static const unsigned short yyprhs[] = 370static const unsigned short int yyprhs[] =
378{ 371{
379 0, 0, 3, 4, 7, 9, 11, 13, 17, 19, 372 0, 0, 3, 5, 6, 9, 12, 15, 20, 23,
380 21, 23, 26, 28, 30, 32, 34, 36, 38, 42, 373 28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
381 45, 49, 52, 53, 56, 59, 62, 65, 69, 74, 374 53, 55, 57, 59, 61, 63, 67, 70, 74, 77,
382 78, 83, 87, 91, 95, 100, 105, 110, 116, 119, 375 81, 84, 85, 88, 91, 94, 97, 100, 104, 109,
383 122, 124, 128, 131, 132, 135, 138, 141, 144, 149, 376 114, 119, 125, 128, 131, 133, 137, 138, 141, 144,
384 153, 157, 160, 165, 166, 169, 173, 175, 179, 182, 377 147, 150, 153, 158, 162, 165, 170, 171, 174, 178,
385 183, 186, 189, 192, 196, 199, 201, 205, 208, 209, 378 180, 184, 185, 188, 191, 194, 198, 201, 203, 207,
386 212, 215, 218, 222, 226, 228, 232, 235, 238, 241, 379 208, 211, 214, 217, 221, 225, 228, 231, 234, 235,
387 242, 245, 248, 253, 257, 261, 262, 265, 267, 269, 380 238, 241, 244, 249, 253, 257, 258, 261, 263, 265,
388 272, 275, 278, 280, 282, 283, 286, 288, 292, 296, 381 268, 271, 274, 276, 279, 280, 283, 285, 289, 293,
389 300, 303, 307, 311, 313 382 297, 300, 304, 308, 310
390}; 383};
391 384
392/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 385/* YYRHS -- A `-1'-separated list of the rules' RHS. */
393static const yysigned_char yyrhs[] = 386static const yysigned_char yyrhs[] =
394{ 387{
395 43, 0, -1, -1, 43, 44, -1, 45, -1, 55, 388 36, 0, -1, 37, -1, -1, 37, 39, -1, 37,
396 -1, 66, -1, 3, 77, 79, -1, 5, -1, 15, 389 50, -1, 37, 61, -1, 37, 3, 71, 73, -1,
397 -1, 8, -1, 1, 79, -1, 61, -1, 71, -1, 390 37, 72, -1, 37, 25, 1, 30, -1, 37, 38,
398 47, -1, 49, -1, 69, -1, 79, -1, 10, 28, 391 1, 30, -1, 37, 1, 30, -1, 16, -1, 19,
399 32, -1, 46, 50, -1, 11, 28, 32, -1, 48, 392 -1, 20, -1, 22, -1, 18, -1, 23, -1, 21,
400 50, -1, -1, 50, 51, -1, 50, 75, -1, 50, 393 -1, 30, -1, 56, -1, 65, -1, 42, -1, 44,
401 73, -1, 50, 32, -1, 21, 76, 32, -1, 22, 394 -1, 63, -1, 25, 1, 30, -1, 1, 30, -1,
402 81, 80, 32, -1, 23, 76, 32, -1, 24, 81, 395 10, 25, 30, -1, 41, 45, -1, 11, 25, 30,
403 80, 32, -1, 26, 76, 32, -1, 27, 76, 32, 396 -1, 43, 45, -1, -1, 45, 46, -1, 45, 69,
404 -1, 25, 76, 32, -1, 19, 77, 80, 32, -1, 397 -1, 45, 67, -1, 45, 40, -1, 45, 30, -1,
405 20, 81, 80, 32, -1, 36, 28, 80, 32, -1, 398 20, 70, 30, -1, 19, 71, 74, 30, -1, 21,
406 37, 82, 82, 80, 32, -1, 7, 32, -1, 52, 399 75, 74, 30, -1, 22, 25, 74, 30, -1, 23,
407 56, -1, 78, -1, 53, 58, 54, -1, 53, 58, 400 76, 76, 74, 30, -1, 7, 30, -1, 47, 51,
408 -1, -1, 56, 57, -1, 56, 75, -1, 56, 73, 401 -1, 72, -1, 48, 53, 49, -1, -1, 51, 52,
409 -1, 56, 32, -1, 19, 77, 80, 32, -1, 21, 402 -1, 51, 69, -1, 51, 67, -1, 51, 30, -1,
410 76, 32, -1, 23, 76, 32, -1, 18, 32, -1, 403 51, 40, -1, 19, 71, 74, 30, -1, 20, 70,
411 20, 28, 80, 32, -1, -1, 58, 45, -1, 14, 404 30, -1, 18, 30, -1, 21, 25, 74, 30, -1,
412 81, 32, -1, 78, -1, 59, 62, 60, -1, 59, 405 -1, 53, 39, -1, 14, 75, 73, -1, 72, -1,
413 62, -1, -1, 62, 45, -1, 62, 66, -1, 62, 406 54, 57, 55, -1, -1, 57, 39, -1, 57, 61,
414 55, -1, 4, 77, 32, -1, 63, 74, -1, 78, 407 -1, 57, 50, -1, 4, 71, 30, -1, 58, 68,
415 -1, 64, 67, 65, -1, 64, 67, -1, -1, 67, 408 -1, 72, -1, 59, 62, 60, -1, -1, 62, 39,
416 45, -1, 67, 66, -1, 67, 55, -1, 67, 1, 409 -1, 62, 61, -1, 62, 50, -1, 6, 71, 30,
417 32, -1, 6, 77, 32, -1, 68, -1, 9, 77, 410 -1, 9, 71, 30, -1, 64, 68, -1, 12, 30,
418 32, -1, 70, 74, -1, 12, 32, -1, 72, 13, 411 -1, 66, 13, -1, -1, 68, 69, -1, 68, 30,
419 -1, -1, 74, 75, -1, 74, 32, -1, 16, 35, 412 -1, 68, 40, -1, 16, 24, 75, 30, -1, 16,
420 81, 32, -1, 16, 81, 32, -1, 17, 81, 32, 413 75, 30, -1, 17, 75, 30, -1, -1, 71, 74,
421 -1, -1, 77, 80, -1, 28, -1, 29, -1, 5, 414 -1, 25, -1, 26, -1, 5, 30, -1, 8, 30,
422 79, -1, 8, 79, -1, 15, 79, -1, 32, -1, 415 -1, 15, 30, -1, 30, -1, 73, 30, -1, -1,
423 31, -1, -1, 14, 81, -1, 82, -1, 82, 40, 416 14, 75, -1, 76, -1, 76, 33, 76, -1, 76,
424 82, -1, 82, 30, 82, -1, 34, 81, 33, -1, 417 27, 76, -1, 29, 75, 28, -1, 34, 75, -1,
425 41, 81, -1, 81, 38, 81, -1, 81, 39, 81, 418 75, 31, 75, -1, 75, 32, 75, -1, 25, -1,
426 -1, 28, -1, 29, -1 419 26, -1
427}; 420};
428 421
429/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 422/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
430static const unsigned short yyrline[] = 423static const unsigned short int yyrline[] =
431{ 424{
432 0, 94, 94, 95, 98, 99, 100, 101, 102, 103, 425 0, 103, 103, 105, 107, 108, 109, 110, 111, 112,
433 104, 105, 109, 110, 111, 112, 113, 114, 120, 128, 426 113, 117, 121, 121, 121, 121, 121, 121, 121, 125,
434 134, 142, 152, 154, 155, 156, 157, 160, 166, 173, 427 126, 127, 128, 129, 130, 134, 135, 141, 149, 155,
435 179, 186, 192, 198, 204, 210, 216, 222, 230, 239, 428 163, 173, 175, 176, 177, 178, 179, 182, 190, 196,
436 245, 254, 255, 261, 263, 264, 265, 266, 269, 275, 429 206, 212, 220, 229, 234, 242, 245, 247, 248, 249,
437 281, 287, 293, 299, 301, 306, 315, 324, 325, 331, 430 250, 251, 254, 260, 271, 277, 287, 289, 294, 302,
438 333, 334, 335, 340, 347, 353, 362, 363, 369, 371, 431 310, 313, 315, 316, 317, 322, 329, 334, 342, 345,
439 372, 373, 374, 377, 383, 390, 397, 404, 410, 417, 432 347, 348, 349, 352, 360, 367, 374, 380, 387, 389,
440 418, 419, 422, 427, 432, 440, 442, 447, 448, 451, 433 390, 391, 394, 399, 404, 412, 414, 419, 420, 423,
441 452, 453, 457, 457, 459, 460, 463, 464, 465, 466, 434 424, 425, 429, 430, 433, 434, 437, 438, 439, 440,
442 467, 468, 469, 472, 473 435 441, 442, 443, 446, 447
443}; 436};
444#endif 437#endif
445 438
@@ -448,67 +441,65 @@ static const unsigned short yyrline[] =
448 First, the terminals, then, starting at YYNTOKENS, nonterminals. */ 441 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
449static const char *const yytname[] = 442static const char *const yytname[] =
450{ 443{
451 "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", 444 "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
452 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", 445 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
453 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", 446 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
454 "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE", 447 "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
455 "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT", 448 "T_SELECT", "T_RANGE", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
456 "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL", 449 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
457 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR", 450 "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt",
458 "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block", 451 "option_error", "config_entry_start", "config_stmt",
459 "common_block", "config_entry_start", "config_stmt", 452 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
460 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", 453 "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
461 "config_option", "choice", "choice_entry", "choice_end", "choice_stmt", 454 "choice_option_list", "choice_option", "choice_block", "if_entry",
462 "choice_option_list", "choice_option", "choice_block", "if", "if_end", 455 "if_end", "if_stmt", "if_block", "menu", "menu_entry", "menu_end",
463 "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt", 456 "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt",
464 "menu_block", "source", "source_stmt", "comment", "comment_stmt", 457 "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
465 "help_start", "help", "depends_list", "depends", "prompt_stmt_opt", 458 "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
466 "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0
467}; 459};
468#endif 460#endif
469 461
470# ifdef YYPRINT 462# ifdef YYPRINT
471/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to 463/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
472 token YYLEX-NUM. */ 464 token YYLEX-NUM. */
473static const unsigned short yytoknum[] = 465static const unsigned short int yytoknum[] =
474{ 466{
475 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 467 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
476 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 468 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
477 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 469 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
478 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 470 285, 286, 287, 288, 289
479 295, 296
480}; 471};
481# endif 472# endif
482 473
483/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 474/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
484static const unsigned char yyr1[] = 475static const unsigned char yyr1[] =
485{ 476{
486 0, 42, 43, 43, 44, 44, 44, 44, 44, 44, 477 0, 35, 36, 37, 37, 37, 37, 37, 37, 37,
487 44, 44, 45, 45, 45, 45, 45, 45, 46, 47, 478 37, 37, 38, 38, 38, 38, 38, 38, 38, 39,
488 48, 49, 50, 50, 50, 50, 50, 51, 51, 51, 479 39, 39, 39, 39, 39, 40, 40, 41, 42, 43,
489 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, 480 44, 45, 45, 45, 45, 45, 45, 46, 46, 46,
490 54, 55, 55, 56, 56, 56, 56, 56, 57, 57, 481 46, 46, 47, 48, 49, 50, 51, 51, 51, 51,
491 57, 57, 57, 58, 58, 59, 60, 61, 61, 62, 482 51, 51, 52, 52, 52, 52, 53, 53, 54, 55,
492 62, 62, 62, 63, 64, 65, 66, 66, 67, 67, 483 56, 57, 57, 57, 57, 58, 59, 60, 61, 62,
493 67, 67, 67, 68, 69, 70, 71, 72, 73, 74, 484 62, 62, 62, 63, 64, 65, 66, 67, 68, 68,
494 74, 74, 75, 75, 75, 76, 76, 77, 77, 78, 485 68, 68, 69, 69, 69, 70, 70, 71, 71, 72,
495 78, 78, 79, 79, 80, 80, 81, 81, 81, 81, 486 72, 72, 73, 73, 74, 74, 75, 75, 75, 75,
496 81, 81, 81, 82, 82 487 75, 75, 75, 76, 76
497}; 488};
498 489
499/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 490/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
500static const unsigned char yyr2[] = 491static const unsigned char yyr2[] =
501{ 492{
502 0, 2, 0, 2, 1, 1, 1, 3, 1, 1, 493 0, 2, 1, 0, 2, 2, 2, 4, 2, 4,
503 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 494 4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
504 3, 2, 0, 2, 2, 2, 2, 3, 4, 3, 495 1, 1, 1, 1, 1, 3, 2, 3, 2, 3,
505 4, 3, 3, 3, 4, 4, 4, 5, 2, 2, 496 2, 0, 2, 2, 2, 2, 2, 3, 4, 4,
506 1, 3, 2, 0, 2, 2, 2, 2, 4, 3, 497 4, 5, 2, 2, 1, 3, 0, 2, 2, 2,
507 3, 2, 4, 0, 2, 3, 1, 3, 2, 0, 498 2, 2, 4, 3, 2, 4, 0, 2, 3, 1,
508 2, 2, 2, 3, 2, 1, 3, 2, 0, 2, 499 3, 0, 2, 2, 2, 3, 2, 1, 3, 0,
509 2, 2, 3, 3, 1, 3, 2, 2, 2, 0, 500 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
510 2, 2, 4, 3, 3, 0, 2, 1, 1, 2, 501 2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
511 2, 2, 1, 1, 0, 2, 1, 3, 3, 3, 502 2, 2, 1, 2, 0, 2, 1, 3, 3, 3,
512 2, 3, 3, 1, 1 503 2, 3, 3, 1, 1
513}; 504};
514 505
@@ -517,151 +508,160 @@ static const unsigned char yyr2[] =
517 means the default is an error. */ 508 means the default is an error. */
518static const unsigned char yydefact[] = 509static const unsigned char yydefact[] =
519{ 510{
520 2, 0, 1, 0, 0, 0, 8, 0, 0, 10, 511 3, 0, 0, 1, 0, 0, 0, 0, 0, 0,
521 0, 0, 0, 0, 9, 93, 92, 3, 4, 22, 512 0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
522 14, 22, 15, 43, 53, 5, 59, 12, 79, 68, 513 18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
523 6, 74, 16, 79, 13, 17, 11, 87, 88, 0, 514 23, 46, 56, 5, 61, 20, 78, 69, 6, 24,
524 0, 0, 38, 0, 0, 0, 103, 104, 0, 0, 515 78, 21, 8, 11, 87, 88, 0, 0, 89, 0,
525 0, 96, 19, 21, 39, 42, 58, 64, 0, 76, 516 42, 90, 0, 0, 0, 103, 104, 0, 0, 0,
526 7, 63, 73, 75, 18, 20, 0, 100, 55, 0, 517 96, 91, 0, 0, 0, 0, 0, 0, 0, 0,
527 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 518 0, 0, 92, 7, 65, 73, 74, 27, 29, 0,
528 85, 0, 85, 85, 85, 26, 0, 0, 23, 0, 519 100, 0, 0, 58, 0, 0, 9, 10, 0, 0,
529 25, 24, 0, 0, 0, 85, 85, 47, 44, 46, 520 0, 0, 0, 85, 0, 0, 0, 0, 36, 35,
530 45, 0, 0, 0, 54, 41, 40, 60, 62, 57, 521 32, 0, 34, 33, 0, 0, 85, 0, 50, 51,
531 61, 56, 81, 80, 0, 69, 71, 66, 70, 65, 522 47, 49, 48, 57, 45, 44, 62, 64, 60, 63,
532 99, 101, 102, 98, 97, 77, 0, 0, 0, 94, 523 59, 80, 81, 79, 70, 72, 68, 71, 67, 93,
533 94, 0, 94, 94, 0, 94, 0, 0, 0, 94, 524 99, 101, 102, 98, 97, 26, 76, 0, 0, 0,
534 0, 78, 51, 94, 94, 0, 0, 89, 90, 91, 525 94, 0, 94, 94, 94, 0, 0, 77, 54, 94,
535 72, 0, 83, 84, 0, 0, 0, 27, 86, 0, 526 0, 94, 0, 83, 84, 0, 0, 37, 86, 0,
536 29, 0, 33, 31, 32, 0, 94, 0, 0, 49, 527 0, 94, 25, 0, 53, 0, 82, 95, 38, 39,
537 50, 82, 95, 34, 35, 28, 30, 36, 0, 48, 528 40, 0, 52, 55, 41
538 52, 37
539}; 529};
540 530
541/* YYDEFGOTO[NTERM-NUM]. */ 531/* YYDEFGOTO[NTERM-NUM]. */
542static const short yydefgoto[] = 532static const short int yydefgoto[] =
543{ 533{
544 -1, 1, 17, 18, 19, 20, 21, 22, 52, 88, 534 -1, 1, 2, 25, 26, 99, 27, 28, 29, 30,
545 23, 24, 105, 25, 54, 98, 55, 26, 109, 27, 535 64, 100, 31, 32, 114, 33, 66, 110, 67, 34,
546 56, 28, 29, 117, 30, 58, 31, 32, 33, 34, 536 118, 35, 68, 36, 37, 126, 38, 70, 39, 40,
547 89, 90, 57, 91, 131, 132, 106, 35, 155, 50, 537 41, 101, 102, 69, 103, 141, 142, 42, 73, 156,
548 51 538 59, 60
549}; 539};
550 540
551/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 541/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
552 STATE-NUM. */ 542 STATE-NUM. */
553#define YYPACT_NINF -99 543#define YYPACT_NINF -78
554static const short yypact[] = 544static const short int yypact[] =
555{ 545{
556 -99, 48, -99, 38, 46, 46, -99, 46, -29, -99, 546 -78, 2, 159, -78, -21, 0, 0, -12, 0, 1,
557 46, -17, -3, -11, -99, -99, -99, -99, -99, -99, 547 4, 0, 27, 38, 60, 58, -78, -78, -78, -78,
558 -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, 548 -78, -78, -78, 100, -78, 104, -78, -78, -78, -78,
559 -99, -99, -99, -99, -99, -99, -99, -99, -99, 38, 549 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
560 12, 15, -99, 18, 51, 62, -99, -99, -11, -11, 550 -78, -78, -78, -78, -78, -78, 86, 113, -78, 114,
561 4, -24, 138, 138, 160, 121, 110, -4, 81, -4, 551 -78, -78, 125, 127, 128, -78, -78, 60, 60, 210,
562 -99, -99, -99, -99, -99, -99, -19, -99, -99, -11, 552 65, -78, 141, 142, 39, 103, 182, 200, 6, 66,
563 -11, 70, 70, 73, 32, -11, 46, -11, 46, -11, 553 6, 131, -78, 146, -78, -78, -78, -78, -78, 196,
564 46, -11, 46, 46, 46, -99, 36, 70, -99, 95, 554 -78, 60, 60, 146, 40, 40, -78, -78, 155, 156,
565 -99, -99, 96, 46, 106, 46, 46, -99, -99, -99, 555 -2, 60, 0, 0, 60, 105, 40, 194, -78, -78,
566 -99, 38, 38, 38, -99, -99, -99, -99, -99, -99, 556 -78, 206, -78, -78, 183, 0, 0, 195, -78, -78,
567 -99, -99, -99, -99, 112, -99, -99, -99, -99, -99, 557 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
568 -99, 117, -99, -99, -99, -99, -11, 33, 65, 131, 558 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
569 1, 119, 131, 1, 136, 1, 153, 154, 155, 131, 559 -78, 197, -78, -78, -78, -78, -78, 60, 213, 216,
570 70, -99, -99, 131, 131, 156, 157, -99, -99, -99, 560 212, 203, 212, 190, 212, 40, 208, -78, -78, 212,
571 -99, 101, -99, -99, -11, 158, 159, -99, -99, 161, 561 222, 212, 219, -78, -78, 60, 223, -78, -78, 224,
572 -99, 162, -99, -99, -99, 163, 131, 164, 165, -99, 562 225, 212, -78, 226, -78, 227, -78, 47, -78, -78,
573 -99, -99, 99, -99, -99, -99, -99, -99, 166, -99, 563 -78, 228, -78, -78, -78
574 -99, -99
575}; 564};
576 565
577/* YYPGOTO[NTERM-NUM]. */ 566/* YYPGOTO[NTERM-NUM]. */
578static const short yypgoto[] = 567static const short int yypgoto[] =
579{ 568{
580 -99, -99, -99, 111, -99, -99, -99, -99, 178, -99, 569 -78, -78, -78, -78, 164, -36, -78, -78, -78, -78,
581 -99, -99, -99, 91, -99, -99, -99, -99, -99, -99, 570 230, -78, -78, -78, -78, 29, -78, -78, -78, -78,
582 -99, -99, -99, -99, 115, -99, -99, -99, -99, -99, 571 -78, -78, -78, -78, -78, -78, 59, -78, -78, -78,
583 -99, 146, 168, 89, 27, 0, 126, -1, -98, -48, 572 -78, -78, 198, 220, 24, 157, -5, 169, 202, 74,
584 -63 573 -53, -77
585}; 574};
586 575
587/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 576/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
588 positive, shift that token. If negative, reduce the rule which 577 positive, shift that token. If negative, reduce the rule which
589 number is the opposite. If zero, do what YYDEFACT says. 578 number is the opposite. If zero, do what YYDEFACT says.
590 If YYTABLE_NINF, syntax error. */ 579 If YYTABLE_NINF, syntax error. */
591#define YYTABLE_NINF -68 580#define YYTABLE_NINF -76
592static const short yytable[] = 581static const short int yytable[] =
593{ 582{
594 66, 67, 36, 42, 39, 40, 71, 41, 123, 124, 583 46, 47, 3, 49, 79, 80, 52, 133, 134, 43,
595 43, 44, 74, 75, 120, 154, 72, 46, 47, 69, 584 6, 7, 8, 9, 10, 11, 12, 13, 48, 145,
596 70, 121, 122, 48, 140, 45, 127, 128, 112, 130, 585 14, 15, 137, 55, 56, 44, 45, 57, 131, 132,
597 49, 133, 156, 135, 158, 159, 68, 161, 60, 69, 586 109, 50, 58, 122, 51, 122, 24, 138, 139, -28,
598 70, 165, 69, 70, 61, 167, 168, 62, 2, 3, 587 88, 143, -28, -28, -28, -28, -28, -28, -28, -28,
599 63, 4, 5, 6, 7, 8, 9, 10, 11, 12, 588 -28, 89, 53, -28, -28, 90, 91, -28, 92, 93,
600 46, 47, 13, 14, 139, 152, 48, 126, 178, 15, 589 94, 95, 96, 54, 97, 55, 56, 88, 161, 98,
601 16, 69, 70, 49, 37, 38, 129, 166, 151, 15, 590 -66, -66, -66, -66, -66, -66, -66, -66, 81, 82,
602 16, -67, 114, 64, -67, 5, 101, 7, 8, 102, 591 -66, -66, 90, 91, 152, 55, 56, 140, 61, 57,
603 10, 11, 12, 143, 65, 13, 103, 153, 46, 47, 592 112, 97, 84, 123, 58, 123, 121, 117, 85, 125,
604 147, 148, 149, 69, 70, 125, 172, 134, 141, 136, 593 149, 62, 167, -30, 88, 63, -30, -30, -30, -30,
605 137, 138, 15, 16, 5, 101, 7, 8, 102, 10, 594 -30, -30, -30, -30, -30, 89, 72, -30, -30, 90,
606 11, 12, 145, 146, 13, 103, 101, 7, 142, 102, 595 91, -30, 92, 93, 94, 95, 96, 119, 97, 127,
607 10, 11, 12, 171, 144, 13, 103, 69, 70, 69, 596 144, -75, 88, 98, -75, -75, -75, -75, -75, -75,
608 70, 15, 16, 100, 150, 154, 113, 108, 113, 116, 597 -75, -75, -75, 74, 75, -75, -75, 90, 91, -75,
609 73, 157, 15, 16, 74, 75, 70, 76, 77, 78, 598 -75, -75, -75, -75, -75, 76, 97, 77, 78, -2,
610 79, 80, 81, 82, 83, 84, 104, 107, 160, 115, 599 4, 121, 5, 6, 7, 8, 9, 10, 11, 12,
611 85, 110, 73, 118, 86, 87, 74, 75, 92, 93, 600 13, 86, 87, 14, 15, 16, 129, 17, 18, 19,
612 94, 95, 111, 96, 119, 162, 163, 164, 169, 170, 601 20, 21, 22, 88, 23, 135, 136, -43, -43, 24,
613 173, 174, 97, 175, 176, 177, 179, 180, 181, 53, 602 -43, -43, -43, -43, 89, 146, -43, -43, 90, 91,
614 99, 59 603 104, 105, 106, 107, 155, 7, 8, 97, 10, 11,
604 12, 13, 108, 148, 14, 15, 158, 159, 160, 147,
605 151, 81, 82, 163, 130, 165, 155, 81, 82, 82,
606 24, 113, 116, 157, 124, 171, 115, 120, 162, 128,
607 72, 81, 82, 153, 81, 82, 154, 81, 82, 166,
608 81, 82, 164, 168, 169, 170, 172, 173, 174, 65,
609 71, 83, 0, 150, 111
615}; 610};
616 611
617static const unsigned char yycheck[] = 612static const short int yycheck[] =
618{ 613{
619 48, 49, 3, 32, 4, 5, 30, 7, 71, 72, 614 5, 6, 0, 8, 57, 58, 11, 84, 85, 30,
620 10, 28, 16, 17, 33, 14, 40, 28, 29, 38, 615 4, 5, 6, 7, 8, 9, 10, 11, 30, 96,
621 39, 69, 70, 34, 87, 28, 74, 75, 32, 77, 616 14, 15, 24, 25, 26, 25, 26, 29, 81, 82,
622 41, 79, 130, 81, 132, 133, 32, 135, 39, 38, 617 66, 30, 34, 69, 30, 71, 30, 90, 91, 0,
623 39, 139, 38, 39, 32, 143, 144, 32, 0, 1, 618 1, 94, 3, 4, 5, 6, 7, 8, 9, 10,
624 32, 3, 4, 5, 6, 7, 8, 9, 10, 11, 619 11, 12, 25, 14, 15, 16, 17, 18, 19, 20,
625 28, 29, 14, 15, 28, 32, 34, 35, 166, 31, 620 21, 22, 23, 25, 25, 25, 26, 1, 145, 30,
626 32, 38, 39, 41, 28, 29, 76, 140, 126, 31, 621 4, 5, 6, 7, 8, 9, 10, 11, 31, 32,
627 32, 0, 1, 32, 3, 4, 5, 6, 7, 8, 622 14, 15, 16, 17, 137, 25, 26, 92, 30, 29,
628 9, 10, 11, 93, 32, 14, 15, 32, 28, 29, 623 66, 25, 27, 69, 34, 71, 30, 68, 33, 70,
629 101, 102, 103, 38, 39, 32, 154, 80, 13, 82, 624 105, 1, 155, 0, 1, 1, 3, 4, 5, 6,
630 83, 84, 31, 32, 4, 5, 6, 7, 8, 9, 625 7, 8, 9, 10, 11, 12, 30, 14, 15, 16,
631 10, 11, 95, 96, 14, 15, 5, 6, 32, 8, 626 17, 18, 19, 20, 21, 22, 23, 68, 25, 70,
632 9, 10, 11, 32, 28, 14, 15, 38, 39, 38, 627 25, 0, 1, 30, 3, 4, 5, 6, 7, 8,
633 39, 31, 32, 54, 32, 14, 57, 56, 59, 58, 628 9, 10, 11, 30, 30, 14, 15, 16, 17, 18,
634 12, 32, 31, 32, 16, 17, 39, 19, 20, 21, 629 19, 20, 21, 22, 23, 30, 25, 30, 30, 0,
635 22, 23, 24, 25, 26, 27, 55, 56, 32, 58, 630 1, 30, 3, 4, 5, 6, 7, 8, 9, 10,
636 32, 56, 12, 58, 36, 37, 16, 17, 18, 19, 631 11, 30, 30, 14, 15, 16, 30, 18, 19, 20,
637 20, 21, 56, 23, 58, 32, 32, 32, 32, 32, 632 21, 22, 23, 1, 25, 30, 30, 5, 6, 30,
638 32, 32, 32, 32, 32, 32, 32, 32, 32, 21, 633 8, 9, 10, 11, 12, 1, 14, 15, 16, 17,
639 54, 33 634 18, 19, 20, 21, 14, 5, 6, 25, 8, 9,
635 10, 11, 30, 30, 14, 15, 142, 143, 144, 13,
636 25, 31, 32, 149, 28, 151, 14, 31, 32, 32,
637 30, 67, 68, 30, 70, 161, 67, 68, 30, 70,
638 30, 31, 32, 30, 31, 32, 30, 31, 32, 30,
639 31, 32, 30, 30, 30, 30, 30, 30, 30, 29,
640 40, 59, -1, 106, 66
640}; 641};
641 642
642/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 643/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
643 symbol of state STATE-NUM. */ 644 symbol of state STATE-NUM. */
644static const unsigned char yystos[] = 645static const unsigned char yystos[] =
645{ 646{
646 0, 43, 0, 1, 3, 4, 5, 6, 7, 8, 647 0, 36, 37, 0, 1, 3, 4, 5, 6, 7,
647 9, 10, 11, 14, 15, 31, 32, 44, 45, 46, 648 8, 9, 10, 11, 14, 15, 16, 18, 19, 20,
648 47, 48, 49, 52, 53, 55, 59, 61, 63, 64, 649 21, 22, 23, 25, 30, 38, 39, 41, 42, 43,
649 66, 68, 69, 70, 71, 79, 79, 28, 29, 77, 650 44, 47, 48, 50, 54, 56, 58, 59, 61, 63,
650 77, 77, 32, 77, 28, 28, 28, 29, 34, 41, 651 64, 65, 72, 30, 25, 26, 71, 71, 30, 71,
651 81, 82, 50, 50, 56, 58, 62, 74, 67, 74, 652 30, 30, 71, 25, 25, 25, 26, 29, 34, 75,
652 79, 32, 32, 32, 32, 32, 81, 81, 32, 38, 653 76, 30, 1, 1, 45, 45, 51, 53, 57, 68,
653 39, 30, 40, 12, 16, 17, 19, 20, 21, 22, 654 62, 68, 30, 73, 30, 30, 30, 30, 30, 75,
654 23, 24, 25, 26, 27, 32, 36, 37, 51, 72, 655 75, 31, 32, 73, 27, 33, 30, 30, 1, 12,
655 73, 75, 18, 19, 20, 21, 23, 32, 57, 73, 656 16, 17, 19, 20, 21, 22, 23, 25, 30, 40,
656 75, 5, 8, 15, 45, 54, 78, 45, 55, 60, 657 46, 66, 67, 69, 18, 19, 20, 21, 30, 40,
657 66, 78, 32, 75, 1, 45, 55, 65, 66, 78, 658 52, 67, 69, 39, 49, 72, 39, 50, 55, 61,
658 33, 81, 81, 82, 82, 32, 35, 81, 81, 77, 659 72, 30, 40, 69, 39, 50, 60, 61, 72, 30,
659 81, 76, 77, 81, 76, 81, 76, 76, 76, 28, 660 28, 75, 75, 76, 76, 30, 30, 24, 75, 75,
660 82, 13, 32, 77, 28, 76, 76, 79, 79, 79, 661 71, 70, 71, 75, 25, 76, 1, 13, 30, 71,
661 32, 81, 32, 32, 14, 80, 80, 32, 80, 80, 662 70, 25, 75, 30, 30, 14, 74, 30, 74, 74,
662 32, 80, 32, 32, 32, 80, 82, 80, 80, 32, 663 74, 76, 30, 74, 30, 74, 30, 75, 30, 30,
663 32, 32, 81, 32, 32, 32, 32, 32, 80, 32, 664 30, 74, 30, 30, 30
664 32, 32
665}; 665};
666 666
667#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) 667#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -687,7 +687,7 @@ static const unsigned char yystos[] =
687 687
688#define YYACCEPT goto yyacceptlab 688#define YYACCEPT goto yyacceptlab
689#define YYABORT goto yyabortlab 689#define YYABORT goto yyabortlab
690#define YYERROR goto yyerrlab1 690#define YYERROR goto yyerrorlab
691 691
692 692
693/* Like YYERROR except do call yyerror. This remains here temporarily 693/* Like YYERROR except do call yyerror. This remains here temporarily
@@ -715,20 +715,53 @@ do \
715 } \ 715 } \
716while (0) 716while (0)
717 717
718
718#define YYTERROR 1 719#define YYTERROR 1
719#define YYERRCODE 256 720#define YYERRCODE 256
720 721
721/* YYLLOC_DEFAULT -- Compute the default location (before the actions
722 are run). */
723 722
723/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
724 If N is 0, then set CURRENT to the empty location which ends
725 the previous symbol: RHS[0] (always defined). */
726
727#define YYRHSLOC(Rhs, K) ((Rhs)[K])
724#ifndef YYLLOC_DEFAULT 728#ifndef YYLLOC_DEFAULT
725# define YYLLOC_DEFAULT(Current, Rhs, N) \ 729# define YYLLOC_DEFAULT(Current, Rhs, N) \
726 Current.first_line = Rhs[1].first_line; \ 730 do \
727 Current.first_column = Rhs[1].first_column; \ 731 if (N) \
728 Current.last_line = Rhs[N].last_line; \ 732 { \
729 Current.last_column = Rhs[N].last_column; 733 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
734 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
735 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
736 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
737 } \
738 else \
739 { \
740 (Current).first_line = (Current).last_line = \
741 YYRHSLOC (Rhs, 0).last_line; \
742 (Current).first_column = (Current).last_column = \
743 YYRHSLOC (Rhs, 0).last_column; \
744 } \
745 while (0)
746#endif
747
748
749/* YY_LOCATION_PRINT -- Print the location on the stream.
750 This macro was not mandated originally: define only if we know
751 we won't break user code: when these are the locations we know. */
752
753#ifndef YY_LOCATION_PRINT
754# if YYLTYPE_IS_TRIVIAL
755# define YY_LOCATION_PRINT(File, Loc) \
756 fprintf (File, "%d.%d-%d.%d", \
757 (Loc).first_line, (Loc).first_column, \
758 (Loc).last_line, (Loc).last_column)
759# else
760# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
761# endif
730#endif 762#endif
731 763
764
732/* YYLEX -- calling `yylex' with the right arguments. */ 765/* YYLEX -- calling `yylex' with the right arguments. */
733 766
734#ifdef YYLEX_PARAM 767#ifdef YYLEX_PARAM
@@ -751,36 +784,30 @@ do { \
751 YYFPRINTF Args; \ 784 YYFPRINTF Args; \
752} while (0) 785} while (0)
753 786
754# define YYDSYMPRINT(Args) \ 787# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
755do { \
756 if (yydebug) \
757 yysymprint Args; \
758} while (0)
759
760# define YYDSYMPRINTF(Title, Token, Value, Location) \
761do { \ 788do { \
762 if (yydebug) \ 789 if (yydebug) \
763 { \ 790 { \
764 YYFPRINTF (stderr, "%s ", Title); \ 791 YYFPRINTF (stderr, "%s ", Title); \
765 yysymprint (stderr, \ 792 yysymprint (stderr, \
766 Token, Value); \ 793 Type, Value); \
767 YYFPRINTF (stderr, "\n"); \ 794 YYFPRINTF (stderr, "\n"); \
768 } \ 795 } \
769} while (0) 796} while (0)
770 797
771/*------------------------------------------------------------------. 798/*------------------------------------------------------------------.
772| yy_stack_print -- Print the state stack from its BOTTOM up to its | 799| yy_stack_print -- Print the state stack from its BOTTOM up to its |
773| TOP (cinluded). | 800| TOP (included). |
774`------------------------------------------------------------------*/ 801`------------------------------------------------------------------*/
775 802
776#if defined (__STDC__) || defined (__cplusplus) 803#if defined (__STDC__) || defined (__cplusplus)
777static void 804static void
778yy_stack_print (short *bottom, short *top) 805yy_stack_print (short int *bottom, short int *top)
779#else 806#else
780static void 807static void
781yy_stack_print (bottom, top) 808yy_stack_print (bottom, top)
782 short *bottom; 809 short int *bottom;
783 short *top; 810 short int *top;
784#endif 811#endif
785{ 812{
786 YYFPRINTF (stderr, "Stack now"); 813 YYFPRINTF (stderr, "Stack now");
@@ -810,9 +837,9 @@ yy_reduce_print (yyrule)
810#endif 837#endif
811{ 838{
812 int yyi; 839 int yyi;
813 unsigned int yylineno = yyrline[yyrule]; 840 unsigned int yylno = yyrline[yyrule];
814 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", 841 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
815 yyrule - 1, yylineno); 842 yyrule - 1, yylno);
816 /* Print the symbols being reduced, and their result. */ 843 /* Print the symbols being reduced, and their result. */
817 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) 844 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
818 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); 845 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
@@ -830,8 +857,7 @@ do { \
830int yydebug; 857int yydebug;
831#else /* !YYDEBUG */ 858#else /* !YYDEBUG */
832# define YYDPRINTF(Args) 859# define YYDPRINTF(Args)
833# define YYDSYMPRINT(Args) 860# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
834# define YYDSYMPRINTF(Title, Token, Value, Location)
835# define YY_STACK_PRINT(Bottom, Top) 861# define YY_STACK_PRINT(Bottom, Top)
836# define YY_REDUCE_PRINT(Rule) 862# define YY_REDUCE_PRINT(Rule)
837#endif /* !YYDEBUG */ 863#endif /* !YYDEBUG */
@@ -849,10 +875,6 @@ int yydebug;
849 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) 875 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
850 evaluated with infinite-precision integer arithmetic. */ 876 evaluated with infinite-precision integer arithmetic. */
851 877
852#if YYMAXDEPTH == 0
853# undef YYMAXDEPTH
854#endif
855
856#ifndef YYMAXDEPTH 878#ifndef YYMAXDEPTH
857# define YYMAXDEPTH 10000 879# define YYMAXDEPTH 10000
858#endif 880#endif
@@ -934,15 +956,15 @@ yysymprint (yyoutput, yytype, yyvaluep)
934 (void) yyvaluep; 956 (void) yyvaluep;
935 957
936 if (yytype < YYNTOKENS) 958 if (yytype < YYNTOKENS)
937 { 959 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
938 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
939# ifdef YYPRINT
940 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
941# endif
942 }
943 else 960 else
944 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); 961 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
945 962
963
964# ifdef YYPRINT
965 if (yytype < YYNTOKENS)
966 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
967# endif
946 switch (yytype) 968 switch (yytype)
947 { 969 {
948 default: 970 default:
@@ -958,10 +980,11 @@ yysymprint (yyoutput, yytype, yyvaluep)
958 980
959#if defined (__STDC__) || defined (__cplusplus) 981#if defined (__STDC__) || defined (__cplusplus)
960static void 982static void
961yydestruct (int yytype, YYSTYPE *yyvaluep) 983yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
962#else 984#else
963static void 985static void
964yydestruct (yytype, yyvaluep) 986yydestruct (yymsg, yytype, yyvaluep)
987 const char *yymsg;
965 int yytype; 988 int yytype;
966 YYSTYPE *yyvaluep; 989 YYSTYPE *yyvaluep;
967#endif 990#endif
@@ -969,8 +992,42 @@ yydestruct (yytype, yyvaluep)
969 /* Pacify ``unused variable'' warnings. */ 992 /* Pacify ``unused variable'' warnings. */
970 (void) yyvaluep; 993 (void) yyvaluep;
971 994
995 if (!yymsg)
996 yymsg = "Deleting";
997 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
998
972 switch (yytype) 999 switch (yytype)
973 { 1000 {
1001 case 48: /* choice_entry */
1002
1003 {
1004 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
1005 (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
1006 if (current_menu == (yyvaluep->menu))
1007 menu_end_menu();
1008};
1009
1010 break;
1011 case 54: /* if_entry */
1012
1013 {
1014 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
1015 (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
1016 if (current_menu == (yyvaluep->menu))
1017 menu_end_menu();
1018};
1019
1020 break;
1021 case 59: /* menu_entry */
1022
1023 {
1024 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
1025 (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
1026 if (current_menu == (yyvaluep->menu))
1027 menu_end_menu();
1028};
1029
1030 break;
974 1031
975 default: 1032 default:
976 break; 1033 break;
@@ -996,10 +1053,10 @@ int yyparse ();
996 1053
997 1054
998 1055
999/* The lookahead symbol. */ 1056/* The look-ahead symbol. */
1000int yychar; 1057int yychar;
1001 1058
1002/* The semantic value of the lookahead symbol. */ 1059/* The semantic value of the look-ahead symbol. */
1003YYSTYPE yylval; 1060YYSTYPE yylval;
1004 1061
1005/* Number of syntax errors so far. */ 1062/* Number of syntax errors so far. */
@@ -1035,7 +1092,7 @@ yyparse ()
1035 int yyresult; 1092 int yyresult;
1036 /* Number of tokens to shift before error messages enabled. */ 1093 /* Number of tokens to shift before error messages enabled. */
1037 int yyerrstatus; 1094 int yyerrstatus;
1038 /* Lookahead token as an internal (translated) token number. */ 1095 /* Look-ahead token as an internal (translated) token number. */
1039 int yytoken = 0; 1096 int yytoken = 0;
1040 1097
1041 /* Three stacks and their tools: 1098 /* Three stacks and their tools:
@@ -1047,9 +1104,9 @@ yyparse ()
1047 to reallocate them elsewhere. */ 1104 to reallocate them elsewhere. */
1048 1105
1049 /* The state stack. */ 1106 /* The state stack. */
1050 short yyssa[YYINITDEPTH]; 1107 short int yyssa[YYINITDEPTH];
1051 short *yyss = yyssa; 1108 short int *yyss = yyssa;
1052 register short *yyssp; 1109 register short int *yyssp;
1053 1110
1054 /* The semantic value stack. */ 1111 /* The semantic value stack. */
1055 YYSTYPE yyvsa[YYINITDEPTH]; 1112 YYSTYPE yyvsa[YYINITDEPTH];
@@ -1086,6 +1143,9 @@ yyparse ()
1086 yyssp = yyss; 1143 yyssp = yyss;
1087 yyvsp = yyvs; 1144 yyvsp = yyvs;
1088 1145
1146
1147 yyvsp[0] = yylval;
1148
1089 goto yysetstate; 1149 goto yysetstate;
1090 1150
1091/*------------------------------------------------------------. 1151/*------------------------------------------------------------.
@@ -1111,7 +1171,7 @@ yyparse ()
1111 these so that the &'s don't force the real ones into 1171 these so that the &'s don't force the real ones into
1112 memory. */ 1172 memory. */
1113 YYSTYPE *yyvs1 = yyvs; 1173 YYSTYPE *yyvs1 = yyvs;
1114 short *yyss1 = yyss; 1174 short int *yyss1 = yyss;
1115 1175
1116 1176
1117 /* Each stack pointer address is followed by the size of the 1177 /* Each stack pointer address is followed by the size of the
@@ -1139,7 +1199,7 @@ yyparse ()
1139 yystacksize = YYMAXDEPTH; 1199 yystacksize = YYMAXDEPTH;
1140 1200
1141 { 1201 {
1142 short *yyss1 = yyss; 1202 short int *yyss1 = yyss;
1143 union yyalloc *yyptr = 1203 union yyalloc *yyptr =
1144 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); 1204 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1145 if (! yyptr) 1205 if (! yyptr)
@@ -1175,18 +1235,18 @@ yyparse ()
1175yybackup: 1235yybackup:
1176 1236
1177/* Do appropriate processing given the current state. */ 1237/* Do appropriate processing given the current state. */
1178/* Read a lookahead token if we need one and don't already have one. */ 1238/* Read a look-ahead token if we need one and don't already have one. */
1179/* yyresume: */ 1239/* yyresume: */
1180 1240
1181 /* First try to decide what to do without reference to lookahead token. */ 1241 /* First try to decide what to do without reference to look-ahead token. */
1182 1242
1183 yyn = yypact[yystate]; 1243 yyn = yypact[yystate];
1184 if (yyn == YYPACT_NINF) 1244 if (yyn == YYPACT_NINF)
1185 goto yydefault; 1245 goto yydefault;
1186 1246
1187 /* Not known => get a lookahead token if don't already have one. */ 1247 /* Not known => get a look-ahead token if don't already have one. */
1188 1248
1189 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ 1249 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1190 if (yychar == YYEMPTY) 1250 if (yychar == YYEMPTY)
1191 { 1251 {
1192 YYDPRINTF ((stderr, "Reading a token: ")); 1252 YYDPRINTF ((stderr, "Reading a token: "));
@@ -1201,7 +1261,7 @@ yybackup:
1201 else 1261 else
1202 { 1262 {
1203 yytoken = YYTRANSLATE (yychar); 1263 yytoken = YYTRANSLATE (yychar);
1204 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); 1264 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1205 } 1265 }
1206 1266
1207 /* If the proper action on seeing token YYTOKEN is to reduce or to 1267 /* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -1221,8 +1281,8 @@ yybackup:
1221 if (yyn == YYFINAL) 1281 if (yyn == YYFINAL)
1222 YYACCEPT; 1282 YYACCEPT;
1223 1283
1224 /* Shift the lookahead token. */ 1284 /* Shift the look-ahead token. */
1225 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); 1285 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1226 1286
1227 /* Discard the token being shifted unless it is eof. */ 1287 /* Discard the token being shifted unless it is eof. */
1228 if (yychar != YYEOF) 1288 if (yychar != YYEOF)
@@ -1273,155 +1333,123 @@ yyreduce:
1273 { 1333 {
1274 case 8: 1334 case 8:
1275 1335
1276 { zconfprint("unexpected 'endmenu' statement"); ;} 1336 { zconf_error("unexpected end statement"); ;}
1277 break; 1337 break;
1278 1338
1279 case 9: 1339 case 9:
1280 1340
1281 { zconfprint("unexpected 'endif' statement"); ;} 1341 { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
1282 break; 1342 break;
1283 1343
1284 case 10: 1344 case 10:
1285 1345
1286 { zconfprint("unexpected 'endchoice' statement"); ;} 1346 {
1347 zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
1348;}
1287 break; 1349 break;
1288 1350
1289 case 11: 1351 case 11:
1290 1352
1291 { zconfprint("syntax error"); yyerrok; ;} 1353 { zconf_error("invalid statement"); ;}
1292 break; 1354 break;
1293 1355
1294 case 18: 1356 case 25:
1295 1357
1296 { 1358 { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;}
1297 struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
1298 sym->flags |= SYMBOL_OPTIONAL;
1299 menu_add_entry(sym);
1300 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
1301;}
1302 break; 1359 break;
1303 1360
1304 case 19: 1361 case 26:
1305 1362
1306 { 1363 { zconf_error("invalid option"); ;}
1307 menu_end_entry();
1308 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1309;}
1310 break; 1364 break;
1311 1365
1312 case 20: 1366 case 27:
1313 1367
1314 { 1368 {
1315 struct symbol *sym = sym_lookup(yyvsp[-1].string, 0); 1369 struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
1316 sym->flags |= SYMBOL_OPTIONAL; 1370 sym->flags |= SYMBOL_OPTIONAL;
1317 menu_add_entry(sym); 1371 menu_add_entry(sym);
1318 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); 1372 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
1319;} 1373;}
1320 break; 1374 break;
1321 1375
1322 case 21: 1376 case 28:
1323 1377
1324 { 1378 {
1325 if (current_entry->prompt)
1326 current_entry->prompt->type = P_MENU;
1327 else
1328 zconfprint("warning: menuconfig statement without prompt");
1329 menu_end_entry(); 1379 menu_end_entry();
1330 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 1380 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1331;} 1381;}
1332 break; 1382 break;
1333 1383
1334 case 27:
1335
1336 {
1337 menu_set_type(S_TRISTATE);
1338 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
1339;}
1340 break;
1341
1342 case 28:
1343
1344 {
1345 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
1346 menu_set_type(S_TRISTATE);
1347 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
1348;}
1349 break;
1350
1351 case 29: 1384 case 29:
1352 1385
1353 { 1386 {
1354 menu_set_type(S_BOOLEAN); 1387 struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
1355 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); 1388 sym->flags |= SYMBOL_OPTIONAL;
1389 menu_add_entry(sym);
1390 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
1356;} 1391;}
1357 break; 1392 break;
1358 1393
1359 case 30: 1394 case 30:
1360 1395
1361 { 1396 {
1362 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); 1397 if (current_entry->prompt)
1363 menu_set_type(S_BOOLEAN); 1398 current_entry->prompt->type = P_MENU;
1364 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); 1399 else
1365;} 1400 zconfprint("warning: menuconfig statement without prompt");
1366 break; 1401 menu_end_entry();
1367 1402 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1368 case 31:
1369
1370 {
1371 menu_set_type(S_INT);
1372 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
1373;}
1374 break;
1375
1376 case 32:
1377
1378 {
1379 menu_set_type(S_HEX);
1380 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
1381;} 1403;}
1382 break; 1404 break;
1383 1405
1384 case 33: 1406 case 37:
1385 1407
1386 { 1408 {
1387 menu_set_type(S_STRING); 1409 menu_set_type((yyvsp[-2].id)->stype);
1388 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); 1410 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
1411 zconf_curname(), zconf_lineno(),
1412 (yyvsp[-2].id)->stype);
1389;} 1413;}
1390 break; 1414 break;
1391 1415
1392 case 34: 1416 case 38:
1393 1417
1394 { 1418 {
1395 menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); 1419 menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
1396 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 1420 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
1397;} 1421;}
1398 break; 1422 break;
1399 1423
1400 case 35: 1424 case 39:
1401 1425
1402 { 1426 {
1403 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); 1427 menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
1404 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 1428 if ((yyvsp[-3].id)->stype != S_UNKNOWN)
1429 menu_set_type((yyvsp[-3].id)->stype);
1430 printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
1431 zconf_curname(), zconf_lineno(),
1432 (yyvsp[-3].id)->stype);
1405;} 1433;}
1406 break; 1434 break;
1407 1435
1408 case 36: 1436 case 40:
1409 1437
1410 { 1438 {
1411 menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); 1439 menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
1412 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); 1440 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
1413;} 1441;}
1414 break; 1442 break;
1415 1443
1416 case 37: 1444 case 41:
1417 1445
1418 { 1446 {
1419 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr); 1447 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
1420 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); 1448 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
1421;} 1449;}
1422 break; 1450 break;
1423 1451
1424 case 38: 1452 case 42:
1425 1453
1426 { 1454 {
1427 struct symbol *sym = sym_lookup(NULL, 0); 1455 struct symbol *sym = sym_lookup(NULL, 0);
@@ -1432,57 +1460,45 @@ yyreduce:
1432;} 1460;}
1433 break; 1461 break;
1434 1462
1435 case 39: 1463 case 43:
1436 1464
1437 { 1465 {
1438 menu_end_entry(); 1466 (yyval.menu) = menu_add_menu();
1439 menu_add_menu();
1440;} 1467;}
1441 break; 1468 break;
1442 1469
1443 case 40: 1470 case 44:
1444 1471
1445 { 1472 {
1446 if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) { 1473 if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
1447 menu_end_menu(); 1474 menu_end_menu();
1448 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); 1475 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
1449 } 1476 }
1450;} 1477;}
1451 break; 1478 break;
1452 1479
1453 case 42: 1480 case 52:
1454
1455 {
1456 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
1457 zconfnerrs++;
1458;}
1459 break;
1460
1461 case 48:
1462 1481
1463 { 1482 {
1464 menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); 1483 menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
1465 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 1484 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
1466;} 1485;}
1467 break; 1486 break;
1468 1487
1469 case 49: 1488 case 53:
1470 1489
1471 { 1490 {
1472 menu_set_type(S_TRISTATE); 1491 if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
1473 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); 1492 menu_set_type((yyvsp[-2].id)->stype);
1493 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
1494 zconf_curname(), zconf_lineno(),
1495 (yyvsp[-2].id)->stype);
1496 } else
1497 YYERROR;
1474;} 1498;}
1475 break; 1499 break;
1476 1500
1477 case 50: 1501 case 54:
1478
1479 {
1480 menu_set_type(S_BOOLEAN);
1481 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
1482;}
1483 break;
1484
1485 case 51:
1486 1502
1487 { 1503 {
1488 current_entry->sym->flags |= SYMBOL_OPTIONAL; 1504 current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1490,115 +1506,89 @@ yyreduce:
1490;} 1506;}
1491 break; 1507 break;
1492 1508
1493 case 52: 1509 case 55:
1494 1510
1495 { 1511 {
1496 menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); 1512 if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
1497 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 1513 menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
1514 printd(DEBUG_PARSE, "%s:%d:default\n",
1515 zconf_curname(), zconf_lineno());
1516 } else
1517 YYERROR;
1498;} 1518;}
1499 break; 1519 break;
1500 1520
1501 case 55: 1521 case 58:
1502 1522
1503 { 1523 {
1504 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 1524 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
1505 menu_add_entry(NULL); 1525 menu_add_entry(NULL);
1506 menu_add_dep(yyvsp[-1].expr); 1526 menu_add_dep((yyvsp[-1].expr));
1507 menu_end_entry(); 1527 (yyval.menu) = menu_add_menu();
1508 menu_add_menu();
1509;} 1528;}
1510 break; 1529 break;
1511 1530
1512 case 56: 1531 case 59:
1513 1532
1514 { 1533 {
1515 if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) { 1534 if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
1516 menu_end_menu(); 1535 menu_end_menu();
1517 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); 1536 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
1518 } 1537 }
1519;} 1538;}
1520 break; 1539 break;
1521 1540
1522 case 58: 1541 case 65:
1523
1524 {
1525 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
1526 zconfnerrs++;
1527;}
1528 break;
1529
1530 case 63:
1531 1542
1532 { 1543 {
1533 menu_add_entry(NULL); 1544 menu_add_entry(NULL);
1534 menu_add_prompt(P_MENU, yyvsp[-1].string, NULL); 1545 menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
1535 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 1546 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
1536;} 1547;}
1537 break; 1548 break;
1538 1549
1539 case 64: 1550 case 66:
1540 1551
1541 { 1552 {
1542 menu_end_entry(); 1553 (yyval.menu) = menu_add_menu();
1543 menu_add_menu();
1544;} 1554;}
1545 break; 1555 break;
1546 1556
1547 case 65: 1557 case 67:
1548 1558
1549 { 1559 {
1550 if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) { 1560 if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
1551 menu_end_menu(); 1561 menu_end_menu();
1552 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); 1562 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
1553 } 1563 }
1554;} 1564;}
1555 break; 1565 break;
1556 1566
1557 case 67:
1558
1559 {
1560 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
1561 zconfnerrs++;
1562;}
1563 break;
1564
1565 case 72:
1566
1567 { zconfprint("invalid menu option"); yyerrok; ;}
1568 break;
1569
1570 case 73: 1567 case 73:
1571 1568
1572 { 1569 {
1573 yyval.string = yyvsp[-1].string; 1570 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
1574 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); 1571 zconf_nextfile((yyvsp[-1].string));
1575;} 1572;}
1576 break; 1573 break;
1577 1574
1578 case 74: 1575 case 74:
1579 1576
1580 { 1577 {
1581 zconf_nextfile(yyvsp[0].string);
1582;}
1583 break;
1584
1585 case 75:
1586
1587 {
1588 menu_add_entry(NULL); 1578 menu_add_entry(NULL);
1589 menu_add_prompt(P_COMMENT, yyvsp[-1].string, NULL); 1579 menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
1590 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); 1580 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
1591;} 1581;}
1592 break; 1582 break;
1593 1583
1594 case 76: 1584 case 75:
1595 1585
1596 { 1586 {
1597 menu_end_entry(); 1587 menu_end_entry();
1598;} 1588;}
1599 break; 1589 break;
1600 1590
1601 case 77: 1591 case 76:
1602 1592
1603 { 1593 {
1604 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); 1594 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1606,17 +1596,17 @@ yyreduce:
1606;} 1596;}
1607 break; 1597 break;
1608 1598
1609 case 78: 1599 case 77:
1610 1600
1611 { 1601 {
1612 current_entry->sym->help = yyvsp[0].string; 1602 current_entry->sym->help = (yyvsp[0].string);
1613;} 1603;}
1614 break; 1604 break;
1615 1605
1616 case 82: 1606 case 82:
1617 1607
1618 { 1608 {
1619 menu_add_dep(yyvsp[-1].expr); 1609 menu_add_dep((yyvsp[-1].expr));
1620 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); 1610 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
1621;} 1611;}
1622 break; 1612 break;
@@ -1624,7 +1614,7 @@ yyreduce:
1624 case 83: 1614 case 83:
1625 1615
1626 { 1616 {
1627 menu_add_dep(yyvsp[-1].expr); 1617 menu_add_dep((yyvsp[-1].expr));
1628 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); 1618 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
1629;} 1619;}
1630 break; 1620 break;
@@ -1632,7 +1622,7 @@ yyreduce:
1632 case 84: 1622 case 84:
1633 1623
1634 { 1624 {
1635 menu_add_dep(yyvsp[-1].expr); 1625 menu_add_dep((yyvsp[-1].expr));
1636 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); 1626 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
1637;} 1627;}
1638 break; 1628 break;
@@ -1640,84 +1630,84 @@ yyreduce:
1640 case 86: 1630 case 86:
1641 1631
1642 { 1632 {
1643 menu_add_prompt(P_PROMPT, yyvsp[-1].string, yyvsp[0].expr); 1633 menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
1644;} 1634;}
1645 break; 1635 break;
1646 1636
1647 case 89: 1637 case 89:
1648 1638
1649 { yyval.token = T_ENDMENU; ;} 1639 { (yyval.id) = (yyvsp[-1].id); ;}
1650 break; 1640 break;
1651 1641
1652 case 90: 1642 case 90:
1653 1643
1654 { yyval.token = T_ENDCHOICE; ;} 1644 { (yyval.id) = (yyvsp[-1].id); ;}
1655 break; 1645 break;
1656 1646
1657 case 91: 1647 case 91:
1658 1648
1659 { yyval.token = T_ENDIF; ;} 1649 { (yyval.id) = (yyvsp[-1].id); ;}
1660 break; 1650 break;
1661 1651
1662 case 94: 1652 case 94:
1663 1653
1664 { yyval.expr = NULL; ;} 1654 { (yyval.expr) = NULL; ;}
1665 break; 1655 break;
1666 1656
1667 case 95: 1657 case 95:
1668 1658
1669 { yyval.expr = yyvsp[0].expr; ;} 1659 { (yyval.expr) = (yyvsp[0].expr); ;}
1670 break; 1660 break;
1671 1661
1672 case 96: 1662 case 96:
1673 1663
1674 { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;} 1664 { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
1675 break; 1665 break;
1676 1666
1677 case 97: 1667 case 97:
1678 1668
1679 { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} 1669 { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
1680 break; 1670 break;
1681 1671
1682 case 98: 1672 case 98:
1683 1673
1684 { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} 1674 { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
1685 break; 1675 break;
1686 1676
1687 case 99: 1677 case 99:
1688 1678
1689 { yyval.expr = yyvsp[-1].expr; ;} 1679 { (yyval.expr) = (yyvsp[-1].expr); ;}
1690 break; 1680 break;
1691 1681
1692 case 100: 1682 case 100:
1693 1683
1694 { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;} 1684 { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;}
1695 break; 1685 break;
1696 1686
1697 case 101: 1687 case 101:
1698 1688
1699 { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;} 1689 { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
1700 break; 1690 break;
1701 1691
1702 case 102: 1692 case 102:
1703 1693
1704 { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;} 1694 { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
1705 break; 1695 break;
1706 1696
1707 case 103: 1697 case 103:
1708 1698
1709 { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;} 1699 { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;}
1710 break; 1700 break;
1711 1701
1712 case 104: 1702 case 104:
1713 1703
1714 { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;} 1704 { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;}
1715 break; 1705 break;
1716 1706
1717 1707
1718 } 1708 }
1719 1709
1720/* Line 999 of yacc.c. */ 1710/* Line 1037 of yacc.c. */
1721 1711
1722 1712
1723 yyvsp -= yylen; 1713 yyvsp -= yylen;
@@ -1759,18 +1749,33 @@ yyerrlab:
1759 { 1749 {
1760 YYSIZE_T yysize = 0; 1750 YYSIZE_T yysize = 0;
1761 int yytype = YYTRANSLATE (yychar); 1751 int yytype = YYTRANSLATE (yychar);
1752 const char* yyprefix;
1762 char *yymsg; 1753 char *yymsg;
1763 int yyx, yycount; 1754 int yyx;
1764 1755
1765 yycount = 0;
1766 /* Start YYX at -YYN if negative to avoid negative indexes in 1756 /* Start YYX at -YYN if negative to avoid negative indexes in
1767 YYCHECK. */ 1757 YYCHECK. */
1768 for (yyx = yyn < 0 ? -yyn : 0; 1758 int yyxbegin = yyn < 0 ? -yyn : 0;
1769 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) 1759
1760 /* Stay within bounds of both yycheck and yytname. */
1761 int yychecklim = YYLAST - yyn;
1762 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1763 int yycount = 0;
1764
1765 yyprefix = ", expecting ";
1766 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1770 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 1767 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1771 yysize += yystrlen (yytname[yyx]) + 15, yycount++; 1768 {
1772 yysize += yystrlen ("syntax error, unexpected ") + 1; 1769 yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
1773 yysize += yystrlen (yytname[yytype]); 1770 yycount += 1;
1771 if (yycount == 5)
1772 {
1773 yysize = 0;
1774 break;
1775 }
1776 }
1777 yysize += (sizeof ("syntax error, unexpected ")
1778 + yystrlen (yytname[yytype]));
1774 yymsg = (char *) YYSTACK_ALLOC (yysize); 1779 yymsg = (char *) YYSTACK_ALLOC (yysize);
1775 if (yymsg != 0) 1780 if (yymsg != 0)
1776 { 1781 {
@@ -1779,16 +1784,13 @@ yyerrlab:
1779 1784
1780 if (yycount < 5) 1785 if (yycount < 5)
1781 { 1786 {
1782 yycount = 0; 1787 yyprefix = ", expecting ";
1783 for (yyx = yyn < 0 ? -yyn : 0; 1788 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1784 yyx < (int) (sizeof (yytname) / sizeof (char *));
1785 yyx++)
1786 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 1789 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1787 { 1790 {
1788 const char *yyq = ! yycount ? ", expecting " : " or "; 1791 yyp = yystpcpy (yyp, yyprefix);
1789 yyp = yystpcpy (yyp, yyq);
1790 yyp = yystpcpy (yyp, yytname[yyx]); 1792 yyp = yystpcpy (yyp, yytname[yyx]);
1791 yycount++; 1793 yyprefix = " or ";
1792 } 1794 }
1793 } 1795 }
1794 yyerror (yymsg); 1796 yyerror (yymsg);
@@ -1806,38 +1808,57 @@ yyerrlab:
1806 1808
1807 if (yyerrstatus == 3) 1809 if (yyerrstatus == 3)
1808 { 1810 {
1809 /* If just tried and failed to reuse lookahead token after an 1811 /* If just tried and failed to reuse look-ahead token after an
1810 error, discard it. */ 1812 error, discard it. */
1811 1813
1812 /* Return failure if at end of input. */ 1814 if (yychar <= YYEOF)
1813 if (yychar == YYEOF)
1814 { 1815 {
1815 /* Pop the error token. */ 1816 /* If at end of input, pop the error token,
1816 YYPOPSTACK; 1817 then the rest of the stack, then return failure. */
1817 /* Pop the rest of the stack. */ 1818 if (yychar == YYEOF)
1818 while (yyss < yyssp) 1819 for (;;)
1819 { 1820 {
1820 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); 1821
1821 yydestruct (yystos[*yyssp], yyvsp); 1822 YYPOPSTACK;
1822 YYPOPSTACK; 1823 if (yyssp == yyss)
1823 } 1824 YYABORT;
1824 YYABORT; 1825 yydestruct ("Error: popping",
1826 yystos[*yyssp], yyvsp);
1827 }
1825 } 1828 }
1826 1829 else
1827 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); 1830 {
1828 yydestruct (yytoken, &yylval); 1831 yydestruct ("Error: discarding", yytoken, &yylval);
1829 yychar = YYEMPTY; 1832 yychar = YYEMPTY;
1830 1833 }
1831 } 1834 }
1832 1835
1833 /* Else will try to reuse lookahead token after shifting the error 1836 /* Else will try to reuse look-ahead token after shifting the error
1834 token. */ 1837 token. */
1835 goto yyerrlab1; 1838 goto yyerrlab1;
1836 1839
1837 1840
1838/*----------------------------------------------------. 1841/*---------------------------------------------------.
1839| yyerrlab1 -- error raised explicitly by an action. | 1842| yyerrorlab -- error raised explicitly by YYERROR. |
1840`----------------------------------------------------*/ 1843`---------------------------------------------------*/
1844yyerrorlab:
1845
1846#ifdef __GNUC__
1847 /* Pacify GCC when the user code never invokes YYERROR and the label
1848 yyerrorlab therefore never appears in user code. */
1849 if (0)
1850 goto yyerrorlab;
1851#endif
1852
1853yyvsp -= yylen;
1854 yyssp -= yylen;
1855 yystate = *yyssp;
1856 goto yyerrlab1;
1857
1858
1859/*-------------------------------------------------------------.
1860| yyerrlab1 -- common code for both syntax error and YYERROR. |
1861`-------------------------------------------------------------*/
1841yyerrlab1: 1862yyerrlab1:
1842 yyerrstatus = 3; /* Each real token shifted decrements this. */ 1863 yyerrstatus = 3; /* Each real token shifted decrements this. */
1843 1864
@@ -1859,22 +1880,22 @@ yyerrlab1:
1859 if (yyssp == yyss) 1880 if (yyssp == yyss)
1860 YYABORT; 1881 YYABORT;
1861 1882
1862 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1863 yydestruct (yystos[yystate], yyvsp);
1864 yyvsp--;
1865 yystate = *--yyssp;
1866 1883
1884 yydestruct ("Error: popping", yystos[yystate], yyvsp);
1885 YYPOPSTACK;
1886 yystate = *yyssp;
1867 YY_STACK_PRINT (yyss, yyssp); 1887 YY_STACK_PRINT (yyss, yyssp);
1868 } 1888 }
1869 1889
1870 if (yyn == YYFINAL) 1890 if (yyn == YYFINAL)
1871 YYACCEPT; 1891 YYACCEPT;
1872 1892
1873 YYDPRINTF ((stderr, "Shifting error token, "));
1874
1875 *++yyvsp = yylval; 1893 *++yyvsp = yylval;
1876 1894
1877 1895
1896 /* Shift the error token. */
1897 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1898
1878 yystate = yyn; 1899 yystate = yyn;
1879 goto yynewstate; 1900 goto yynewstate;
1880 1901
@@ -1890,6 +1911,9 @@ yyacceptlab:
1890| yyabortlab -- YYABORT comes here. | 1911| yyabortlab -- YYABORT comes here. |
1891`-----------------------------------*/ 1912`-----------------------------------*/
1892yyabortlab: 1913yyabortlab:
1914 yydestruct ("Error: discarding lookahead",
1915 yytoken, &yylval);
1916 yychar = YYEMPTY;
1893 yyresult = 1; 1917 yyresult = 1;
1894 goto yyreturn; 1918 goto yyreturn;
1895 1919
@@ -1927,16 +1951,16 @@ void conf_parse(const char *name)
1927 modules_sym = sym_lookup("MODULES", 0); 1951 modules_sym = sym_lookup("MODULES", 0);
1928 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); 1952 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
1929 1953
1930 //zconfdebug = 1; 1954#if YYDEBUG
1955 if (getenv("ZCONF_DEBUG"))
1956 zconfdebug = 1;
1957#endif
1931 zconfparse(); 1958 zconfparse();
1932 if (zconfnerrs) 1959 if (zconfnerrs)
1933 exit(1); 1960 exit(1);
1934 menu_finalize(&rootmenu); 1961 menu_finalize(&rootmenu);
1935 for_all_symbols(i, sym) { 1962 for_all_symbols(i, sym) {
1936 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) 1963 sym_check_deps(sym);
1937 printf("\n");
1938 else
1939 sym->flags |= SYMBOL_CHECK_DONE;
1940 } 1964 }
1941 1965
1942 sym_change_count = 1; 1966 sym_change_count = 1;
@@ -1951,20 +1975,25 @@ const char *zconf_tokenname(int token)
1951 case T_ENDCHOICE: return "endchoice"; 1975 case T_ENDCHOICE: return "endchoice";
1952 case T_IF: return "if"; 1976 case T_IF: return "if";
1953 case T_ENDIF: return "endif"; 1977 case T_ENDIF: return "endif";
1978 case T_DEPENDS: return "depends";
1954 } 1979 }
1955 return "<token>"; 1980 return "<token>";
1956} 1981}
1957 1982
1958static bool zconf_endtoken(int token, int starttoken, int endtoken) 1983static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
1959{ 1984{
1960 if (token != endtoken) { 1985 if (id->token != endtoken) {
1961 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); 1986 zconf_error("unexpected '%s' within %s block",
1987 kconf_id_strings + id->name, zconf_tokenname(starttoken));
1962 zconfnerrs++; 1988 zconfnerrs++;
1963 return false; 1989 return false;
1964 } 1990 }
1965 if (current_menu->file != current_file) { 1991 if (current_menu->file != current_file) {
1966 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); 1992 zconf_error("'%s' in different file than '%s'",
1967 zconfprint("location of the '%s'", zconf_tokenname(starttoken)); 1993 kconf_id_strings + id->name, zconf_tokenname(starttoken));
1994 fprintf(stderr, "%s:%d: location of the '%s'\n",
1995 current_menu->file->name, current_menu->lineno,
1996 zconf_tokenname(starttoken));
1968 zconfnerrs++; 1997 zconfnerrs++;
1969 return false; 1998 return false;
1970 } 1999 }
@@ -1975,7 +2004,19 @@ static void zconfprint(const char *err, ...)
1975{ 2004{
1976 va_list ap; 2005 va_list ap;
1977 2006
1978 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); 2007 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
2008 va_start(ap, err);
2009 vfprintf(stderr, err, ap);
2010 va_end(ap);
2011 fprintf(stderr, "\n");
2012}
2013
2014static void zconf_error(const char *err, ...)
2015{
2016 va_list ap;
2017
2018 zconfnerrs++;
2019 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
1979 va_start(ap, err); 2020 va_start(ap, err);
1980 vfprintf(stderr, err, ap); 2021 vfprintf(stderr, err, ap);
1981 va_end(ap); 2022 va_end(ap);
@@ -1984,7 +2025,9 @@ static void zconfprint(const char *err, ...)
1984 2025
1985static void zconferror(const char *err) 2026static void zconferror(const char *err)
1986{ 2027{
2028#if YYDEBUG
1987 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); 2029 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
2030#endif
1988} 2031}
1989 2032
1990void print_quoted_string(FILE *out, const char *str) 2033void print_quoted_string(FILE *out, const char *str)
diff --git a/scripts/kconfig/zconf.tab.h_shipped b/scripts/kconfig/zconf.tab.h_shipped
deleted file mode 100644
index 3b191ef59985..000000000000
--- a/scripts/kconfig/zconf.tab.h_shipped
+++ /dev/null
@@ -1,125 +0,0 @@
1/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
2
3/* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21/* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
25
26#ifndef BISON_ZCONF_TAB_H
27# define BISON_ZCONF_TAB_H
28
29/* Tokens. */
30#ifndef YYTOKENTYPE
31# define YYTOKENTYPE
32 /* Put the tokens into the symbol table, so that GDB and other debuggers
33 know about them. */
34 enum yytokentype {
35 T_MAINMENU = 258,
36 T_MENU = 259,
37 T_ENDMENU = 260,
38 T_SOURCE = 261,
39 T_CHOICE = 262,
40 T_ENDCHOICE = 263,
41 T_COMMENT = 264,
42 T_CONFIG = 265,
43 T_HELP = 266,
44 T_HELPTEXT = 267,
45 T_IF = 268,
46 T_ENDIF = 269,
47 T_DEPENDS = 270,
48 T_REQUIRES = 271,
49 T_OPTIONAL = 272,
50 T_PROMPT = 273,
51 T_DEFAULT = 274,
52 T_TRISTATE = 275,
53 T_BOOLEAN = 276,
54 T_INT = 277,
55 T_HEX = 278,
56 T_WORD = 279,
57 T_STRING = 280,
58 T_UNEQUAL = 281,
59 T_EOF = 282,
60 T_EOL = 283,
61 T_CLOSE_PAREN = 284,
62 T_OPEN_PAREN = 285,
63 T_ON = 286,
64 T_OR = 287,
65 T_AND = 288,
66 T_EQUAL = 289,
67 T_NOT = 290
68 };
69#endif
70#define T_MAINMENU 258
71#define T_MENU 259
72#define T_ENDMENU 260
73#define T_SOURCE 261
74#define T_CHOICE 262
75#define T_ENDCHOICE 263
76#define T_COMMENT 264
77#define T_CONFIG 265
78#define T_HELP 266
79#define T_HELPTEXT 267
80#define T_IF 268
81#define T_ENDIF 269
82#define T_DEPENDS 270
83#define T_REQUIRES 271
84#define T_OPTIONAL 272
85#define T_PROMPT 273
86#define T_DEFAULT 274
87#define T_TRISTATE 275
88#define T_BOOLEAN 276
89#define T_INT 277
90#define T_HEX 278
91#define T_WORD 279
92#define T_STRING 280
93#define T_UNEQUAL 281
94#define T_EOF 282
95#define T_EOL 283
96#define T_CLOSE_PAREN 284
97#define T_OPEN_PAREN 285
98#define T_ON 286
99#define T_OR 287
100#define T_AND 288
101#define T_EQUAL 289
102#define T_NOT 290
103
104
105
106
107#ifndef YYSTYPE
108#line 33 "zconf.y"
109typedef union {
110 int token;
111 char *string;
112 struct symbol *symbol;
113 struct expr *expr;
114 struct menu *menu;
115} yystype;
116/* Line 1281 of /usr/share/bison/yacc.c. */
117#line 118 "zconf.tab.h"
118# define YYSTYPE yystype
119#endif
120
121extern YYSTYPE zconflval;
122
123
124#endif /* not BISON_ZCONF_TAB_H */
125
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index e1a0f455d4a8..1f61fba6aa28 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -11,6 +11,11 @@
11#include <string.h> 11#include <string.h>
12#include <stdbool.h> 12#include <stdbool.h>
13 13
14#define LKC_DIRECT_LINK
15#include "lkc.h"
16
17#include "zconf.hash.c"
18
14#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 19#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
15 20
16#define PRINTD 0x0001 21#define PRINTD 0x0001
@@ -20,61 +25,59 @@ int cdebug = PRINTD;
20 25
21extern int zconflex(void); 26extern int zconflex(void);
22static void zconfprint(const char *err, ...); 27static void zconfprint(const char *err, ...);
28static void zconf_error(const char *err, ...);
23static void zconferror(const char *err); 29static void zconferror(const char *err);
24static bool zconf_endtoken(int token, int starttoken, int endtoken); 30static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
25 31
26struct symbol *symbol_hash[257]; 32struct symbol *symbol_hash[257];
27 33
28static struct menu *current_menu, *current_entry; 34static struct menu *current_menu, *current_entry;
29 35
36#define YYDEBUG 0
37#if YYDEBUG
30#define YYERROR_VERBOSE 38#define YYERROR_VERBOSE
39#endif
31%} 40%}
32%expect 40 41%expect 26
33 42
34%union 43%union
35{ 44{
36 int token;
37 char *string; 45 char *string;
46 struct file *file;
38 struct symbol *symbol; 47 struct symbol *symbol;
39 struct expr *expr; 48 struct expr *expr;
40 struct menu *menu; 49 struct menu *menu;
50 struct kconf_id *id;
41} 51}
42 52
43%token T_MAINMENU 53%token <id>T_MAINMENU
44%token T_MENU 54%token <id>T_MENU
45%token T_ENDMENU 55%token <id>T_ENDMENU
46%token T_SOURCE 56%token <id>T_SOURCE
47%token T_CHOICE 57%token <id>T_CHOICE
48%token T_ENDCHOICE 58%token <id>T_ENDCHOICE
49%token T_COMMENT 59%token <id>T_COMMENT
50%token T_CONFIG 60%token <id>T_CONFIG
51%token T_MENUCONFIG 61%token <id>T_MENUCONFIG
52%token T_HELP 62%token <id>T_HELP
53%token <string> T_HELPTEXT 63%token <string> T_HELPTEXT
54%token T_IF 64%token <id>T_IF
55%token T_ENDIF 65%token <id>T_ENDIF
56%token T_DEPENDS 66%token <id>T_DEPENDS
57%token T_REQUIRES 67%token <id>T_REQUIRES
58%token T_OPTIONAL 68%token <id>T_OPTIONAL
59%token T_PROMPT 69%token <id>T_PROMPT
60%token T_DEFAULT 70%token <id>T_TYPE
61%token T_TRISTATE 71%token <id>T_DEFAULT
62%token T_DEF_TRISTATE 72%token <id>T_SELECT
63%token T_BOOLEAN 73%token <id>T_RANGE
64%token T_DEF_BOOLEAN 74%token <id>T_ON
65%token T_STRING
66%token T_INT
67%token T_HEX
68%token <string> T_WORD 75%token <string> T_WORD
69%token <string> T_WORD_QUOTE 76%token <string> T_WORD_QUOTE
70%token T_UNEQUAL 77%token T_UNEQUAL
71%token T_EOF
72%token T_EOL
73%token T_CLOSE_PAREN 78%token T_CLOSE_PAREN
74%token T_OPEN_PAREN 79%token T_OPEN_PAREN
75%token T_ON 80%token T_EOL
76%token T_SELECT
77%token T_RANGE
78 81
79%left T_OR 82%left T_OR
80%left T_AND 83%left T_AND
@@ -82,38 +85,54 @@ static struct menu *current_menu, *current_entry;
82%nonassoc T_NOT 85%nonassoc T_NOT
83 86
84%type <string> prompt 87%type <string> prompt
85%type <string> source
86%type <symbol> symbol 88%type <symbol> symbol
87%type <expr> expr 89%type <expr> expr
88%type <expr> if_expr 90%type <expr> if_expr
89%type <token> end 91%type <id> end
92%type <id> option_name
93%type <menu> if_entry menu_entry choice_entry
94
95%destructor {
96 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
97 $$->file->name, $$->lineno);
98 if (current_menu == $$)
99 menu_end_menu();
100} if_entry menu_entry choice_entry
90 101
91%{
92#define LKC_DIRECT_LINK
93#include "lkc.h"
94%}
95%% 102%%
96input: /* empty */ 103input: stmt_list;
97 | input block 104
105stmt_list:
106 /* empty */
107 | stmt_list common_stmt
108 | stmt_list choice_stmt
109 | stmt_list menu_stmt
110 | stmt_list T_MAINMENU prompt nl
111 | stmt_list end { zconf_error("unexpected end statement"); }
112 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
113 | stmt_list option_name error T_EOL
114{
115 zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
116}
117 | stmt_list error T_EOL { zconf_error("invalid statement"); }
98; 118;
99 119
100block: common_block 120option_name:
101 | choice_stmt 121 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
102 | menu_stmt
103 | T_MAINMENU prompt nl_or_eof
104 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
105 | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
106 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
107 | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
108; 122;
109 123
110common_block: 124common_stmt:
111 if_stmt 125 T_EOL
126 | if_stmt
112 | comment_stmt 127 | comment_stmt
113 | config_stmt 128 | config_stmt
114 | menuconfig_stmt 129 | menuconfig_stmt
115 | source_stmt 130 | source_stmt
116 | nl_or_eof 131;
132
133option_error:
134 T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); }
135 | error T_EOL { zconf_error("invalid option"); }
117; 136;
118 137
119 138
@@ -156,51 +175,16 @@ config_option_list:
156 | config_option_list config_option 175 | config_option_list config_option
157 | config_option_list depends 176 | config_option_list depends
158 | config_option_list help 177 | config_option_list help
178 | config_option_list option_error
159 | config_option_list T_EOL 179 | config_option_list T_EOL
160; 180;
161 181
162config_option: T_TRISTATE prompt_stmt_opt T_EOL 182config_option: T_TYPE prompt_stmt_opt T_EOL
163{ 183{
164 menu_set_type(S_TRISTATE); 184 menu_set_type($1->stype);
165 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); 185 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
166}; 186 zconf_curname(), zconf_lineno(),
167 187 $1->stype);
168config_option: T_DEF_TRISTATE expr if_expr T_EOL
169{
170 menu_add_expr(P_DEFAULT, $2, $3);
171 menu_set_type(S_TRISTATE);
172 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
173};
174
175config_option: T_BOOLEAN prompt_stmt_opt T_EOL
176{
177 menu_set_type(S_BOOLEAN);
178 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
179};
180
181config_option: T_DEF_BOOLEAN expr if_expr T_EOL
182{
183 menu_add_expr(P_DEFAULT, $2, $3);
184 menu_set_type(S_BOOLEAN);
185 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
186};
187
188config_option: T_INT prompt_stmt_opt T_EOL
189{
190 menu_set_type(S_INT);
191 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
192};
193
194config_option: T_HEX prompt_stmt_opt T_EOL
195{
196 menu_set_type(S_HEX);
197 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
198};
199
200config_option: T_STRING prompt_stmt_opt T_EOL
201{
202 menu_set_type(S_STRING);
203 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
204}; 188};
205 189
206config_option: T_PROMPT prompt if_expr T_EOL 190config_option: T_PROMPT prompt if_expr T_EOL
@@ -212,7 +196,11 @@ config_option: T_PROMPT prompt if_expr T_EOL
212config_option: T_DEFAULT expr if_expr T_EOL 196config_option: T_DEFAULT expr if_expr T_EOL
213{ 197{
214 menu_add_expr(P_DEFAULT, $2, $3); 198 menu_add_expr(P_DEFAULT, $2, $3);
215 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 199 if ($1->stype != S_UNKNOWN)
200 menu_set_type($1->stype);
201 printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
202 zconf_curname(), zconf_lineno(),
203 $1->stype);
216}; 204};
217 205
218config_option: T_SELECT T_WORD if_expr T_EOL 206config_option: T_SELECT T_WORD if_expr T_EOL
@@ -240,8 +228,7 @@ choice: T_CHOICE T_EOL
240 228
241choice_entry: choice choice_option_list 229choice_entry: choice choice_option_list
242{ 230{
243 menu_end_entry(); 231 $$ = menu_add_menu();
244 menu_add_menu();
245}; 232};
246 233
247choice_end: end 234choice_end: end
@@ -252,13 +239,8 @@ choice_end: end
252 } 239 }
253}; 240};
254 241
255choice_stmt: 242choice_stmt: choice_entry choice_block choice_end
256 choice_entry choice_block choice_end 243;
257 | choice_entry choice_block
258{
259 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
260 zconfnerrs++;
261};
262 244
263choice_option_list: 245choice_option_list:
264 /* empty */ 246 /* empty */
@@ -266,6 +248,7 @@ choice_option_list:
266 | choice_option_list depends 248 | choice_option_list depends
267 | choice_option_list help 249 | choice_option_list help
268 | choice_option_list T_EOL 250 | choice_option_list T_EOL
251 | choice_option_list option_error
269; 252;
270 253
271choice_option: T_PROMPT prompt if_expr T_EOL 254choice_option: T_PROMPT prompt if_expr T_EOL
@@ -274,16 +257,15 @@ choice_option: T_PROMPT prompt if_expr T_EOL
274 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 257 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
275}; 258};
276 259
277choice_option: T_TRISTATE prompt_stmt_opt T_EOL 260choice_option: T_TYPE prompt_stmt_opt T_EOL
278{
279 menu_set_type(S_TRISTATE);
280 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
281};
282
283choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
284{ 261{
285 menu_set_type(S_BOOLEAN); 262 if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
286 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); 263 menu_set_type($1->stype);
264 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
265 zconf_curname(), zconf_lineno(),
266 $1->stype);
267 } else
268 YYERROR;
287}; 269};
288 270
289choice_option: T_OPTIONAL T_EOL 271choice_option: T_OPTIONAL T_EOL
@@ -294,24 +276,27 @@ choice_option: T_OPTIONAL T_EOL
294 276
295choice_option: T_DEFAULT T_WORD if_expr T_EOL 277choice_option: T_DEFAULT T_WORD if_expr T_EOL
296{ 278{
297 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); 279 if ($1->stype == S_UNKNOWN) {
298 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 280 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
281 printd(DEBUG_PARSE, "%s:%d:default\n",
282 zconf_curname(), zconf_lineno());
283 } else
284 YYERROR;
299}; 285};
300 286
301choice_block: 287choice_block:
302 /* empty */ 288 /* empty */
303 | choice_block common_block 289 | choice_block common_stmt
304; 290;
305 291
306/* if entry */ 292/* if entry */
307 293
308if: T_IF expr T_EOL 294if_entry: T_IF expr nl
309{ 295{
310 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 296 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
311 menu_add_entry(NULL); 297 menu_add_entry(NULL);
312 menu_add_dep($2); 298 menu_add_dep($2);
313 menu_end_entry(); 299 $$ = menu_add_menu();
314 menu_add_menu();
315}; 300};
316 301
317if_end: end 302if_end: end
@@ -322,17 +307,12 @@ if_end: end
322 } 307 }
323}; 308};
324 309
325if_stmt: 310if_stmt: if_entry if_block if_end
326 if if_block if_end 311;
327 | if if_block
328{
329 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
330 zconfnerrs++;
331};
332 312
333if_block: 313if_block:
334 /* empty */ 314 /* empty */
335 | if_block common_block 315 | if_block common_stmt
336 | if_block menu_stmt 316 | if_block menu_stmt
337 | if_block choice_stmt 317 | if_block choice_stmt
338; 318;
@@ -348,8 +328,7 @@ menu: T_MENU prompt T_EOL
348 328
349menu_entry: menu depends_list 329menu_entry: menu depends_list
350{ 330{
351 menu_end_entry(); 331 $$ = menu_add_menu();
352 menu_add_menu();
353}; 332};
354 333
355menu_end: end 334menu_end: end
@@ -360,31 +339,20 @@ menu_end: end
360 } 339 }
361}; 340};
362 341
363menu_stmt: 342menu_stmt: menu_entry menu_block menu_end
364 menu_entry menu_block menu_end 343;
365 | menu_entry menu_block
366{
367 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
368 zconfnerrs++;
369};
370 344
371menu_block: 345menu_block:
372 /* empty */ 346 /* empty */
373 | menu_block common_block 347 | menu_block common_stmt
374 | menu_block menu_stmt 348 | menu_block menu_stmt
375 | menu_block choice_stmt 349 | menu_block choice_stmt
376 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
377; 350;
378 351
379source: T_SOURCE prompt T_EOL 352source_stmt: T_SOURCE prompt T_EOL
380{ 353{
381 $$ = $2;
382 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); 354 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
383}; 355 zconf_nextfile($2);
384
385source_stmt: source
386{
387 zconf_nextfile($1);
388}; 356};
389 357
390/* comment entry */ 358/* comment entry */
@@ -416,9 +384,11 @@ help: help_start T_HELPTEXT
416 384
417/* depends option */ 385/* depends option */
418 386
419depends_list: /* empty */ 387depends_list:
420 | depends_list depends 388 /* empty */
421 | depends_list T_EOL 389 | depends_list depends
390 | depends_list T_EOL
391 | depends_list option_error
422; 392;
423 393
424depends: T_DEPENDS T_ON expr T_EOL 394depends: T_DEPENDS T_ON expr T_EOL
@@ -450,13 +420,15 @@ prompt: T_WORD
450 | T_WORD_QUOTE 420 | T_WORD_QUOTE
451; 421;
452 422
453end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; } 423end: T_ENDMENU T_EOL { $$ = $1; }
454 | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; } 424 | T_ENDCHOICE T_EOL { $$ = $1; }
455 | T_ENDIF nl_or_eof { $$ = T_ENDIF; } 425 | T_ENDIF T_EOL { $$ = $1; }
456; 426;
457 427
458nl_or_eof: 428nl:
459 T_EOL | T_EOF; 429 T_EOL
430 | nl T_EOL
431;
460 432
461if_expr: /* empty */ { $$ = NULL; } 433if_expr: /* empty */ { $$ = NULL; }
462 | T_IF expr { $$ = $2; } 434 | T_IF expr { $$ = $2; }
@@ -489,16 +461,16 @@ void conf_parse(const char *name)
489 modules_sym = sym_lookup("MODULES", 0); 461 modules_sym = sym_lookup("MODULES", 0);
490 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); 462 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
491 463
492 //zconfdebug = 1; 464#if YYDEBUG
465 if (getenv("ZCONF_DEBUG"))
466 zconfdebug = 1;
467#endif
493 zconfparse(); 468 zconfparse();
494 if (zconfnerrs) 469 if (zconfnerrs)
495 exit(1); 470 exit(1);
496 menu_finalize(&rootmenu); 471 menu_finalize(&rootmenu);
497 for_all_symbols(i, sym) { 472 for_all_symbols(i, sym) {
498 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) 473 sym_check_deps(sym);
499 printf("\n");
500 else
501 sym->flags |= SYMBOL_CHECK_DONE;
502 } 474 }
503 475
504 sym_change_count = 1; 476 sym_change_count = 1;
@@ -513,20 +485,25 @@ const char *zconf_tokenname(int token)
513 case T_ENDCHOICE: return "endchoice"; 485 case T_ENDCHOICE: return "endchoice";
514 case T_IF: return "if"; 486 case T_IF: return "if";
515 case T_ENDIF: return "endif"; 487 case T_ENDIF: return "endif";
488 case T_DEPENDS: return "depends";
516 } 489 }
517 return "<token>"; 490 return "<token>";
518} 491}
519 492
520static bool zconf_endtoken(int token, int starttoken, int endtoken) 493static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
521{ 494{
522 if (token != endtoken) { 495 if (id->token != endtoken) {
523 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); 496 zconf_error("unexpected '%s' within %s block",
497 kconf_id_strings + id->name, zconf_tokenname(starttoken));
524 zconfnerrs++; 498 zconfnerrs++;
525 return false; 499 return false;
526 } 500 }
527 if (current_menu->file != current_file) { 501 if (current_menu->file != current_file) {
528 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); 502 zconf_error("'%s' in different file than '%s'",
529 zconfprint("location of the '%s'", zconf_tokenname(starttoken)); 503 kconf_id_strings + id->name, zconf_tokenname(starttoken));
504 fprintf(stderr, "%s:%d: location of the '%s'\n",
505 current_menu->file->name, current_menu->lineno,
506 zconf_tokenname(starttoken));
530 zconfnerrs++; 507 zconfnerrs++;
531 return false; 508 return false;
532 } 509 }
@@ -537,7 +514,19 @@ static void zconfprint(const char *err, ...)
537{ 514{
538 va_list ap; 515 va_list ap;
539 516
540 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); 517 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
518 va_start(ap, err);
519 vfprintf(stderr, err, ap);
520 va_end(ap);
521 fprintf(stderr, "\n");
522}
523
524static void zconf_error(const char *err, ...)
525{
526 va_list ap;
527
528 zconfnerrs++;
529 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
541 va_start(ap, err); 530 va_start(ap, err);
542 vfprintf(stderr, err, ap); 531 vfprintf(stderr, err, ap);
543 va_end(ap); 532 va_end(ap);
@@ -546,7 +535,9 @@ static void zconfprint(const char *err, ...)
546 535
547static void zconferror(const char *err) 536static void zconferror(const char *err)
548{ 537{
538#if YYDEBUG
549 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); 539 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
540#endif
550} 541}
551 542
552void print_quoted_string(FILE *out, const char *str) 543void print_quoted_string(FILE *out, const char *str)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 45c41490d521..fc774436a264 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1986,6 +1986,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1986 1986
1987 inode_security_set_sid(inode, newsid); 1987 inode_security_set_sid(inode, newsid);
1988 1988
1989 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
1990 return -EOPNOTSUPP;
1991
1989 if (name) { 1992 if (name) {
1990 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL); 1993 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
1991 if (!namep) 1994 if (!namep)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index fdc382389720..0e1352a555c8 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -271,46 +271,38 @@ static struct file_operations sel_load_ops = {
271 .write = sel_write_load, 271 .write = sel_write_load,
272}; 272};
273 273
274 274static ssize_t sel_write_context(struct file * file, char *buf, size_t size)
275static ssize_t sel_write_context(struct file * file, const char __user * buf,
276 size_t count, loff_t *ppos)
277
278{ 275{
279 char *page; 276 char *canon;
280 u32 sid; 277 u32 sid, len;
281 ssize_t length; 278 ssize_t length;
282 279
283 length = task_has_security(current, SECURITY__CHECK_CONTEXT); 280 length = task_has_security(current, SECURITY__CHECK_CONTEXT);
284 if (length) 281 if (length)
285 return length; 282 return length;
286 283
287 if (count >= PAGE_SIZE) 284 length = security_context_to_sid(buf, size, &sid);
288 return -ENOMEM; 285 if (length < 0)
289 if (*ppos != 0) { 286 return length;
290 /* No partial writes. */
291 return -EINVAL;
292 }
293 page = (char*)get_zeroed_page(GFP_KERNEL);
294 if (!page)
295 return -ENOMEM;
296 length = -EFAULT;
297 if (copy_from_user(page, buf, count))
298 goto out;
299 287
300 length = security_context_to_sid(page, count, &sid); 288 length = security_sid_to_context(sid, &canon, &len);
301 if (length < 0) 289 if (length < 0)
290 return length;
291
292 if (len > SIMPLE_TRANSACTION_LIMIT) {
293 printk(KERN_ERR "%s: context size (%u) exceeds payload "
294 "max\n", __FUNCTION__, len);
295 length = -ERANGE;
302 goto out; 296 goto out;
297 }
303 298
304 length = count; 299 memcpy(buf, canon, len);
300 length = len;
305out: 301out:
306 free_page((unsigned long) page); 302 kfree(canon);
307 return length; 303 return length;
308} 304}
309 305
310static struct file_operations sel_context_ops = {
311 .write = sel_write_context,
312};
313
314static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, 306static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
315 size_t count, loff_t *ppos) 307 size_t count, loff_t *ppos)
316{ 308{
@@ -375,6 +367,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
375 [SEL_RELABEL] = sel_write_relabel, 367 [SEL_RELABEL] = sel_write_relabel,
376 [SEL_USER] = sel_write_user, 368 [SEL_USER] = sel_write_user,
377 [SEL_MEMBER] = sel_write_member, 369 [SEL_MEMBER] = sel_write_member,
370 [SEL_CONTEXT] = sel_write_context,
378}; 371};
379 372
380static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) 373static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -1220,7 +1213,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1220 static struct tree_descr selinux_files[] = { 1213 static struct tree_descr selinux_files[] = {
1221 [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR}, 1214 [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
1222 [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR}, 1215 [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
1223 [SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO}, 1216 [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
1224 [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO}, 1217 [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
1225 [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO}, 1218 [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
1226 [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO}, 1219 [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index aaefac2921f1..640d0bfdbc68 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -262,8 +262,11 @@ int mls_context_to_sid(char oldc,
262 struct cat_datum *catdatum, *rngdatum; 262 struct cat_datum *catdatum, *rngdatum;
263 int l, rc = -EINVAL; 263 int l, rc = -EINVAL;
264 264
265 if (!selinux_mls_enabled) 265 if (!selinux_mls_enabled) {
266 if (def_sid != SECSID_NULL && oldc)
267 *scontext += strlen(*scontext);
266 return 0; 268 return 0;
269 }
267 270
268 /* 271 /*
269 * No MLS component to the security context, try and map to 272 * No MLS component to the security context, try and map to
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 9a3dc3c3b3de..c4993b004c42 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -23,6 +23,7 @@
23#include <sound/driver.h> 23#include <sound/driver.h>
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/firmware.h> 25#include <linux/firmware.h>
26#include <linux/vmalloc.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/hwdep.h> 28#include <sound/hwdep.h>
28#include <sound/vx_core.h> 29#include <sound/vx_core.h>
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 953e5f3ea03d..88e52dc84c09 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -4,9 +4,24 @@
4# More hacking for modularisation. 4# More hacking for modularisation.
5# 5#
6# Prompt user for primary drivers. 6# Prompt user for primary drivers.
7
8config OBSOLETE_OSS_DRIVER
9 bool "Obsolete OSS drivers"
10 depends on SOUND_PRIME
11 help
12 This option enables support for obsolete OSS drivers that
13 are scheduled for removal in the near future since there
14 are ALSA drivers for the same hardware.
15
16 Please contact Adrian Bunk <bunk@stusta.de> if you had to
17 say Y here because your soundcard is not properly supported
18 by ALSA.
19
20 If unsure, say N.
21
7config SOUND_BT878 22config SOUND_BT878
8 tristate "BT878 audio dma" 23 tristate "BT878 audio dma"
9 depends on SOUND_PRIME && PCI 24 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
10 ---help--- 25 ---help---
11 Audio DMA support for bt878 based grabber boards. As you might have 26 Audio DMA support for bt878 based grabber boards. As you might have
12 already noticed, bt878 is listed with two functions in /proc/pci. 27 already noticed, bt878 is listed with two functions in /proc/pci.
@@ -22,7 +37,7 @@ config SOUND_BT878
22 37
23config SOUND_CMPCI 38config SOUND_CMPCI
24 tristate "C-Media PCI (CMI8338/8738)" 39 tristate "C-Media PCI (CMI8338/8738)"
25 depends on SOUND_PRIME && PCI 40 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
26 help 41 help
27 Say Y or M if you have a PCI sound card using the CMI8338 42 Say Y or M if you have a PCI sound card using the CMI8338
28 or the CMI8738 chipset. Data on these chips are available at 43 or the CMI8738 chipset. Data on these chips are available at
@@ -61,7 +76,7 @@ config SOUND_CMPCI_JOYSTICK
61 76
62config SOUND_EMU10K1 77config SOUND_EMU10K1
63 tristate "Creative SBLive! (EMU10K1)" 78 tristate "Creative SBLive! (EMU10K1)"
64 depends on SOUND_PRIME && PCI 79 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
65 ---help--- 80 ---help---
66 Say Y or M if you have a PCI sound card using the EMU10K1 chipset, 81 Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
67 such as the Creative SBLive!, SB PCI512 or Emu-APS. 82 such as the Creative SBLive!, SB PCI512 or Emu-APS.
@@ -95,7 +110,7 @@ config SOUND_FUSION
95 110
96config SOUND_CS4281 111config SOUND_CS4281
97 tristate "Crystal Sound CS4281" 112 tristate "Crystal Sound CS4281"
98 depends on SOUND_PRIME && PCI 113 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
99 help 114 help
100 Picture and feature list at 115 Picture and feature list at
101 <http://www.pcbroker.com/crystal4281.html>. 116 <http://www.pcbroker.com/crystal4281.html>.
@@ -112,7 +127,7 @@ config SOUND_BCM_CS4297A
112 127
113config SOUND_ES1370 128config SOUND_ES1370
114 tristate "Ensoniq AudioPCI (ES1370)" 129 tristate "Ensoniq AudioPCI (ES1370)"
115 depends on SOUND_PRIME && PCI 130 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
116 help 131 help
117 Say Y or M if you have a PCI sound card utilizing the Ensoniq 132 Say Y or M if you have a PCI sound card utilizing the Ensoniq
118 ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find 133 ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find
@@ -125,7 +140,7 @@ config SOUND_ES1370
125 140
126config SOUND_ES1371 141config SOUND_ES1371
127 tristate "Creative Ensoniq AudioPCI 97 (ES1371)" 142 tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
128 depends on SOUND_PRIME && PCI 143 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
129 help 144 help
130 Say Y or M if you have a PCI sound card utilizing the Ensoniq 145 Say Y or M if you have a PCI sound card utilizing the Ensoniq
131 ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if 146 ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
@@ -138,7 +153,7 @@ config SOUND_ES1371
138 153
139config SOUND_ESSSOLO1 154config SOUND_ESSSOLO1
140 tristate "ESS Technology Solo1" 155 tristate "ESS Technology Solo1"
141 depends on SOUND_PRIME && PCI 156 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
142 help 157 help
143 Say Y or M if you have a PCI sound card utilizing the ESS Technology 158 Say Y or M if you have a PCI sound card utilizing the ESS Technology
144 Solo1 chip. To find out if your sound card uses a 159 Solo1 chip. To find out if your sound card uses a
@@ -149,7 +164,7 @@ config SOUND_ESSSOLO1
149 164
150config SOUND_MAESTRO 165config SOUND_MAESTRO
151 tristate "ESS Maestro, Maestro2, Maestro2E driver" 166 tristate "ESS Maestro, Maestro2, Maestro2E driver"
152 depends on SOUND_PRIME && PCI 167 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
153 help 168 help
154 Say Y or M if you have a sound system driven by ESS's Maestro line 169 Say Y or M if you have a sound system driven by ESS's Maestro line
155 of PCI sound chips. These include the Maestro 1, Maestro 2, and 170 of PCI sound chips. These include the Maestro 1, Maestro 2, and
@@ -158,7 +173,7 @@ config SOUND_MAESTRO
158 173
159config SOUND_MAESTRO3 174config SOUND_MAESTRO3
160 tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)" 175 tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)"
161 depends on SOUND_PRIME && PCI && EXPERIMENTAL 176 depends on SOUND_PRIME && PCI && EXPERIMENTAL && OBSOLETE_OSS_DRIVER
162 help 177 help
163 Say Y or M if you have a sound system driven by ESS's Maestro 3 178 Say Y or M if you have a sound system driven by ESS's Maestro 3
164 PCI sound chip. 179 PCI sound chip.
@@ -172,14 +187,14 @@ config SOUND_ICH
172 187
173config SOUND_HARMONY 188config SOUND_HARMONY
174 tristate "PA Harmony audio driver" 189 tristate "PA Harmony audio driver"
175 depends on GSC_LASI && SOUND_PRIME 190 depends on GSC_LASI && SOUND_PRIME && OBSOLETE_OSS_DRIVER
176 help 191 help
177 Say 'Y' or 'M' to include support for Harmony soundchip 192 Say 'Y' or 'M' to include support for Harmony soundchip
178 on HP 712, 715/new and many other GSC based machines. 193 on HP 712, 715/new and many other GSC based machines.
179 194
180config SOUND_SONICVIBES 195config SOUND_SONICVIBES
181 tristate "S3 SonicVibes" 196 tristate "S3 SonicVibes"
182 depends on SOUND_PRIME && PCI 197 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
183 help 198 help
184 Say Y or M if you have a PCI sound card utilizing the S3 199 Say Y or M if you have a PCI sound card utilizing the S3
185 SonicVibes chipset. To find out if your sound card uses a 200 SonicVibes chipset. To find out if your sound card uses a
@@ -218,7 +233,7 @@ config SOUND_VRC5477
218 233
219config SOUND_AU1000 234config SOUND_AU1000
220 tristate "Au1000 Sound" 235 tristate "Au1000 Sound"
221 depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) 236 depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && OBSOLETE_OSS_DRIVER
222 237
223config SOUND_AU1550_AC97 238config SOUND_AU1550_AC97
224 tristate "Au1550 AC97 Sound" 239 tristate "Au1550 AC97 Sound"
@@ -492,7 +507,7 @@ config MSND_FIFOSIZE
492 507
493config SOUND_VIA82CXXX 508config SOUND_VIA82CXXX
494 tristate "VIA 82C686 Audio Codec" 509 tristate "VIA 82C686 Audio Codec"
495 depends on SOUND_PRIME && PCI 510 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
496 help 511 help
497 Say Y here to include support for the audio codec found on VIA 512 Say Y here to include support for the audio codec found on VIA
498 82Cxxx-based chips. Typically these are built into a motherboard. 513 82Cxxx-based chips. Typically these are built into a motherboard.
@@ -563,7 +578,7 @@ config SOUND_AD1889
563 578
564config SOUND_SGALAXY 579config SOUND_SGALAXY
565 tristate "Aztech Sound Galaxy (non-PnP) cards" 580 tristate "Aztech Sound Galaxy (non-PnP) cards"
566 depends on SOUND_OSS 581 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
567 help 582 help
568 This module initializes the older non Plug and Play sound galaxy 583 This module initializes the older non Plug and Play sound galaxy
569 cards from Aztech. It supports the Waverider Pro 32 - 3D and the 584 cards from Aztech. It supports the Waverider Pro 32 - 3D and the
@@ -599,7 +614,7 @@ config SOUND_ACI_MIXER
599 614
600config SOUND_CS4232 615config SOUND_CS4232
601 tristate "Crystal CS4232 based (PnP) cards" 616 tristate "Crystal CS4232 based (PnP) cards"
602 depends on SOUND_OSS 617 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
603 help 618 help
604 Say Y here if you have a card based on the Crystal CS4232 chip set, 619 Say Y here if you have a card based on the Crystal CS4232 chip set,
605 which uses its own Plug and Play protocol. 620 which uses its own Plug and Play protocol.
@@ -613,7 +628,7 @@ config SOUND_CS4232
613 628
614config SOUND_SSCAPE 629config SOUND_SSCAPE
615 tristate "Ensoniq SoundScape support" 630 tristate "Ensoniq SoundScape support"
616 depends on SOUND_OSS 631 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
617 help 632 help
618 Answer Y if you have a sound card based on the Ensoniq SoundScape 633 Answer Y if you have a sound card based on the Ensoniq SoundScape
619 chipset. Such cards are being manufactured at least by Ensoniq, Spea 634 chipset. Such cards are being manufactured at least by Ensoniq, Spea
@@ -625,7 +640,7 @@ config SOUND_SSCAPE
625 640
626config SOUND_GUS 641config SOUND_GUS
627 tristate "Gravis Ultrasound support" 642 tristate "Gravis Ultrasound support"
628 depends on SOUND_OSS 643 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
629 help 644 help
630 Say Y here for any type of Gravis Ultrasound card, including the GUS 645 Say Y here for any type of Gravis Ultrasound card, including the GUS
631 or GUS MAX. See also <file:Documentation/sound/oss/ultrasound> for more 646 or GUS MAX. See also <file:Documentation/sound/oss/ultrasound> for more
@@ -727,7 +742,7 @@ config SOUND_MPU401
727 742
728config SOUND_NM256 743config SOUND_NM256
729 tristate "NM256AV/NM256ZX audio support" 744 tristate "NM256AV/NM256ZX audio support"
730 depends on SOUND_OSS 745 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
731 help 746 help
732 Say M here to include audio support for the NeoMagic 256AV/256ZX 747 Say M here to include audio support for the NeoMagic 256AV/256ZX
733 chipsets. These are the audio chipsets found in the Sony 748 chipsets. These are the audio chipsets found in the Sony
@@ -739,7 +754,7 @@ config SOUND_NM256
739 754
740config SOUND_MAD16 755config SOUND_MAD16
741 tristate "OPTi MAD16 and/or Mozart based cards" 756 tristate "OPTi MAD16 and/or Mozart based cards"
742 depends on SOUND_OSS 757 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
743 ---help--- 758 ---help---
744 Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi 759 Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi
745 82C928 or 82C929 or 82C931) audio interface chip. These chips are 760 82C928 or 82C929 or 82C931) audio interface chip. These chips are
@@ -860,7 +875,7 @@ config SOUND_SB
860 875
861config SOUND_AWE32_SYNTH 876config SOUND_AWE32_SYNTH
862 tristate "AWE32 synth" 877 tristate "AWE32 synth"
863 depends on SOUND_OSS 878 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
864 help 879 help
865 Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or 880 Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
866 similar sound card. See <file:Documentation/sound/oss/README.awe>, 881 similar sound card. See <file:Documentation/sound/oss/README.awe>,
@@ -870,7 +885,7 @@ config SOUND_AWE32_SYNTH
870 885
871config SOUND_WAVEFRONT 886config SOUND_WAVEFRONT
872 tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards" 887 tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards"
873 depends on SOUND_OSS && m 888 depends on SOUND_OSS && m && OBSOLETE_OSS_DRIVER
874 help 889 help
875 Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card 890 Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card
876 and read the files <file:Documentation/sound/oss/Wavefront> and 891 and read the files <file:Documentation/sound/oss/Wavefront> and
@@ -878,7 +893,7 @@ config SOUND_WAVEFRONT
878 893
879config SOUND_MAUI 894config SOUND_MAUI
880 tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers" 895 tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers"
881 depends on SOUND_OSS 896 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
882 help 897 help
883 Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez 898 Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez
884 sound card. 899 sound card.
@@ -904,7 +919,7 @@ config MAUI_BOOT_FILE
904 919
905config SOUND_YM3812 920config SOUND_YM3812
906 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support" 921 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support"
907 depends on SOUND_OSS 922 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
908 ---help--- 923 ---help---
909 Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). 924 Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
910 Answering Y is usually a safe and recommended choice, however some 925 Answering Y is usually a safe and recommended choice, however some
@@ -920,7 +935,7 @@ config SOUND_YM3812
920 935
921config SOUND_OPL3SA1 936config SOUND_OPL3SA1
922 tristate "Yamaha OPL3-SA1 audio controller" 937 tristate "Yamaha OPL3-SA1 audio controller"
923 depends on SOUND_OSS 938 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
924 help 939 help
925 Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is 940 Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is
926 usually built into motherboards. Read 941 usually built into motherboards. Read
@@ -946,7 +961,7 @@ config SOUND_OPL3SA2
946 961
947config SOUND_YMFPCI 962config SOUND_YMFPCI
948 tristate "Yamaha YMF7xx PCI audio (native mode)" 963 tristate "Yamaha YMF7xx PCI audio (native mode)"
949 depends on SOUND_OSS && PCI 964 depends on SOUND_OSS && PCI && OBSOLETE_OSS_DRIVER
950 help 965 help
951 Support for Yamaha cards including the YMF711, YMF715, YMF718, 966 Support for Yamaha cards including the YMF711, YMF715, YMF718,
952 YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital. 967 YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital.
@@ -1088,11 +1103,11 @@ config SOUND_KAHLUA
1088 1103
1089config SOUND_ALI5455 1104config SOUND_ALI5455
1090 tristate "ALi5455 audio support" 1105 tristate "ALi5455 audio support"
1091 depends on SOUND_PRIME && PCI 1106 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
1092 1107
1093config SOUND_FORTE 1108config SOUND_FORTE
1094 tristate "ForteMedia FM801 driver" 1109 tristate "ForteMedia FM801 driver"
1095 depends on SOUND_PRIME && PCI 1110 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
1096 help 1111 help
1097 Say Y or M if you want driver support for the ForteMedia FM801 PCI 1112 Say Y or M if you want driver support for the ForteMedia FM801 PCI
1098 audio controller (Abit AU10, Genius Sound Maker, HP Workstation 1113 audio controller (Abit AU10, Genius Sound Maker, HP Workstation
@@ -1100,7 +1115,7 @@ config SOUND_FORTE
1100 1115
1101config SOUND_RME96XX 1116config SOUND_RME96XX
1102 tristate "RME Hammerfall (RME96XX) support" 1117 tristate "RME Hammerfall (RME96XX) support"
1103 depends on SOUND_PRIME && PCI 1118 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
1104 help 1119 help
1105 Say Y or M if you have a Hammerfall or Hammerfall light 1120 Say Y or M if you have a Hammerfall or Hammerfall light
1106 multichannel card from RME. If you want to access advanced 1121 multichannel card from RME. If you want to access advanced
@@ -1108,7 +1123,7 @@ config SOUND_RME96XX
1108 1123
1109config SOUND_AD1980 1124config SOUND_AD1980
1110 tristate "AD1980 front/back switch plugin" 1125 tristate "AD1980 front/back switch plugin"
1111 depends on SOUND_PRIME 1126 depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER
1112 1127
1113config SOUND_SH_DAC_AUDIO 1128config SOUND_SH_DAC_AUDIO
1114 tristate "SuperH DAC audio support" 1129 tristate "SuperH DAC audio support"
diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c
index 4f1ff1bccdce..a7ad2b0a2ac0 100644
--- a/sound/oss/msnd.c
+++ b/sound/oss/msnd.c
@@ -24,7 +24,6 @@
24 * 24 *
25 ********************************************************************/ 25 ********************************************************************/
26 26
27#include <linux/version.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/kernel.h> 28#include <linux/kernel.h>
30#include <linux/slab.h> 29#include <linux/slab.h>
diff --git a/sound/oss/os.h b/sound/oss/os.h
index 80dce329cc3a..0490562c7f7f 100644
--- a/sound/oss/os.h
+++ b/sound/oss/os.h
@@ -5,10 +5,8 @@
5#undef DO_TIMINGS 5#undef DO_TIMINGS
6 6
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/version.h>
9 8
10#ifdef __KERNEL__ 9#ifdef __KERNEL__
11#include <linux/utsname.h>
12#include <linux/string.h> 10#include <linux/string.h>
13#include <linux/fs.h> 11#include <linux/fs.h>
14#include <asm/dma.h> 12#include <asm/dma.h>
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
index 7609c68a89f4..318dc51009fe 100644
--- a/sound/oss/rme96xx.c
+++ b/sound/oss/rme96xx.c
@@ -44,7 +44,6 @@ TODO:
44#define RMEVERSION "0.8" 44#define RMEVERSION "0.8"
45#endif 45#endif
46 46
47#include <linux/version.h>
48#include <linux/module.h> 47#include <linux/module.h>
49#include <linux/string.h> 48#include <linux/string.h>
50#include <linux/sched.h> 49#include <linux/sched.h>
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index c09cdeedc191..8a9917c919c2 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -2,7 +2,6 @@
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/linkage.h> 5#include <linux/linkage.h>
7#include <linux/slab.h> 6#include <linux/slab.h>
8#include <linux/fs.h> 7#include <linux/fs.h>
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index e72ccd1a004f..1fdae678a345 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -1067,7 +1067,6 @@ MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
1067 1067
1068static struct pci_driver ad1889_pci = { 1068static struct pci_driver ad1889_pci = {
1069 .name = "AD1889 Audio", 1069 .name = "AD1889 Audio",
1070 .owner = THIS_MODULE,
1071 .id_table = snd_ad1889_ids, 1070 .id_table = snd_ad1889_ids,
1072 .probe = snd_ad1889_probe, 1071 .probe = snd_ad1889_probe,
1073 .remove = __devexit_p(snd_ad1889_remove), 1072 .remove = __devexit_p(snd_ad1889_remove),
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 4e76c4a636d9..feffbe73387e 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2403,7 +2403,6 @@ static void __devexit snd_ali_remove(struct pci_dev *pci)
2403 2403
2404static struct pci_driver driver = { 2404static struct pci_driver driver = {
2405 .name = "ALI 5451", 2405 .name = "ALI 5451",
2406 .owner = THIS_MODULE,
2407 .id_table = snd_ali_ids, 2406 .id_table = snd_ali_ids,
2408 .probe = snd_ali_probe, 2407 .probe = snd_ali_probe,
2409 .remove = __devexit_p(snd_ali_remove), 2408 .remove = __devexit_p(snd_ali_remove),
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 7c61561f297f..1904df650265 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -768,7 +768,6 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
768 768
769static struct pci_driver driver = { 769static struct pci_driver driver = {
770 .name = "ALS4000", 770 .name = "ALS4000",
771 .owner = THIS_MODULE,
772 .id_table = snd_als4000_ids, 771 .id_table = snd_als4000_ids,
773 .probe = snd_card_als4000_probe, 772 .probe = snd_card_als4000_probe,
774 .remove = __devexit_p(snd_card_als4000_remove), 773 .remove = __devexit_p(snd_card_als4000_remove),
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index f5dad9248e39..8bae10d93529 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1635,7 +1635,6 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
1635 1635
1636static struct pci_driver driver = { 1636static struct pci_driver driver = {
1637 .name = "ATI IXP AC97 controller", 1637 .name = "ATI IXP AC97 controller",
1638 .owner = THIS_MODULE,
1639 .id_table = snd_atiixp_ids, 1638 .id_table = snd_atiixp_ids,
1640 .probe = snd_atiixp_probe, 1639 .probe = snd_atiixp_probe,
1641 .remove = __devexit_p(snd_atiixp_remove), 1640 .remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 0cf202079571..3174b6625419 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1309,7 +1309,6 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
1309 1309
1310static struct pci_driver driver = { 1310static struct pci_driver driver = {
1311 .name = "ATI IXP MC97 controller", 1311 .name = "ATI IXP MC97 controller",
1312 .owner = THIS_MODULE,
1313 .id_table = snd_atiixp_ids, 1312 .id_table = snd_atiixp_ids,
1314 .probe = snd_atiixp_probe, 1313 .probe = snd_atiixp_probe,
1315 .remove = __devexit_p(snd_atiixp_remove), 1314 .remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 6af3b13f2fd1..d965609d8b38 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -373,7 +373,6 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci)
373// pci_driver definition 373// pci_driver definition
374static struct pci_driver driver = { 374static struct pci_driver driver = {
375 .name = CARD_NAME_SHORT, 375 .name = CARD_NAME_SHORT,
376 .owner = THIS_MODULE,
377 .id_table = snd_vortex_ids, 376 .id_table = snd_vortex_ids,
378 .probe = snd_vortex_probe, 377 .probe = snd_vortex_probe,
379 .remove = __devexit_p(snd_vortex_remove), 378 .remove = __devexit_p(snd_vortex_remove),
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index da99b1be2e8f..ab737d6df41d 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1838,7 +1838,6 @@ snd_azf3328_remove(struct pci_dev *pci)
1838 1838
1839static struct pci_driver driver = { 1839static struct pci_driver driver = {
1840 .name = "AZF3328", 1840 .name = "AZF3328",
1841 .owner = THIS_MODULE,
1842 .id_table = snd_azf3328_ids, 1841 .id_table = snd_azf3328_ids,
1843 .probe = snd_azf3328_probe, 1842 .probe = snd_azf3328_probe,
1844 .remove = __devexit_p(snd_azf3328_remove), 1843 .remove = __devexit_p(snd_azf3328_remove),
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 01d98eeb242e..8feca228c6d4 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -897,14 +897,13 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
897/* default entries for all Bt87x cards - it's not exported */ 897/* default entries for all Bt87x cards - it's not exported */
898/* driver_data is set to 0 to call detection */ 898/* driver_data is set to 0 to call detection */
899static struct pci_device_id snd_bt87x_default_ids[] = { 899static struct pci_device_id snd_bt87x_default_ids[] = {
900 BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0), 900 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0),
901 BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0), 901 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0),
902 { } 902 { }
903}; 903};
904 904
905static struct pci_driver driver = { 905static struct pci_driver driver = {
906 .name = "Bt87x", 906 .name = "Bt87x",
907 .owner = THIS_MODULE,
908 .id_table = snd_bt87x_ids, 907 .id_table = snd_bt87x_ids,
909 .probe = snd_bt87x_probe, 908 .probe = snd_bt87x_probe,
910 .remove = __devexit_p(snd_bt87x_remove), 909 .remove = __devexit_p(snd_bt87x_remove),
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ee58d16002e5..389d967c97f4 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1499,7 +1499,6 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
1499// pci_driver definition 1499// pci_driver definition
1500static struct pci_driver driver = { 1500static struct pci_driver driver = {
1501 .name = "CA0106", 1501 .name = "CA0106",
1502 .owner = THIS_MODULE,
1503 .id_table = snd_ca0106_ids, 1502 .id_table = snd_ca0106_ids,
1504 .probe = snd_ca0106_probe, 1503 .probe = snd_ca0106_probe,
1505 .remove = __devexit_p(snd_ca0106_remove), 1504 .remove = __devexit_p(snd_ca0106_remove),
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 57e8e433d56f..db605373b3bc 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3053,7 +3053,6 @@ static void __devexit snd_cmipci_remove(struct pci_dev *pci)
3053 3053
3054static struct pci_driver driver = { 3054static struct pci_driver driver = {
3055 .name = "C-Media PCI", 3055 .name = "C-Media PCI",
3056 .owner = THIS_MODULE,
3057 .id_table = snd_cmipci_ids, 3056 .id_table = snd_cmipci_ids,
3058 .probe = snd_cmipci_probe, 3057 .probe = snd_cmipci_probe,
3059 .remove = __devexit_p(snd_cmipci_remove), 3058 .remove = __devexit_p(snd_cmipci_remove),
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index aea2c47712f9..034ff3755a3b 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -2106,7 +2106,6 @@ static int cs4281_resume(snd_card_t *card)
2106 2106
2107static struct pci_driver driver = { 2107static struct pci_driver driver = {
2108 .name = "CS4281", 2108 .name = "CS4281",
2109 .owner = THIS_MODULE,
2110 .id_table = snd_cs4281_ids, 2109 .id_table = snd_cs4281_ids,
2111 .probe = snd_cs4281_probe, 2110 .probe = snd_cs4281_probe,
2112 .remove = __devexit_p(snd_cs4281_remove), 2111 .remove = __devexit_p(snd_cs4281_remove),
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 32b4f8465cef..b9fff4ee6f9d 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -163,7 +163,6 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
163 163
164static struct pci_driver driver = { 164static struct pci_driver driver = {
165 .name = "Sound Fusion CS46xx", 165 .name = "Sound Fusion CS46xx",
166 .owner = THIS_MODULE,
167 .id_table = snd_cs46xx_ids, 166 .id_table = snd_cs46xx_ids,
168 .probe = snd_card_cs46xx_probe, 167 .probe = snd_card_cs46xx_probe,
169 .remove = __devexit_p(snd_card_cs46xx_remove), 168 .remove = __devexit_p(snd_card_cs46xx_remove),
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index dd1ea9d3b81a..78270f8710ff 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -223,7 +223,6 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
223 223
224static struct pci_driver driver = { 224static struct pci_driver driver = {
225 .name = "EMU10K1_Audigy", 225 .name = "EMU10K1_Audigy",
226 .owner = THIS_MODULE,
227 .id_table = snd_emu10k1_ids, 226 .id_table = snd_emu10k1_ids,
228 .probe = snd_card_emu10k1_probe, 227 .probe = snd_card_emu10k1_probe,
229 .remove = __devexit_p(snd_card_emu10k1_remove), 228 .remove = __devexit_p(snd_card_emu10k1_remove),
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index cbb689474e7d..795577716a5d 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1613,7 +1613,6 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
1613// pci_driver definition 1613// pci_driver definition
1614static struct pci_driver driver = { 1614static struct pci_driver driver = {
1615 .name = "EMU10K1X", 1615 .name = "EMU10K1X",
1616 .owner = THIS_MODULE,
1617 .id_table = snd_emu10k1x_ids, 1616 .id_table = snd_emu10k1x_ids,
1618 .probe = snd_emu10k1x_probe, 1617 .probe = snd_emu10k1x_probe,
1619 .remove = __devexit_p(snd_emu10k1x_remove), 1618 .remove = __devexit_p(snd_emu10k1x_remove),
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 92ff7c510f2b..2daa575f43ff 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2386,7 +2386,6 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci)
2386 2386
2387static struct pci_driver driver = { 2387static struct pci_driver driver = {
2388 .name = DRIVER_NAME, 2388 .name = DRIVER_NAME,
2389 .owner = THIS_MODULE,
2390 .id_table = snd_audiopci_ids, 2389 .id_table = snd_audiopci_ids,
2391 .probe = snd_audiopci_probe, 2390 .probe = snd_audiopci_probe,
2392 .remove = __devexit_p(snd_audiopci_remove), 2391 .remove = __devexit_p(snd_audiopci_remove),
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 78f90defcab1..c134f48152b0 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1758,7 +1758,6 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci)
1758 1758
1759static struct pci_driver driver = { 1759static struct pci_driver driver = {
1760 .name = "ESS ES1938 (Solo-1)", 1760 .name = "ESS ES1938 (Solo-1)",
1761 .owner = THIS_MODULE,
1762 .id_table = snd_es1938_ids, 1761 .id_table = snd_es1938_ids,
1763 .probe = snd_es1938_probe, 1762 .probe = snd_es1938_probe,
1764 .remove = __devexit_p(snd_es1938_remove), 1763 .remove = __devexit_p(snd_es1938_remove),
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ac8294e21cc1..50079dc90743 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2761,7 +2761,6 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci)
2761 2761
2762static struct pci_driver driver = { 2762static struct pci_driver driver = {
2763 .name = "ES1968 (ESS Maestro)", 2763 .name = "ES1968 (ESS Maestro)",
2764 .owner = THIS_MODULE,
2765 .id_table = snd_es1968_ids, 2764 .id_table = snd_es1968_ids,
2766 .probe = snd_es1968_probe, 2765 .probe = snd_es1968_probe,
2767 .remove = __devexit_p(snd_es1968_remove), 2766 .remove = __devexit_p(snd_es1968_remove),
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 4c7c8d225c7f..4e1d3434888d 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1459,7 +1459,6 @@ static void __devexit snd_card_fm801_remove(struct pci_dev *pci)
1459 1459
1460static struct pci_driver driver = { 1460static struct pci_driver driver = {
1461 .name = "FM801", 1461 .name = "FM801",
1462 .owner = THIS_MODULE,
1463 .id_table = snd_fm801_ids, 1462 .id_table = snd_fm801_ids,
1464 .probe = snd_card_fm801_probe, 1463 .probe = snd_card_fm801_probe,
1465 .remove = __devexit_p(snd_card_fm801_remove), 1464 .remove = __devexit_p(snd_card_fm801_remove),
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 9d1412a9f2f8..ed525c03c996 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1616,7 +1616,6 @@ MODULE_DEVICE_TABLE(pci, azx_ids);
1616/* pci_driver definition */ 1616/* pci_driver definition */
1617static struct pci_driver driver = { 1617static struct pci_driver driver = {
1618 .name = "HDA Intel", 1618 .name = "HDA Intel",
1619 .owner = THIS_MODULE,
1620 .id_table = azx_ids, 1619 .id_table = azx_ids,
1621 .probe = azx_probe, 1620 .probe = azx_probe,
1622 .remove = __devexit_p(azx_remove), 1621 .remove = __devexit_p(azx_remove),
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 5aca37798c32..bd71bf424549 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2735,7 +2735,6 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci)
2735 2735
2736static struct pci_driver driver = { 2736static struct pci_driver driver = {
2737 .name = "ICE1712", 2737 .name = "ICE1712",
2738 .owner = THIS_MODULE,
2739 .id_table = snd_ice1712_ids, 2738 .id_table = snd_ice1712_ids,
2740 .probe = snd_ice1712_probe, 2739 .probe = snd_ice1712_probe,
2741 .remove = __devexit_p(snd_ice1712_remove), 2740 .remove = __devexit_p(snd_ice1712_remove),
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 5b4293f5a652..0b5389ee26d5 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2332,7 +2332,6 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
2332 2332
2333static struct pci_driver driver = { 2333static struct pci_driver driver = {
2334 .name = "ICE1724", 2334 .name = "ICE1724",
2335 .owner = THIS_MODULE,
2336 .id_table = snd_vt1724_ids, 2335 .id_table = snd_vt1724_ids,
2337 .probe = snd_vt1724_probe, 2336 .probe = snd_vt1724_probe,
2338 .remove = __devexit_p(snd_vt1724_remove), 2337 .remove = __devexit_p(snd_vt1724_remove),
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 0801083f32dd..cf7801d2dd10 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2876,7 +2876,6 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
2876 2876
2877static struct pci_driver driver = { 2877static struct pci_driver driver = {
2878 .name = "Intel ICH", 2878 .name = "Intel ICH",
2879 .owner = THIS_MODULE,
2880 .id_table = snd_intel8x0_ids, 2879 .id_table = snd_intel8x0_ids,
2881 .probe = snd_intel8x0_probe, 2880 .probe = snd_intel8x0_probe,
2882 .remove = __devexit_p(snd_intel8x0_remove), 2881 .remove = __devexit_p(snd_intel8x0_remove),
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index acfb197a833c..a42091860da7 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1317,7 +1317,6 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
1317 1317
1318static struct pci_driver driver = { 1318static struct pci_driver driver = {
1319 .name = "Intel ICH Modem", 1319 .name = "Intel ICH Modem",
1320 .owner = THIS_MODULE,
1321 .id_table = snd_intel8x0m_ids, 1320 .id_table = snd_intel8x0m_ids,
1322 .probe = snd_intel8x0m_probe, 1321 .probe = snd_intel8x0m_probe,
1323 .remove = __devexit_p(snd_intel8x0m_remove), 1322 .remove = __devexit_p(snd_intel8x0m_remove),
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 5561fd4091e8..a110d664f626 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2534,7 +2534,6 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci)
2534 2534
2535static struct pci_driver driver = { 2535static struct pci_driver driver = {
2536 .name = "korg1212", 2536 .name = "korg1212",
2537 .owner = THIS_MODULE,
2538 .id_table = snd_korg1212_ids, 2537 .id_table = snd_korg1212_ids,
2539 .probe = snd_korg1212_probe, 2538 .probe = snd_korg1212_probe,
2540 .remove = __devexit_p(snd_korg1212_remove), 2539 .remove = __devexit_p(snd_korg1212_remove),
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 99eb76c56f81..ede7a75bfe08 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2858,7 +2858,6 @@ static void __devexit snd_m3_remove(struct pci_dev *pci)
2858 2858
2859static struct pci_driver driver = { 2859static struct pci_driver driver = {
2860 .name = "Maestro3", 2860 .name = "Maestro3",
2861 .owner = THIS_MODULE,
2862 .id_table = snd_m3_ids, 2861 .id_table = snd_m3_ids,
2863 .probe = snd_m3_probe, 2862 .probe = snd_m3_probe,
2864 .remove = __devexit_p(snd_m3_remove), 2863 .remove = __devexit_p(snd_m3_remove),
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index c341c99ec783..b3090a13edab 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1423,7 +1423,6 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci)
1423 1423
1424static struct pci_driver driver = { 1424static struct pci_driver driver = {
1425 .name = "Digigram miXart", 1425 .name = "Digigram miXart",
1426 .owner = THIS_MODULE,
1427 .id_table = snd_mixart_ids, 1426 .id_table = snd_mixart_ids,
1428 .probe = snd_mixart_probe, 1427 .probe = snd_mixart_probe,
1429 .remove = __devexit_p(snd_mixart_remove), 1428 .remove = __devexit_p(snd_mixart_remove),
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index e7aa15178453..089d23b4a002 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1673,7 +1673,6 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci)
1673 1673
1674static struct pci_driver driver = { 1674static struct pci_driver driver = {
1675 .name = "NeoMagic 256", 1675 .name = "NeoMagic 256",
1676 .owner = THIS_MODULE,
1677 .id_table = snd_nm256_ids, 1676 .id_table = snd_nm256_ids,
1678 .probe = snd_nm256_probe, 1677 .probe = snd_nm256_probe,
1679 .remove = __devexit_p(snd_nm256_remove), 1678 .remove = __devexit_p(snd_nm256_remove),
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index e6627b0e38e4..783df7625c1c 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -2012,7 +2012,6 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci)
2012 2012
2013static struct pci_driver driver = { 2013static struct pci_driver driver = {
2014 .name = "RME Digi32", 2014 .name = "RME Digi32",
2015 .owner = THIS_MODULE,
2016 .id_table = snd_rme32_ids, 2015 .id_table = snd_rme32_ids,
2017 .probe = snd_rme32_probe, 2016 .probe = snd_rme32_probe,
2018 .remove = __devexit_p(snd_rme32_remove), 2017 .remove = __devexit_p(snd_rme32_remove),
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 0eddeb16a10f..6d422ef64999 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -2413,7 +2413,6 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci)
2413 2413
2414static struct pci_driver driver = { 2414static struct pci_driver driver = {
2415 .name = "RME Digi96", 2415 .name = "RME Digi96",
2416 .owner = THIS_MODULE,
2417 .id_table = snd_rme96_ids, 2416 .id_table = snd_rme96_ids,
2418 .probe = snd_rme96_probe, 2417 .probe = snd_rme96_probe,
2419 .remove = __devexit_p(snd_rme96_remove), 2418 .remove = __devexit_p(snd_rme96_remove),
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 845158b01b02..d15ffb3e9b0a 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -5062,7 +5062,6 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci)
5062 5062
5063static struct pci_driver driver = { 5063static struct pci_driver driver = {
5064 .name = "RME Hammerfall DSP", 5064 .name = "RME Hammerfall DSP",
5065 .owner = THIS_MODULE,
5066 .id_table = snd_hdsp_ids, 5065 .id_table = snd_hdsp_ids,
5067 .probe = snd_hdsp_probe, 5066 .probe = snd_hdsp_probe,
5068 .remove = __devexit_p(snd_hdsp_remove), 5067 .remove = __devexit_p(snd_hdsp_remove),
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 60a1141f1327..a1aef6f6767e 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3639,7 +3639,6 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci)
3639 3639
3640static struct pci_driver driver = { 3640static struct pci_driver driver = {
3641 .name = "RME Hammerfall DSP MADI", 3641 .name = "RME Hammerfall DSP MADI",
3642 .owner = THIS_MODULE,
3643 .id_table = snd_hdspm_ids, 3642 .id_table = snd_hdspm_ids,
3644 .probe = snd_hdspm_probe, 3643 .probe = snd_hdspm_probe,
3645 .remove = __devexit_p(snd_hdspm_remove), 3644 .remove = __devexit_p(snd_hdspm_remove),
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 59fcef9b6b81..f9d0c126c213 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -2654,7 +2654,6 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci)
2654 2654
2655static struct pci_driver driver = { 2655static struct pci_driver driver = {
2656 .name = "RME Digi9652 (Hammerfall)", 2656 .name = "RME Digi9652 (Hammerfall)",
2657 .owner = THIS_MODULE,
2658 .id_table = snd_rme9652_ids, 2657 .id_table = snd_rme9652_ids,
2659 .probe = snd_rme9652_probe, 2658 .probe = snd_rme9652_probe,
2660 .remove = __devexit_p(snd_rme9652_remove), 2659 .remove = __devexit_p(snd_rme9652_remove),
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 9a35474aad05..e92ef3ae2ca1 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1502,7 +1502,6 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci)
1502 1502
1503static struct pci_driver driver = { 1503static struct pci_driver driver = {
1504 .name = "S3 SonicVibes", 1504 .name = "S3 SonicVibes",
1505 .owner = THIS_MODULE,
1506 .id_table = snd_sonic_ids, 1505 .id_table = snd_sonic_ids,
1507 .probe = snd_sonic_probe, 1506 .probe = snd_sonic_probe,
1508 .remove = __devexit_p(snd_sonic_remove), 1507 .remove = __devexit_p(snd_sonic_remove),
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index a8ca8e17853f..940d531575c0 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -177,7 +177,6 @@ static void __devexit snd_trident_remove(struct pci_dev *pci)
177 177
178static struct pci_driver driver = { 178static struct pci_driver driver = {
179 .name = "Trident4DWaveAudio", 179 .name = "Trident4DWaveAudio",
180 .owner = THIS_MODULE,
181 .id_table = snd_trident_ids, 180 .id_table = snd_trident_ids,
182 .probe = snd_trident_probe, 181 .probe = snd_trident_probe,
183 .remove = __devexit_p(snd_trident_remove), 182 .remove = __devexit_p(snd_trident_remove),
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 523eace250f7..fad2a2413bf6 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2478,7 +2478,6 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
2478 2478
2479static struct pci_driver driver = { 2479static struct pci_driver driver = {
2480 .name = "VIA 82xx Audio", 2480 .name = "VIA 82xx Audio",
2481 .owner = THIS_MODULE,
2482 .id_table = snd_via82xx_ids, 2481 .id_table = snd_via82xx_ids,
2483 .probe = snd_via82xx_probe, 2482 .probe = snd_via82xx_probe,
2484 .remove = __devexit_p(snd_via82xx_remove), 2483 .remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 011f0fb63bf9..b83660bd05b0 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1198,7 +1198,6 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
1198 1198
1199static struct pci_driver driver = { 1199static struct pci_driver driver = {
1200 .name = "VIA 82xx Modem", 1200 .name = "VIA 82xx Modem",
1201 .owner = THIS_MODULE,
1202 .id_table = snd_via82xx_modem_ids, 1201 .id_table = snd_via82xx_modem_ids,
1203 .probe = snd_via82xx_probe, 1202 .probe = snd_via82xx_probe,
1204 .remove = __devexit_p(snd_via82xx_remove), 1203 .remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 2a7ad9dec021..dca6bd2c7580 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -252,7 +252,6 @@ static void __devexit snd_vx222_remove(struct pci_dev *pci)
252 252
253static struct pci_driver driver = { 253static struct pci_driver driver = {
254 .name = "Digigram VX222", 254 .name = "Digigram VX222",
255 .owner = THIS_MODULE,
256 .id_table = snd_vx222_ids, 255 .id_table = snd_vx222_ids,
257 .probe = snd_vx222_probe, 256 .probe = snd_vx222_probe,
258 .remove = __devexit_p(snd_vx222_remove), 257 .remove = __devexit_p(snd_vx222_remove),
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 1bbba32517ff..d013237205d8 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -344,7 +344,6 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
344 344
345static struct pci_driver driver = { 345static struct pci_driver driver = {
346 .name = "Yamaha DS-XG PCI", 346 .name = "Yamaha DS-XG PCI",
347 .owner = THIS_MODULE,
348 .id_table = snd_ymfpci_ids, 347 .id_table = snd_ymfpci_ids,
349 .probe = snd_card_ymfpci_probe, 348 .probe = snd_card_ymfpci_probe,
350 .remove = __devexit_p(snd_card_ymfpci_remove), 349 .remove = __devexit_p(snd_card_ymfpci_remove),
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index ae3bb6c6edff..bfff788e9847 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -22,7 +22,6 @@
22#ifndef __PMAC_H 22#ifndef __PMAC_H
23#define __PMAC_H 23#define __PMAC_H
24 24
25#include <linux/version.h>
26#include <sound/control.h> 25#include <sound/control.h>
27#include <sound/pcm.h> 26#include <sound/pcm.h>
28#include "awacs.h" 27#include "awacs.h"